UNPKG

betterpack

Version:

A Universal Node.js Package Manager CLI with automated agent capabilities

44,349 lines • 1.27 MB
#!/usr/bin/env node
import require$$2$2 from 'child_process';
import require$$0$2 from 'fs';
import require$$1 from 'path';
import require$$3 from 'os';
import require$$0$1 from 'events';
import require$$0$3 from 'constants';
import require$$0$4 from 'stream';
import require$$0$5 from 'util';
import require$$5 from 'assert';
import require$$0$6 from 'buffer';
import require$$0$7 from 'zlib';
import require$$2$1 from 'string_decoder';
import require$$7 from 'process';
import require$$12 from 'crypto';
import require$$0$8 from 'readline';

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

function getDefaultExportFromCjs (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

function getAugmentedNamespace(n) {
  if (n.__esModule) return n;
  var f = n.default;
	if (typeof f == "function") {
		var a = function a () {
			if (this instanceof a) {
        return Reflect.construct(f, arguments, this.constructor);
			}
			return f.apply(this, arguments);
		};
		a.prototype = f.prototype;
  } else a = {};
  Object.defineProperty(a, '__esModule', {value: true});
	Object.keys(n).forEach(function (k) {
		var d = Object.getOwnPropertyDescriptor(n, k);
		Object.defineProperty(a, k, d.get ? d : {
			enumerable: true,
			get: function () {
				return n[k];
			}
		});
	});
	return a;
}

var path;
var hasRequiredPath;

function requirePath () {
	if (hasRequiredPath) return path;
	hasRequiredPath = 1;
	const isWindows = typeof process === 'object' &&
	  process &&
	  process.platform === 'win32';
	path = isWindows ? { sep: '\\' } : { sep: '/' };
	return path;
}

var balancedMatch;
var hasRequiredBalancedMatch;

function requireBalancedMatch () {
	if (hasRequiredBalancedMatch) return balancedMatch;
	hasRequiredBalancedMatch = 1;
	balancedMatch = balanced;
	function balanced(a, b, str) {
	  if (a instanceof RegExp) a = maybeMatch(a, str);
	  if (b instanceof RegExp) b = maybeMatch(b, str);

	  var r = range(a, b, str);

	  return r && {
	    start: r[0],
	    end: r[1],
	    pre: str.slice(0, r[0]),
	    body: str.slice(r[0] + a.length, r[1]),
	    post: str.slice(r[1] + b.length)
	  };
	}

	function maybeMatch(reg, str) {
	  var m = str.match(reg);
	  return m ? m[0] : null;
	}

	balanced.range = range;
	function range(a, b, str) {
	  var begs, beg, left, right, result;
	  var ai = str.indexOf(a);
	  var bi = str.indexOf(b, ai + 1);
	  var i = ai;

	  if (ai >= 0 && bi > 0) {
	    if(a===b) {
	      return [ai, bi];
	    }
	    begs = [];
	    left = str.length;

	    while (i >= 0 && !result) {
	      if (i == ai) {
	        begs.push(i);
	        ai = str.indexOf(a, i + 1);
	      } else if (begs.length == 1) {
	        result = [ begs.pop(), bi ];
	      } else {
	        beg = begs.pop();
	        if (beg < left) {
	          left = beg;
	          right = bi;
	        }

	        bi = str.indexOf(b, i + 1);
	      }

	      i = ai < bi && ai >= 0 ? ai : bi;
	    }

	    if (begs.length) {
	      result = [ left, right ];
	    }
	  }

	  return result;
	}
	return balancedMatch;
}

var braceExpansion;
var hasRequiredBraceExpansion;

function requireBraceExpansion () {
	if (hasRequiredBraceExpansion) return braceExpansion;
	hasRequiredBraceExpansion = 1;
	var balanced = requireBalancedMatch();

	braceExpansion = expandTop;

	var escSlash = '\0SLASH'+Math.random()+'\0';
	var escOpen = '\0OPEN'+Math.random()+'\0';
	var escClose = '\0CLOSE'+Math.random()+'\0';
	var escComma = '\0COMMA'+Math.random()+'\0';
	var escPeriod = '\0PERIOD'+Math.random()+'\0';

	function numeric(str) {
	  return parseInt(str, 10) == str
	    ? parseInt(str, 10)
	    : str.charCodeAt(0);
	}

	function escapeBraces(str) {
	  return str.split('\\\\').join(escSlash)
	            .split('\\{').join(escOpen)
	            .split('\\}').join(escClose)
	            .split('\\,').join(escComma)
	            .split('\\.').join(escPeriod);
	}

	function unescapeBraces(str) {
	  return str.split(escSlash).join('\\')
	            .split(escOpen).join('{')
	            .split(escClose).join('}')
	            .split(escComma).join(',')
	            .split(escPeriod).join('.');
	}


	// Basically just str.split(","), but handling cases
	// where we have nested braced sections, which should be
	// treated as individual members, like {a,{b,c},d}
	function parseCommaParts(str) {
	  if (!str)
	    return [''];

	  var parts = [];
	  var m = balanced('{', '}', str);

	  if (!m)
	    return str.split(',');

	  var pre = m.pre;
	  var body = m.body;
	  var post = m.post;
	  var p = pre.split(',');

	  p[p.length-1] += '{' + body + '}';
	  var postParts = parseCommaParts(post);
	  if (post.length) {
	    p[p.length-1] += postParts.shift();
	    p.push.apply(p, postParts);
	  }

	  parts.push.apply(parts, p);

	  return parts;
	}

	function expandTop(str) {
	  if (!str)
	    return [];

	  // I don't know why Bash 4.3 does this, but it does.
	  // Anything starting with {} will have the first two bytes preserved
	  // but *only* at the top level, so {},a}b will not expand to anything,
	  // but a{},b}c will be expanded to [a}c,abc].
	  // One could argue that this is a bug in Bash, but since the goal of
	  // this module is to match Bash's rules, we escape a leading {}
	  if (str.substr(0, 2) === '{}') {
	    str = '\\{\\}' + str.substr(2);
	  }

	  return expand(escapeBraces(str), true).map(unescapeBraces);
	}

	function embrace(str) {
	  return '{' + str + '}';
	}
	function isPadded(el) {
	  return /^-?0\d/.test(el);
	}

	function lte(i, y) {
	  return i <= y;
	}
	function gte(i, y) {
	  return i >= y;
	}

	function expand(str, isTop) {
	  var expansions = [];

	  var m = balanced('{', '}', str);
	  if (!m) return [str];

	  // no need to expand pre, since it is guaranteed to be free of brace-sets
	  var pre = m.pre;
	  var post = m.post.length
	    ? expand(m.post, false)
	    : [''];

	  if (/\$$/.test(m.pre)) {    
	    for (var k = 0; k < post.length; k++) {
	      var expansion = pre+ '{' + m.body + '}' + post[k];
	      expansions.push(expansion);
	    }
	  } else {
	    var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
	    var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
	    var isSequence = isNumericSequence || isAlphaSequence;
	    var isOptions = m.body.indexOf(',') >= 0;
	    if (!isSequence && !isOptions) {
	      // {a},b}
	      if (m.post.match(/,(?!,).*\}/)) {
	        str = m.pre + '{' + m.body + escClose + m.post;
	        return expand(str);
	      }
	      return [str];
	    }

	    var n;
	    if (isSequence) {
	      n = m.body.split(/\.\./);
	    } else {
	      n = parseCommaParts(m.body);
	      if (n.length === 1) {
	        // x{{a,b}}y ==> x{a}y x{b}y
	        n = expand(n[0], false).map(embrace);
	        if (n.length === 1) {
	          return post.map(function(p) {
	            return m.pre + n[0] + p;
	          });
	        }
	      }
	    }

	    // at this point, n is the parts, and we know it's not a comma set
	    // with a single entry.
	    var N;

	    if (isSequence) {
	      var x = numeric(n[0]);
	      var y = numeric(n[1]);
	      var width = Math.max(n[0].length, n[1].length);
	      var incr = n.length == 3
	        ? Math.abs(numeric(n[2]))
	        : 1;
	      var test = lte;
	      var reverse = y < x;
	      if (reverse) {
	        incr *= -1;
	        test = gte;
	      }
	      var pad = n.some(isPadded);

	      N = [];

	      for (var i = x; test(i, y); i += incr) {
	        var c;
	        if (isAlphaSequence) {
	          c = String.fromCharCode(i);
	          if (c === '\\')
	            c = '';
	        } else {
	          c = String(i);
	          if (pad) {
	            var need = width - c.length;
	            if (need > 0) {
	              var z = new Array(need + 1).join('0');
	              if (i < 0)
	                c = '-' + z + c.slice(1);
	              else
	                c = z + c;
	            }
	          }
	        }
	        N.push(c);
	      }
	    } else {
	      N = [];

	      for (var j = 0; j < n.length; j++) {
	        N.push.apply(N, expand(n[j], false));
	      }
	    }

	    for (var j = 0; j < N.length; j++) {
	      for (var k = 0; k < post.length; k++) {
	        var expansion = pre + N[j] + post[k];
	        if (!isTop || isSequence || expansion)
	          expansions.push(expansion);
	      }
	    }
	  }

	  return expansions;
	}
	return braceExpansion;
}

var minimatch_1;
var hasRequiredMinimatch;

function requireMinimatch () {
	if (hasRequiredMinimatch) return minimatch_1;
	hasRequiredMinimatch = 1;
	const minimatch = minimatch_1 = (p, pattern, options = {}) => {
	  assertValidPattern(pattern);

	  // shortcut: comments match nothing.
	  if (!options.nocomment && pattern.charAt(0) === '#') {
	    return false
	  }

	  return new Minimatch(pattern, options).match(p)
	};

	minimatch_1 = minimatch;

	const path = requirePath();
	minimatch.sep = path.sep;

	const GLOBSTAR = Symbol('globstar **');
	minimatch.GLOBSTAR = GLOBSTAR;
	const expand = requireBraceExpansion();

	const plTypes = {
	  '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
	  '?': { open: '(?:', close: ')?' },
	  '+': { open: '(?:', close: ')+' },
	  '*': { open: '(?:', close: ')*' },
	  '@': { open: '(?:', close: ')' }
	};

	// any single thing other than /
	// don't need to escape / when using new RegExp()
	const qmark = '[^/]';

	// * => any number of characters
	const star = qmark + '*?';

	// ** when dots are allowed.  Anything goes, except .. and .
	// not (^ or / followed by one or two dots followed by $ or /),
	// followed by anything, any number of times.
	const twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?';

	// not a ^ or / followed by a dot,
	// followed by anything, any number of times.
	const twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?';

	// "abc" -> { a:true, b:true, c:true }
	const charSet = s => s.split('').reduce((set, c) => {
	  set[c] = true;
	  return set
	}, {});

	// characters that need to be escaped in RegExp.
	const reSpecials = charSet('().*{}+?[]^$\\!');

	// characters that indicate we have to add the pattern start
	const addPatternStartSet = charSet('[.(');

	// normalizes slashes.
	const slashSplit = /\/+/;

	minimatch.filter = (pattern, options = {}) =>
	  (p, i, list) => minimatch(p, pattern, options);

	const ext = (a, b = {}) => {
	  const t = {};
	  Object.keys(a).forEach(k => t[k] = a[k]);
	  Object.keys(b).forEach(k => t[k] = b[k]);
	  return t
	};

	minimatch.defaults = def => {
	  if (!def || typeof def !== 'object' || !Object.keys(def).length) {
	    return minimatch
	  }

	  const orig = minimatch;

	  const m = (p, pattern, options) => orig(p, pattern, ext(def, options));
	  m.Minimatch = class Minimatch extends orig.Minimatch {
	    constructor (pattern, options) {
	      super(pattern, ext(def, options));
	    }
	  };
	  m.Minimatch.defaults = options => orig.defaults(ext(def, options)).Minimatch;
	  m.filter = (pattern, options) => orig.filter(pattern, ext(def, options));
	  m.defaults = options => orig.defaults(ext(def, options));
	  m.makeRe = (pattern, options) => orig.makeRe(pattern, ext(def, options));
	  m.braceExpand = (pattern, options) => orig.braceExpand(pattern, ext(def, options));
	  m.match = (list, pattern, options) => orig.match(list, pattern, ext(def, options));

	  return m
	};





	// Brace expansion:
	// a{b,c}d -> abd acd
	// a{b,}c -> abc ac
	// a{0..3}d -> a0d a1d a2d a3d
	// a{b,c{d,e}f}g -> abg acdfg acefg
	// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
	//
	// Invalid sets are not expanded.
	// a{2..}b -> a{2..}b
	// a{b}c -> a{b}c
	minimatch.braceExpand = (pattern, options) => braceExpand(pattern, options);

	const braceExpand = (pattern, options = {}) => {
	  assertValidPattern(pattern);

	  // Thanks to Yeting Li <https://github.com/yetingli> for
	  // improving this regexp to avoid a ReDOS vulnerability.
	  if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
	    // shortcut. no need to expand.
	    return [pattern]
	  }

	  return expand(pattern)
	};

	const MAX_PATTERN_LENGTH = 1024 * 64;
	const assertValidPattern = pattern => {
	  if (typeof pattern !== 'string') {
	    throw new TypeError('invalid pattern')
	  }

	  if (pattern.length > MAX_PATTERN_LENGTH) {
	    throw new TypeError('pattern is too long')
	  }
	};

	// parse a component of the expanded set.
	// At this point, no pattern may contain "/" in it
	// so we're going to return a 2d array, where each entry is the full
	// pattern, split on '/', and then turned into a regular expression.
	// A regexp is made at the end which joins each array with an
	// escaped /, and another full one which joins each regexp with |.
	//
	// Following the lead of Bash 4.1, note that "**" only has special meaning
	// when it is the *only* thing in a path portion.  Otherwise, any series
	// of * is equivalent to a single *.  Globstar behavior is enabled by
	// default, and can be disabled by setting options.noglobstar.
	const SUBPARSE = Symbol('subparse');

	minimatch.makeRe = (pattern, options) =>
	  new Minimatch(pattern, options || {}).makeRe();

	minimatch.match = (list, pattern, options = {}) => {
	  const mm = new Minimatch(pattern, options);
	  list = list.filter(f => mm.match(f));
	  if (mm.options.nonull && !list.length) {
	    list.push(pattern);
	  }
	  return list
	};

	// replace stuff like \* with *
	const globUnescape = s => s.replace(/\\(.)/g, '$1');
	const charUnescape = s => s.replace(/\\([^-\]])/g, '$1');
	const regExpEscape = s => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
	const braExpEscape = s => s.replace(/[[\]\\]/g, '\\$&');

	class Minimatch {
	  constructor (pattern, options) {
	    assertValidPattern(pattern);

	    if (!options) options = {};

	    this.options = options;
	    this.set = [];
	    this.pattern = pattern;
	    this.windowsPathsNoEscape = !!options.windowsPathsNoEscape ||
	      options.allowWindowsEscape === false;
	    if (this.windowsPathsNoEscape) {
	      this.pattern = this.pattern.replace(/\\/g, '/');
	    }
	    this.regexp = null;
	    this.negate = false;
	    this.comment = false;
	    this.empty = false;
	    this.partial = !!options.partial;

	    // make the set of regexps etc.
	    this.make();
	  }

	  debug () {}

	  make () {
	    const pattern = this.pattern;
	    const options = this.options;

	    // empty patterns and comments match nothing.
	    if (!options.nocomment && pattern.charAt(0) === '#') {
	      this.comment = true;
	      return
	    }
	    if (!pattern) {
	      this.empty = true;
	      return
	    }

	    // step 1: figure out negation, etc.
	    this.parseNegate();

	    // step 2: expand braces
	    let set = this.globSet = this.braceExpand();

	    if (options.debug) this.debug = (...args) => console.error(...args);

	    this.debug(this.pattern, set);

	    // step 3: now we have a set, so turn each one into a series of path-portion
	    // matching patterns.
	    // These will be regexps, except in the case of "**", which is
	    // set to the GLOBSTAR object for globstar behavior,
	    // and will not contain any / characters
	    set = this.globParts = set.map(s => s.split(slashSplit));

	    this.debug(this.pattern, set);

	    // glob --> regexps
	    set = set.map((s, si, set) => s.map(this.parse, this));

	    this.debug(this.pattern, set);

	    // filter out everything that didn't compile properly.
	    set = set.filter(s => s.indexOf(false) === -1);

	    this.debug(this.pattern, set);

	    this.set = set;
	  }

	  parseNegate () {
	    if (this.options.nonegate) return

	    const pattern = this.pattern;
	    let negate = false;
	    let negateOffset = 0;

	    for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {
	      negate = !negate;
	      negateOffset++;
	    }

	    if (negateOffset) this.pattern = pattern.slice(negateOffset);
	    this.negate = negate;
	  }

	  // set partial to true to test if, for example,
	  // "/a/b" matches the start of "/*/b/*/d"
	  // Partial means, if you run out of file before you run
	  // out of pattern, then that's fine, as long as all
	  // the parts match.
	  matchOne (file, pattern, partial) {
	    var options = this.options;

	    this.debug('matchOne',
	      { 'this': this, file: file, pattern: pattern });

	    this.debug('matchOne', file.length, pattern.length);

	    for (var fi = 0,
	        pi = 0,
	        fl = file.length,
	        pl = pattern.length
	        ; (fi < fl) && (pi < pl)
	        ; fi++, pi++) {
	      this.debug('matchOne loop');
	      var p = pattern[pi];
	      var f = file[fi];

	      this.debug(pattern, p, f);

	      // should be impossible.
	      // some invalid regexp stuff in the set.
	      /* istanbul ignore if */
	      if (p === false) return false

	      if (p === GLOBSTAR) {
	        this.debug('GLOBSTAR', [pattern, p, f]);

	        // "**"
	        // a/**/b/**/c would match the following:
	        // a/b/x/y/z/c
	        // a/x/y/z/b/c
	        // a/b/x/b/x/c
	        // a/b/c
	        // To do this, take the rest of the pattern after
	        // the **, and see if it would match the file remainder.
	        // If so, return success.
	        // If not, the ** "swallows" a segment, and try again.
	        // This is recursively awful.
	        //
	        // a/**/b/**/c matching a/b/x/y/z/c
	        // - a matches a
	        // - doublestar
	        //   - matchOne(b/x/y/z/c, b/**/c)
	        //     - b matches b
	        //     - doublestar
	        //       - matchOne(x/y/z/c, c) -> no
	        //       - matchOne(y/z/c, c) -> no
	        //       - matchOne(z/c, c) -> no
	        //       - matchOne(c, c) yes, hit
	        var fr = fi;
	        var pr = pi + 1;
	        if (pr === pl) {
	          this.debug('** at the end');
	          // a ** at the end will just swallow the rest.
	          // We have found a match.
	          // however, it will not swallow /.x, unless
	          // options.dot is set.
	          // . and .. are *never* matched by **, for explosively
	          // exponential reasons.
	          for (; fi < fl; fi++) {
	            if (file[fi] === '.' || file[fi] === '..' ||
	              (!options.dot && file[fi].charAt(0) === '.')) return false
	          }
	          return true
	        }

	        // ok, let's see if we can swallow whatever we can.
	        while (fr < fl) {
	          var swallowee = file[fr];

	          this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);

	          // XXX remove this slice.  Just pass the start index.
	          if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
	            this.debug('globstar found match!', fr, fl, swallowee);
	            // found a match.
	            return true
	          } else {
	            // can't swallow "." or ".." ever.
	            // can only swallow ".foo" when explicitly asked.
	            if (swallowee === '.' || swallowee === '..' ||
	              (!options.dot && swallowee.charAt(0) === '.')) {
	              this.debug('dot detected!', file, fr, pattern, pr);
	              break
	            }

	            // ** swallows a segment, and continue.
	            this.debug('globstar swallow a segment, and continue');
	            fr++;
	          }
	        }

	        // no match was found.
	        // However, in partial mode, we can't say this is necessarily over.
	        // If there's more *pattern* left, then
	        /* istanbul ignore if */
	        if (partial) {
	          // ran out of file
	          this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
	          if (fr === fl) return true
	        }
	        return false
	      }

	      // something other than **
	      // non-magic patterns just have to match exactly
	      // patterns with magic have been turned into regexps.
	      var hit;
	      if (typeof p === 'string') {
	        hit = f === p;
	        this.debug('string match', p, f, hit);
	      } else {
	        hit = f.match(p);
	        this.debug('pattern match', p, f, hit);
	      }

	      if (!hit) return false
	    }

	    // Note: ending in / means that we'll get a final ""
	    // at the end of the pattern.  This can only match a
	    // corresponding "" at the end of the file.
	    // If the file ends in /, then it can only match a
	    // a pattern that ends in /, unless the pattern just
	    // doesn't have any more for it. But, a/b/ should *not*
	    // match "a/b/*", even though "" matches against the
	    // [^/]*? pattern, except in partial mode, where it might
	    // simply not be reached yet.
	    // However, a/b/ should still satisfy a/*

	    // now either we fell off the end of the pattern, or we're done.
	    if (fi === fl && pi === pl) {
	      // ran out of pattern and filename at the same time.
	      // an exact hit!
	      return true
	    } else if (fi === fl) {
	      // ran out of file, but still had pattern left.
	      // this is ok if we're doing the match as part of
	      // a glob fs traversal.
	      return partial
	    } else /* istanbul ignore else */ if (pi === pl) {
	      // ran out of pattern, still have file left.
	      // this is only acceptable if we're on the very last
	      // empty segment of a file with a trailing slash.
	      // a/* should match a/b/
	      return (fi === fl - 1) && (file[fi] === '')
	    }

	    // should be unreachable.
	    /* istanbul ignore next */
	    throw new Error('wtf?')
	  }

	  braceExpand () {
	    return braceExpand(this.pattern, this.options)
	  }

	  parse (pattern, isSub) {
	    assertValidPattern(pattern);

	    const options = this.options;

	    // shortcuts
	    if (pattern === '**') {
	      if (!options.noglobstar)
	        return GLOBSTAR
	      else
	        pattern = '*';
	    }
	    if (pattern === '') return ''

	    let re = '';
	    let hasMagic = false;
	    let escaping = false;
	    // ? => one single character
	    const patternListStack = [];
	    const negativeLists = [];
	    let stateChar;
	    let inClass = false;
	    let reClassStart = -1;
	    let classStart = -1;
	    let cs;
	    let pl;
	    let sp;
	    // . and .. never match anything that doesn't start with .,
	    // even when options.dot is set.  However, if the pattern
	    // starts with ., then traversal patterns can match.
	    let dotTravAllowed = pattern.charAt(0) === '.';
	    let dotFileAllowed = options.dot || dotTravAllowed;
	    const patternStart = () =>
	      dotTravAllowed
	        ? ''
	        : dotFileAllowed
	        ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))'
	        : '(?!\\.)';
	    const subPatternStart = (p) =>
	      p.charAt(0) === '.'
	        ? ''
	        : options.dot
	        ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))'
	        : '(?!\\.)';


	    const clearStateChar = () => {
	      if (stateChar) {
	        // we had some state-tracking character
	        // that wasn't consumed by this pass.
	        switch (stateChar) {
	          case '*':
	            re += star;
	            hasMagic = true;
	          break
	          case '?':
	            re += qmark;
	            hasMagic = true;
	          break
	          default:
	            re += '\\' + stateChar;
	          break
	        }
	        this.debug('clearStateChar %j %j', stateChar, re);
	        stateChar = false;
	      }
	    };

	    for (let i = 0, c; (i < pattern.length) && (c = pattern.charAt(i)); i++) {
	      this.debug('%s\t%s %s %j', pattern, i, re, c);

	      // skip over any that are escaped.
	      if (escaping) {
	        /* istanbul ignore next - completely not allowed, even escaped. */
	        if (c === '/') {
	          return false
	        }

	        if (reSpecials[c]) {
	          re += '\\';
	        }
	        re += c;
	        escaping = false;
	        continue
	      }

	      switch (c) {
	        /* istanbul ignore next */
	        case '/': {
	          // Should already be path-split by now.
	          return false
	        }

	        case '\\':
	          if (inClass && pattern.charAt(i + 1) === '-') {
	            re += c;
	            continue
	          }

	          clearStateChar();
	          escaping = true;
	        continue

	        // the various stateChar values
	        // for the "extglob" stuff.
	        case '?':
	        case '*':
	        case '+':
	        case '@':
	        case '!':
	          this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c);

	          // all of those are literals inside a class, except that
	          // the glob [!a] means [^a] in regexp
	          if (inClass) {
	            this.debug('  in class');
	            if (c === '!' && i === classStart + 1) c = '^';
	            re += c;
	            continue
	          }

	          // if we already have a stateChar, then it means
	          // that there was something like ** or +? in there.
	          // Handle the stateChar, then proceed with this one.
	          this.debug('call clearStateChar %j', stateChar);
	          clearStateChar();
	          stateChar = c;
	          // if extglob is disabled, then +(asdf|foo) isn't a thing.
	          // just clear the statechar *now*, rather than even diving into
	          // the patternList stuff.
	          if (options.noext) clearStateChar();
	        continue

	        case '(': {
	          if (inClass) {
	            re += '(';
	            continue
	          }

	          if (!stateChar) {
	            re += '\\(';
	            continue
	          }

	          const plEntry = {
	            type: stateChar,
	            start: i - 1,
	            reStart: re.length,
	            open: plTypes[stateChar].open,
	            close: plTypes[stateChar].close,
	          };
	          this.debug(this.pattern, '\t', plEntry);
	          patternListStack.push(plEntry);
	          // negation is (?:(?!(?:js)(?:<rest>))[^/]*)
	          re += plEntry.open;
	          // next entry starts with a dot maybe?
	          if (plEntry.start === 0 && plEntry.type !== '!') {
	            dotTravAllowed = true;
	            re += subPatternStart(pattern.slice(i + 1));
	          }
	          this.debug('plType %j %j', stateChar, re);
	          stateChar = false;
	          continue
	        }

	        case ')': {
	          const plEntry = patternListStack[patternListStack.length - 1];
	          if (inClass || !plEntry) {
	            re += '\\)';
	            continue
	          }
	          patternListStack.pop();

	          // closing an extglob
	          clearStateChar();
	          hasMagic = true;
	          pl = plEntry;
	          // negation is (?:(?!js)[^/]*)
	          // The others are (?:<pattern>)<type>
	          re += pl.close;
	          if (pl.type === '!') {
	            negativeLists.push(Object.assign(pl, { reEnd: re.length }));
	          }
	          continue
	        }

	        case '|': {
	          const plEntry = patternListStack[patternListStack.length - 1];
	          if (inClass || !plEntry) {
	            re += '\\|';
	            continue
	          }

	          clearStateChar();
	          re += '|';
	          // next subpattern can start with a dot?
	          if (plEntry.start === 0 && plEntry.type !== '!') {
	            dotTravAllowed = true;
	            re += subPatternStart(pattern.slice(i + 1));
	          }
	          continue
	        }

	        // these are mostly the same in regexp and glob
	        case '[':
	          // swallow any state-tracking char before the [
	          clearStateChar();

	          if (inClass) {
	            re += '\\' + c;
	            continue
	          }

	          inClass = true;
	          classStart = i;
	          reClassStart = re.length;
	          re += c;
	        continue

	        case ']':
	          //  a right bracket shall lose its special
	          //  meaning and represent itself in
	          //  a bracket expression if it occurs
	          //  first in the list.  -- POSIX.2 2.8.3.2
	          if (i === classStart + 1 || !inClass) {
	            re += '\\' + c;
	            continue
	          }

	          // split where the last [ was, make sure we don't have
	          // an invalid re. if so, re-walk the contents of the
	          // would-be class to re-translate any characters that
	          // were passed through as-is
	          // TODO: It would probably be faster to determine this
	          // without a try/catch and a new RegExp, but it's tricky
	          // to do safely.  For now, this is safe and works.
	          cs = pattern.substring(classStart + 1, i);
	          try {
	            RegExp('[' + braExpEscape(charUnescape(cs)) + ']');
	            // looks good, finish up the class.
	            re += c;
	          } catch (er) {
	            // out of order ranges in JS are errors, but in glob syntax,
	            // they're just a range that matches nothing.
	            re = re.substring(0, reClassStart) + '(?:$.)'; // match nothing ever
	          }
	          hasMagic = true;
	          inClass = false;
	        continue

	        default:
	          // swallow any state char that wasn't consumed
	          clearStateChar();

	          if (reSpecials[c] && !(c === '^' && inClass)) {
	            re += '\\';
	          }

	          re += c;
	          break

	      } // switch
	    } // for

	    // handle the case where we left a class open.
	    // "[abc" is valid, equivalent to "\[abc"
	    if (inClass) {
	      // split where the last [ was, and escape it
	      // this is a huge pita.  We now have to re-walk
	      // the contents of the would-be class to re-translate
	      // any characters that were passed through as-is
	      cs = pattern.slice(classStart + 1);
	      sp = this.parse(cs, SUBPARSE);
	      re = re.substring(0, reClassStart) + '\\[' + sp[0];
	      hasMagic = hasMagic || sp[1];
	    }

	    // handle the case where we had a +( thing at the *end*
	    // of the pattern.
	    // each pattern list stack adds 3 chars, and we need to go through
	    // and escape any | chars that were passed through as-is for the regexp.
	    // Go through and escape them, taking care not to double-escape any
	    // | chars that were already escaped.
	    for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
	      let tail;
	      tail = re.slice(pl.reStart + pl.open.length);
	      this.debug('setting tail', re, pl);
	      // maybe some even number of \, then maybe 1 \, followed by a |
	      tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => {
	        /* istanbul ignore else - should already be done */
	        if (!$2) {
	          // the | isn't already escaped, so escape it.
	          $2 = '\\';
	        }

	        // need to escape all those slashes *again*, without escaping the
	        // one that we need for escaping the | character.  As it works out,
	        // escaping an even number of slashes can be done by simply repeating
	        // it exactly after itself.  That's why this trick works.
	        //
	        // I am sorry that you have to see this.
	        return $1 + $1 + $2 + '|'
	      });

	      this.debug('tail=%j\n   %s', tail, tail, pl, re);
	      const t = pl.type === '*' ? star
	        : pl.type === '?' ? qmark
	        : '\\' + pl.type;

	      hasMagic = true;
	      re = re.slice(0, pl.reStart) + t + '\\(' + tail;
	    }

	    // handle trailing things that only matter at the very end.
	    clearStateChar();
	    if (escaping) {
	      // trailing \\
	      re += '\\\\';
	    }

	    // only need to apply the nodot start if the re starts with
	    // something that could conceivably capture a dot
	    const addPatternStart = addPatternStartSet[re.charAt(0)];

	    // Hack to work around lack of negative lookbehind in JS
	    // A pattern like: *.!(x).!(y|z) needs to ensure that a name
	    // like 'a.xyz.yz' doesn't match.  So, the first negative
	    // lookahead, has to look ALL the way ahead, to the end of
	    // the pattern.
	    for (let n = negativeLists.length - 1; n > -1; n--) {
	      const nl = negativeLists[n];

	      const nlBefore = re.slice(0, nl.reStart);
	      const nlFirst = re.slice(nl.reStart, nl.reEnd - 8);
	      let nlAfter = re.slice(nl.reEnd);
	      const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter;

	      // Handle nested stuff like *(*.js|!(*.json)), where open parens
	      // mean that we should *not* include the ) in the bit that is considered
	      // "after" the negated section.
	      const closeParensBefore = nlBefore.split(')').length;
	      const openParensBefore = nlBefore.split('(').length - closeParensBefore;
	      let cleanAfter = nlAfter;
	      for (let i = 0; i < openParensBefore; i++) {
	        cleanAfter = cleanAfter.replace(/\)[+*?]?/, '');
	      }
	      nlAfter = cleanAfter;

	      const dollar = nlAfter === '' && isSub !== SUBPARSE ? '(?:$|\\/)' : '';

	      re = nlBefore + nlFirst + nlAfter + dollar + nlLast;
	    }

	    // if the re is not "" at this point, then we need to make sure
	    // it doesn't match against an empty path part.
	    // Otherwise a/* will match a/, which it should not.
	    if (re !== '' && hasMagic) {
	      re = '(?=.)' + re;
	    }

	    if (addPatternStart) {
	      re = patternStart() + re;
	    }

	    // parsing just a piece of a larger pattern.
	    if (isSub === SUBPARSE) {
	      return [re, hasMagic]
	    }

	    // if it's nocase, and the lcase/uppercase don't match, it's magic
	    if (options.nocase && !hasMagic) {
	      hasMagic = pattern.toUpperCase() !== pattern.toLowerCase();
	    }

	    // skip the regexp for non-magical patterns
	    // unescape anything in it, though, so that it'll be
	    // an exact match against a file etc.
	    if (!hasMagic) {
	      return globUnescape(pattern)
	    }

	    const flags = options.nocase ? 'i' : '';
	    try {
	      return Object.assign(new RegExp('^' + re + '$', flags), {
	        _glob: pattern,
	        _src: re,
	      })
	    } catch (er) /* istanbul ignore next - should be impossible */ {
	      // If it was an invalid regular expression, then it can't match
	      // anything.  This trick looks for a character after the end of
	      // the string, which is of course impossible, except in multi-line
	      // mode, but it's not a /m regex.
	      return new RegExp('$.')
	    }
	  }

	  makeRe () {
	    if (this.regexp || this.regexp === false) return this.regexp

	    // at this point, this.set is a 2d array of partial
	    // pattern strings, or "**".
	    //
	    // It's better to use .match().  This function shouldn't
	    // be used, really, but it's pretty convenient sometimes,
	    // when you just want to work with a regex.
	    const set = this.set;

	    if (!set.length) {
	      this.regexp = false;
	      return this.regexp
	    }
	    const options = this.options;

	    const twoStar = options.noglobstar ? star
	      : options.dot ? twoStarDot
	      : twoStarNoDot;
	    const flags = options.nocase ? 'i' : '';

	    // coalesce globstars and regexpify non-globstar patterns
	    // if it's the only item, then we just do one twoStar
	    // if it's the first, and there are more, prepend (\/|twoStar\/)? to next
	    // if it's the last, append (\/twoStar|) to previous
	    // if it's in the middle, append (\/|\/twoStar\/) to previous
	    // then filter out GLOBSTAR symbols
	    let re = set.map(pattern => {
	      pattern = pattern.map(p =>
	        typeof p === 'string' ? regExpEscape(p)
	        : p === GLOBSTAR ? GLOBSTAR
	        : p._src
	      ).reduce((set, p) => {
	        if (!(set[set.length - 1] === GLOBSTAR && p === GLOBSTAR)) {
	          set.push(p);
	        }
	        return set
	      }, []);
	      pattern.forEach((p, i) => {
	        if (p !== GLOBSTAR || pattern[i-1] === GLOBSTAR) {
	          return
	        }
	        if (i === 0) {
	          if (pattern.length > 1) {
	            pattern[i+1] = '(?:\\\/|' + twoStar + '\\\/)?' + pattern[i+1];
	          } else {
	            pattern[i] = twoStar;
	          }
	        } else if (i === pattern.length - 1) {
	          pattern[i-1] += '(?:\\\/|' + twoStar + ')?';
	        } else {
	          pattern[i-1] += '(?:\\\/|\\\/' + twoStar + '\\\/)' + pattern[i+1];
	          pattern[i+1] = GLOBSTAR;
	        }
	      });
	      return pattern.filter(p => p !== GLOBSTAR).join('/')
	    }).join('|');

	    // must match entire pattern
	    // ending in a * or ** will make it less strict.
	    re = '^(?:' + re + ')$';

	    // can match anything, as long as it's not this.
	    if (this.negate) re = '^(?!' + re + ').*$';

	    try {
	      this.regexp = new RegExp(re, flags);
	    } catch (ex) /* istanbul ignore next - should be impossible */ {
	      this.regexp = false;
	    }
	    return this.regexp
	  }

	  match (f, partial = this.partial) {
	    this.debug('match', f, this.pattern);
	    // short-circuit in the case of busted things.
	    // comments, etc.
	    if (this.comment) return false
	    if (this.empty) return f === ''

	    if (f === '/' && partial) return true

	    const options = this.options;

	    // windows: need to use /, not \
	    if (path.sep !== '/') {
	      f = f.split(path.sep).join('/');
	    }

	    // treat the test path as a set of pathparts.
	    f = f.split(slashSplit);
	    this.debug(this.pattern, 'split', f);

	    // just ONE of the pattern sets in this.set needs to match
	    // in order for it to be valid.  If negating, then just one
	    // match means that we have failed.
	    // Either way, return on the first hit.

	    const set = this.set;
	    this.debug(this.pattern, 'set', set);

	    // Find the basename of the path by looking for the last non-empty segment
	    let filename;
	    for (let i = f.length - 1; i >= 0; i--) {
	      filename = f[i];
	      if (filename) break
	    }

	    for (let i = 0; i < set.length; i++) {
	      const pattern = set[i];
	      let file = f;
	      if (options.matchBase && pattern.length === 1) {
	        file = [filename];
	      }
	      const hit = this.matchOne(file, pattern, partial);
	      if (hit) {
	        if (options.flipNegate) return true
	        return !this.negate
	      }
	    }

	    // didn't get any hits.  this is success if it's a negative
	    // pattern, failure otherwise.
	    if (options.flipNegate) return false
	    return this.negate
	  }

	  static defaults (def) {
	    return minimatch.defaults(def).Minimatch
	  }
	}

	minimatch.Minimatch = Minimatch;
	return minimatch_1;
}

var readdirGlob_1;
var hasRequiredReaddirGlob;

function requireReaddirGlob () {
	if (hasRequiredReaddirGlob) return readdirGlob_1;
	hasRequiredReaddirGlob = 1;
	readdirGlob_1 = readdirGlob;

	const fs = require$$0$2;
	const { EventEmitter } = require$$0$1;
	const { Minimatch } = requireMinimatch();
	const { resolve } = require$$1;

	function readdir(dir, strict) {
	  return new Promise((resolve, reject) => {
	    fs.readdir(dir, {withFileTypes: true} ,(err, files) => {
	      if(err) {
	        switch (err.code) {
	          case 'ENOTDIR':      // Not a directory
	            if(strict) {
	              reject(err);
	            } else {
	              resolve([]);
	            }
	            break;
	          case 'ENOTSUP':      // Operation not supported
	          case 'ENOENT':       // No such file or directory
	          case 'ENAMETOOLONG': // Filename too long
	          case 'UNKNOWN':
	            resolve([]);
	            break;
	          case 'ELOOP':        // Too many levels of symbolic links
	          default:
	            reject(err);
	            break;
	        }
	      } else {
	        resolve(files);
	      }
	    });
	  });
	}
	function stat(file, followSymlinks) {
	  return new Promise((resolve, reject) => {
	    const statFunc = followSymlinks ? fs.stat : fs.lstat;
	    statFunc(file, (err, stats) => {
	      if(err) {
	        switch (err.code) {
	          case 'ENOENT':
	            if(followSymlinks) {
	              // Fallback to lstat to handle broken links as files
	              resolve(stat(file, false)); 
	            } else {
	              resolve(null);
	            }
	            break;
	          default:
	            resolve(null);
	            break;
	        }
	      } else {
	        resolve(stats);
	      }
	    });
	  });
	}

	async function* exploreWalkAsync(dir, path, followSymlinks, useStat, shouldSkip, strict) {
	  let files = await readdir(path + dir, strict);
	  for(const file of files) {
	    let name = file.name;
	    if(name === undefined) {
	      // undefined file.name means the `withFileTypes` options is not supported by node
	      // we have to call the stat function to know if file is directory or not.
	      name = file;
	      useStat = true;
	    }
	    const filename = dir + '/' + name;
	    const relative = filename.slice(1); // Remove the leading /
	    const absolute = path + '/' + relative;
	    let stats = null;
	    if(useStat || followSymlinks) {
	      stats = await stat(absolute, followSymlinks);
	    }
	    if(!stats && file.name !== undefined) {
	      stats = file;
	    }
	    if(stats === null) {
	      stats = { isDirectory: () => false };
	    }

	    if(stats.isDirectory()) {
	      if(!shouldSkip(relative)) {
	        yield {relative, absolute, stats};
	        yield* exploreWalkAsync(filename, path, followSymlinks, useStat, shouldSkip, false);
	      }
	    } else {
	      yield {relative, absolute, stats};
	    }
	  }
	}
	async function* explore(path, followSymlinks, useStat, shouldSkip) {
	  yield* exploreWalkAsync('', path, followSymlinks, useStat, shouldSkip, true);
	}


	function readOptions(options) {
	  return {
	    pattern: options.pattern,
	    dot: !!options.dot,
	    noglobstar: !!options.noglobstar,
	    matchBase: !!options.matchBase,
	    nocase: !!options.nocase,
	    ignore: options.ignore,
	    skip: options.skip,

	    follow: !!options.follow,
	    stat: !!options.stat,
	    nodir: !!options.nodir,
	    mark: !!options.mark,
	    silent: !!options.silent,
	    absolute: !!options.absolute
	  };
	}

	class ReaddirGlob extends EventEmitter {
	  constructor(cwd, options, cb) {
	    super();
	    if(typeof options === 'function') {
	      cb = options;
	      options = null;
	    }

	    this.options = readOptions(options ||Ā {});
	  
	    this.matchers = [];
	    if(this.options.pattern) {
	      const matchers = Array.isArray(this.options.pattern) ? this.options.pattern : [this.options.pattern];
	      this.matchers = matchers.map( m =>
	        new Minimatch(m, {
	          dot: this.options.dot,
	          noglobstar:this.options.noglobstar,
	          matchBase:this.options.matchBase,
	          nocase:this.options.nocase
	        })
	      );
	    }
	  
	    this.ignoreMatchers = [];
	    if(this.options.ignore) {
	      const ignorePatterns = Array.isArray(this.options.ignore) ? this.options.ignore : [this.options.ignore];
	      this.ignoreMatchers = ignorePatterns.map( ignore =>
	        new Minimatch(ignore, {dot: true})
	      );
	    }
	  
	    this.skipMatchers = [];
	    if(this.options.skip) {
	      const skipPatterns = Array.isArray(this.options.skip) ? this.options.skip : [this.options.skip];
	      this.skipMatchers = skipPatterns.map( skip =>
	        new Minimatch(skip, {dot: true})
	      );
	    }

	    this.iterator = explore(resolve(cwd || '.'), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
	    this.paused = false;
	    this.inactive = false;
	    this.aborted = false;
	  
	    if(cb) {
	      this._matches = []; 
	      this.on('match', match => this._matches.push(this.options.absolute ? match.absolute : match.relative));
	      this.on('error', err => cb(err));
	      this.on('end', () => cb(null, this._matches));
	    }

	    setTimeout( () => this._next(), 0);
	  }

	  _shouldSkipDirectory(relative) {
	    //console.log(relative, this.skipMatchers.some(m => m.match(relative)));
	    return this.skipMatchers.some(m => m.match(relative));
	  }

	  _fileMatches(relative, isDirectory) {
	    const file = relative + (isDirectory ? '/' : '');
	    return (this.matchers.length === 0 || this.matchers.some(m => m.match(file)))
	      && !this.ignoreMatchers.some(m => m.match(file))
	      && (!this.options.nodir || !isDirectory);
	  }

	  _next() {
	    if(!this.paused && !this.aborted) {
	      this.iterator.next()
	      .then((obj)=> {
	        if(!obj.done) {
	          const isDirectory = obj.value.stats.isDirectory();
	          if(this._fileMatches(obj.value.relative, isDirectory )) {
	            let relative = obj.value.relative;
	            let absolute = obj.value.absolute;
	            if(this.options.mark && isDirectory) {
	              relative += '/';
	              absolute += '/';
	            }
	            if(this.options.stat) {
	              this.emit('match', {relative, absolute, stat:obj.value.stats});
	            } else {
	              this.emit('match', {relative, absolute});
	            }
	          }
	          this._next(this.iterator);
	        } else {
	          this.emit('end');
	        }
	      })
	      .catch((err) => {
	        this.abort();
	        this.emit('error', err);
	        if(!err.code && !this.options.silent) {
	          console.error(err);
	        }
	      });
	    } else {
	      this.inactive = true;
	    }
	  }

	  abort() {
	    this.aborted = true;
	  }

	  pause() {
	    this.paused = true;
	  }

	  resume() {
	    this.paused = false;
	    if(this.inactive) {
	      this.inactive = false;
	      this._next();
	    }
	  }
	}


	function readdirGlob(pattern, options, cb) {
	  return new ReaddirGlob(pattern, options, cb);
	}
	readdirGlob.ReaddirGlob = ReaddirGlob;
	return readdirGlob_1;
}

/**
 * Creates a continuation function with some arguments already applied.
 *
 * Useful as a shorthand when combined with other control flow functions. Any
 * arguments passed to the returned function are added to the arguments
 * originally passed to apply.
 *
 * @name apply
 * @static
 * @memberOf module:Utils
 * @method
 * @category Util
 * @param {Function} fn - The function you want to eventually apply all
 * arguments to. Invokes with (arguments...).
 * @param {...*} arguments... - Any number of arguments to automatically apply
 * when the continuation is called.
 * @returns {Function} the partially-applied function
 * @example
 *
 * // using apply
 * async.parallel([
 *     async.apply(fs.writeFile, 'testfile1', 'test1'),
 *     async.apply(fs.writeFile, 'testfile2', 'test2')
 * ]);
 *
 *
 * // the same process without using apply
 * async.parallel([
 *     function(callback) {
 *         fs.writeFile('testfile1', 'test1', callback);
 *     },
 *     function(callback) {
 *         fs.writeFile('testfile2', 'test2', callback);
 *     }
 * ]);
 *
 * // It's possible to pass any number of additional arguments when calling the
 * // continuation:
 *
 * node> var fn = async.apply(sys.puts, 'one');
 * node> fn('two', 'three');
 * one
 * two
 * three
 */
function apply(fn, ...args) {
    return (...callArgs) => fn(...args,...callArgs);
}

function initialParams (fn) {
    return function (...args/*, callback*/) {
        var callback = args.pop();
        return fn.call(this, args, callback);
    };
}

/* istanbul ignore file */

var hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask;
var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';

function fallback(fn) {
    setTimeout(fn, 0);
}

function wrap(defer) {
    return (fn, ...args) => defer(() => fn(...args));
}

var _defer$1;

if (hasQueueMicrotask) {
    _defer$1 = queueMicrotask;
} else if (hasSetImmediate) {
    _defer$1 = setImmediate;
} else if (hasNextTick) {
    _defer$1 = process.nextTick;
} else {
    _defer$1 = fallback;
}

var setImmediate$1 = wrap(_defer$1);

/**
 * Take a sync function and make it async, passing its return value to a
 * callback. This is useful for plugging sync functions into a waterfall,
 * series, or other async functions. Any arguments passed to the generated
 * function will be passed to the wrapped function (except for the final
 * callback argument). Errors thrown will be passed to the callback.
 *
 * If the function passed to `asyncify` returns a Promise, that promises's
 * resolved/rejected state will be used to call the callback, rather than simply
 * the synchronous return value.
 *
 * This also means you can asyncify ES2017 `async` functions.
 *
 * @name asyncify
 * @static
 * @memberOf module:Utils
 * @method
 * @alias wrapSync
 * @category Util
 * @param {Function} func - The synchronous function, or Promise-returning
 * function to convert to an {@link AsyncFunction}.
 * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
 * invoked with `(args..., callback)`.
 * @example
 *
 * // passing a regular synchronous function
 * async.waterfall([
 *     async.apply(fs.readFile, filename, "utf8"),
 *     async.asyncify(JSON.parse),
 *     function (data, next) {
 *         // data is the result of parsing the text.
 *         // If there was a parsing error, it would have been caught.
 *     }
 * ], callback);
 *
 * // passing a function returning a promise
 * async.waterfall([
 *     async.apply(fs.readFile, filename, "utf8"),
 *     async.asyncify(function (contents) {
 *         return db.model.create(contents);
 *     }),
 *     function (model, next) {
 *         // `model` is the instantiated model object.
 *         // If there was an error, this function would be skipped.
 *     }
 * ], callback);
 *
 * // es2017 example, though `asyncify` is not needed if your JS environment
 * // supports async functions out of the box
 * var q = async.queue(async.asyncify(async function(file) {
 *     var intermediateStep = await processFile(file);
 *     return await somePromise(intermediateStep)
 * }));
 *
 * q.push(files);
 */
function asyncify(func) {
    if (isAsync(func)) {
        return function (...args/*, callback*/) {
            const callback = args.pop();
            const promise = func.apply(this, args);
            return handlePromise(promise, callback)
        }
    }

    return initialParams(function (args, callback) {
        var result;
        try {
            result = func.apply(this, args);
        } catch (e) {
            return callback(e);
        }
        // if result is Promise object
        if (result && typeof result.then === 'function') {
            return handlePromise(result, callback)
        } else {
            callback(null, result);
        }
    });
}

function handlePromise(promise, callback) {
    return promise.then(value => {
        invokeCallback(callback, null, value);
    }, err => {
        invokeCallback(callback, err && (err instanceof Error || err.message) ? err : new Error(err));
    });
}

function invokeCallback(callback, error, value) {
    try {
        callback(error, value);
    } catch (err) {
        setImmediate$1(e => { throw e }, err);
    }
}

function isAsync(fn) {
    return fn[Symbol.toStringTag] === 'AsyncFunction';
}

function isAsyncGenerator(fn) {
    return fn[Symbol.toStringTag] === 'AsyncGenerator';
}

function isAsyncIterable(obj) {
    return typeof obj[Symbol.asyncIterator] === 'function';
}

function wrapAsync(asyncFn) {
    if (typeof asyncFn !== 'function') throw new Error('expected a function')
    return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;
}

// conditionally promisify a function.
// only return a promise if a callback is omitted
function awaitify (asyncFn, arity) {
    if (!arity) arity = asyncFn.length;
    if (!arity) throw new Error('arity is undefined')
    function awaitable (...args) {
        if (typeof args[arity - 1] === 'function') {
            return asyncFn.apply(this, args)
        }

        return new Promise((resolve, reject) => {
            args[arity - 1] = (err, ...cbArgs) => {
                if (err) return reject(err)
                resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
            };
            asyncFn.apply(this, args);
        })
    }

    return awaitable
}

function applyEach$1 (eachfn) {
    return function applyEach(fns, ...callArgs) {
        const go = awaitify(function (callback) {
            var that = this;
            return eachfn(fns, (fn, cb) => {
                wrapAsync(fn).apply(that, callArgs.concat(cb));
            }, callback);
        });
        return go;
    };
}

function _asyncMap(eachfn, arr, iteratee, callback) {
    arr = arr || [];
    var results = [];
    var counter = 0;
    var _iteratee = wrapAsync(iteratee);

    return eachfn(arr, (value, _, iterCb) => {
        var index = counter++;
        _iteratee(value, (err, v) => {
            results[index] = v;
            iterCb(err);
        });
    }, err => {
        callback(err, results);
    });
}

function isArrayLike(value) {
    return value &&
        typeof value.length === 'number' &&
        value.length >= 0 &&
        value.length % 1 === 0;
}

// A temporary value used to identify if the loop should be broken.
// See #1064, #1293
const breakLoop = {};

function once$1(fn) {
    function wrapper (...args) {
        if (fn === null) return;
        var callFn = fn;
        fn = null;
        callFn.apply(this, args);
    }
    Object.assign(wrapper, fn);
    return wrapper
}

function getIterator (coll) {
    return coll[Symbol.iterator] && coll[Symbol.iterator]();
}

function createArrayIterator(coll) {
    var i = -1;
    var len = coll.length;
    return function next() {
        return ++i < len ? {value: coll[i], key: i} : null;
    }
}

function createES2015Iterator(iterator) {
    var i = -1;
    return function next() {
        var item = iterator.next();
        if (item.done)
            return null;
        i++;
        return {value: item.value, key: i};
    }
}

function createObjectIterator(obj) {
    var okeys = obj ? Object.keys(obj) : [];
    var i = -1;
    var len = okeys.length;
    return function next() {
        var key = okeys[++i];
        if (key === '__proto__') {
            return next();
        }
        return i < len ? {value: obj[key], key} : null;
    };
}

function createIterator(coll) {
    if (isArrayLike(coll)) {
        return createArrayIterator(coll);
    }

    var iterator = getIterator(coll);
    return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
}

function onlyOnce(fn) {
    return function (...args) {
        if (fn === null) throw new Error("Callback was already called.");
        var callFn = fn;
        fn = null;
        callFn.apply(this, args);
    };
}

// for async generators
function asyncEachOfLimit(generator, limit, iteratee, callback) {
    let done = false;
    let canceled = false;
    let awaiting = false;
    let running = 0;
    let idx = 0;

    function replenish() {
        //console.log('replenish')
        if (running >= limit || awaiting || done) return
        //console.log('replenish awaiting')
        awaiting = true;
        generator.next().then(({value, done: iterDone}) => {
            //console.log('got value', value)
            if (canceled || done) return
            awaiting = false;
            if (iterDone) {
                done = true;
                if (running <= 0) {
                    //console.log('done nextCb')
                    callback(null);
                }
                return;
            }
            running++;
            iteratee(value, idx, iterateeCallback);
            idx++;
            replenish();
        }).catch(handleError);
    }

    function iterateeCallback(err, result) {
        //console.log('iterateeCallback')
        running -= 1;
        if (canceled) return
        if (err) return handleError(err)

        if (err === false) {
            done = true;
            canceled = true;
            return
        }

        if (result === breakLoop || (done && running <= 0)) {
            done = true;
            //console.log('done iterCb')
            return callback(null);
        }
        replenish();
    }

    function handleError(err) {
        if (canceled) return
        awaiting = false;
        done = true;
        callback(err);
    }

    replenish();
}

var eachOfLimit$2 = (limit) => {
    return (obj, iteratee, callback) => {
        callback = once$1(callback);
        if (limit <= 0) {
            throw new RangeError('concurrency limit cannot be less than 1')
        }
        if (!obj) {
            return callback(null);
        }
        if (isAsyncGenerator(obj)) {
            return asyncEachOfLimit(obj, limit, iteratee, callback)
        }
        if (isAsyncIterable(obj)) {
            return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback)
        }
        var nextElem = createIterator(obj);
        var done = false;
        var canceled = false;
        var running = 0;
        var looping = false;

        function iterateeCallback(err, value) {
            if (canceled) return
            running -= 1;
            if (err) {
                done = true;
                callback(err);
            }
            else if (err === false) {
                done = true;
                canceled = true;
            }
            else if (value === breakLoop || (done && running <= 0)) {
                done = true;
                return callback(null);
            }
            else if (!looping) {
                replenish();
            }
        }

        function replenish () {
            looping = true;
            while (running < limit && !done) {
                var elem = nextElem();
                if (elem === null) {
                    done = true;
                    if (running <= 0) {
                        callback(null);
                    }
                    return;
                }
                running += 1;
                iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));
            }
            looping = false;
        }

        replenish();
    };
};

/**
 * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
 * time.
 *
 * @name eachOfLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.eachOf]{@link module:Collections.eachOf}
 * @alias forEachOfLimit
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - An async function to apply to each
 * item in `coll`. The `key` is the item's key, or index in the case of an
 * array.
 * Invoked with (item, key, callback).
 * @param {Function} [callback] - A callback which is called when all
 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
 * @returns {Promise} a promise, if a callback is omitted
 */
function eachOfLimit(coll, limit, iteratee, callback) {
    return eachOfLimit$2(limit)(coll, wrapAsync(iteratee), callback);
}

var eachOfLimit$1 = awaitify(eachOfLimit, 4);

// eachOf implementation optimized for array-likes
function eachOfArrayLike(coll, iteratee, callback) {
    callback = once$1(callback);
    var index = 0,
        completed = 0,
        {length} = coll,
        canceled = false;
    if (length === 0) {
        callback(null);
    }

    function iteratorCallback(err, value) {
        if (err === false) {
            canceled = true;
        }
        if (canceled === true) return
        if (err) {
            callback(err);
        } else if ((++completed === length) || value === breakLoop) {
            callback(null);
        }
    }

    for (; index < length; index++) {
        iteratee(coll[index], index, onlyOnce(iteratorCallback));
    }
}

// a generic version of eachOf which can handle array, object, and iterator cases.
function eachOfGeneric (coll, iteratee, callback) {
    return eachOfLimit$1(coll, Infinity, iteratee, callback);
}

/**
 * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
 * to the iteratee.
 *
 * @name eachOf
 * @static
 * @memberOf module:Collections
 * @method
 * @alias forEachOf
 * @category Collection
 * @see [async.each]{@link module:Collections.each}
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - A function to apply to each
 * item in `coll`.
 * The `key` is the item's key, or index in the case of an array.
 * Invoked with (item, key, callback).
 * @param {Function} [callback] - A callback which is called when all
 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
 * @returns {Promise} a promise, if a callback is omitted
 * @example
 *
 * // dev.json is a file containing a valid json object config for dev environment
 * // dev.json is a file containing a valid json object config for test environment
 * // prod.json is a file containing a valid json object config for prod environment
 * // invalid.json is a file with a malformed json object
 *
 * let configs = {}; //global variable
 * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'};
 * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'};
 *
 * // asynchronous function that reads a json file and parses the contents as json object
 * function parseFile(file, key, callback) {
 *     fs.readFile(file, "utf8", function(err, data) {
 *         if (err) return calback(err);
 *         try {
 *             configs[key] = JSON.parse(data);
 *         } catch (e) {
 *             return callback(e);
 *         }
 *         callback();
 *     });
 * }
 *
 * // Using callbacks
 * async.forEachOf(validConfigFileMap, parseFile, function (err) {
 *     if (err) {
 *         console.error(err);
 *     } else {
 *         console.log(configs);
 *         // configs is now a map of JSON data, e.g.
 *         // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
 *     }
 * });
 *
 * //Error handing
 * async.forEachOf(invalidConfigFileMap, parseFile, function (err) {
 *     if (err) {
 *         console.error(err);
 *         // JSON parse error exception
 *     } else {
 *         console.log(configs);
 *     }
 * });
 *
 * // Using Promises
 * async.forEachOf(validConfigFileMap, parseFile)
 * .then( () => {
 *     console.log(configs);
 *     // configs is now a map of JSON data, e.g.
 *     // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
 * }).catch( err => {
 *     console.error(err);
 * });
 *
 * //Error handing
 * async.forEachOf(invalidConfigFileMap, parseFile)
 * .then( () => {
 *     console.log(configs);
 * }).catch( err => {
 *     console.error(err);
 *     // JSON parse error exception
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let result = await async.forEachOf(validConfigFileMap, parseFile);
 *         console.log(configs);
 *         // configs is now a map of JSON data, e.g.
 *         // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * //Error handing
 * async () => {
 *     try {
 *         let result = await async.forEachOf(invalidConfigFileMap, parseFile);
 *         console.log(configs);
 *     }
 *     catch (err) {
 *         console.log(err);
 *         // JSON parse error exception
 *     }
 * }
 *
 */
function eachOf(coll, iteratee, callback) {
    var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
    return eachOfImplementation(coll, wrapAsync(iteratee), callback);
}

var eachOf$1 = awaitify(eachOf, 3);

/**
 * Produces a new collection of values by mapping each value in `coll` through
 * the `iteratee` function. The `iteratee` is called with an item from `coll`
 * and a callback for when it has finished processing. Each of these callbacks
 * takes 2 arguments: an `error`, and the transformed item from `coll`. If
 * `iteratee` passes an error to its callback, the main `callback` (for the
 * `map` function) is immediately called with the error.
 *
 * Note, that since this function applies the `iteratee` to each item in
 * parallel, there is no guarantee that the `iteratee` functions will complete
 * in order. However, the results array will be in the same order as the
 * original `coll`.
 *
 * If `map` is passed an Object, the results will be an Array.  The results
 * will roughly be in the order of the original Objects' keys (but this can
 * vary across JavaScript engines).
 *
 * @name map
 * @static
 * @memberOf module:Collections
 * @method
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * The iteratee should complete with the transformed item.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. Results is an Array of the
 * transformed items from the `coll`. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback is passed
 * @example
 *
 * // file1.txt is a file that is 1000 bytes in size
 * // file2.txt is a file that is 2000 bytes in size
 * // file3.txt is a file that is 3000 bytes in size
 * // file4.txt does not exist
 *
 * const fileList = ['file1.txt','file2.txt','file3.txt'];
 * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];
 *
 * // asynchronous function that returns the file size in bytes
 * function getFileSizeInBytes(file, callback) {
 *     fs.stat(file, function(err, stat) {
 *         if (err) {
 *             return callback(err);
 *         }
 *         callback(null, stat.size);
 *     });
 * }
 *
 * // Using callbacks
 * async.map(fileList, getFileSizeInBytes, function(err, results) {
 *     if (err) {
 *         console.log(err);
 *     } else {
 *         console.log(results);
 *         // results is now an array of the file size in bytes for each file, e.g.
 *         // [ 1000, 2000, 3000]
 *     }
 * });
 *
 * // Error Handling
 * async.map(withMissingFileList, getFileSizeInBytes, function(err, results) {
 *     if (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *     } else {
 *         console.log(results);
 *     }
 * });
 *
 * // Using Promises
 * async.map(fileList, getFileSizeInBytes)
 * .then( results => {
 *     console.log(results);
 *     // results is now an array of the file size in bytes for each file, e.g.
 *     // [ 1000, 2000, 3000]
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * // Error Handling
 * async.map(withMissingFileList, getFileSizeInBytes)
 * .then( results => {
 *     console.log(results);
 * }).catch( err => {
 *     console.log(err);
 *     // [ Error: ENOENT: no such file or directory ]
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let results = await async.map(fileList, getFileSizeInBytes);
 *         console.log(results);
 *         // results is now an array of the file size in bytes for each file, e.g.
 *         // [ 1000, 2000, 3000]
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * // Error Handling
 * async () => {
 *     try {
 *         let results = await async.map(withMissingFileList, getFileSizeInBytes);
 *         console.log(results);
 *     }
 *     catch (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *     }
 * }
 *
 */
function map (coll, iteratee, callback) {
    return _asyncMap(eachOf$1, coll, iteratee, callback)
}
var map$1 = awaitify(map, 3);

/**
 * Applies the provided arguments to each function in the array, calling
 * `callback` after all functions have completed. If you only provide the first
 * argument, `fns`, then it will return a function which lets you pass in the
 * arguments as if it were a single function call. If more arguments are
 * provided, `callback` is required while `args` is still optional. The results
 * for each of the applied async functions are passed to the final callback
 * as an array.
 *
 * @name applyEach
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s
 * to all call with the same arguments
 * @param {...*} [args] - any number of separate arguments to pass to the
 * function.
 * @param {Function} [callback] - the final argument should be the callback,
 * called when all functions have completed processing.
 * @returns {AsyncFunction} - Returns a function that takes no args other than
 * an optional callback, that is the result of applying the `args` to each
 * of the functions.
 * @example
 *
 * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket')
 *
 * appliedFn((err, results) => {
 *     // results[0] is the results for `enableSearch`
 *     // results[1] is the results for `updateSchema`
 * });
 *
 * // partial application example:
 * async.each(
 *     buckets,
 *     async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(),
 *     callback
 * );
 */
var applyEach = applyEach$1(map$1);

/**
 * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
 *
 * @name eachOfSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.eachOf]{@link module:Collections.eachOf}
 * @alias forEachOfSeries
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * Invoked with (item, key, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. Invoked with (err).
 * @returns {Promise} a promise, if a callback is omitted
 */
function eachOfSeries(coll, iteratee, callback) {
    return eachOfLimit$1(coll, 1, iteratee, callback)
}
var eachOfSeries$1 = awaitify(eachOfSeries, 3);

/**
 * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.
 *
 * @name mapSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.map]{@link module:Collections.map}
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * The iteratee should complete with the transformed item.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. Results is an array of the
 * transformed items from the `coll`. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback is passed
 */
function mapSeries (coll, iteratee, callback) {
    return _asyncMap(eachOfSeries$1, coll, iteratee, callback)
}
var mapSeries$1 = awaitify(mapSeries, 3);

/**
 * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.
 *
 * @name applyEachSeries
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.applyEach]{@link module:ControlFlow.applyEach}
 * @category Control Flow
 * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all
 * call with the same arguments
 * @param {...*} [args] - any number of separate arguments to pass to the
 * function.
 * @param {Function} [callback] - the final argument should be the callback,
 * called when all functions have completed processing.
 * @returns {AsyncFunction} - A function, that when called, is the result of
 * appling the `args` to the list of functions.  It takes no args, other than
 * a callback.
 */
var applyEachSeries = applyEach$1(mapSeries$1);

const PROMISE_SYMBOL = Symbol('promiseCallback');

function promiseCallback () {
    let resolve, reject;
    function callback (err, ...args) {
        if (err) return reject(err)
        resolve(args.length > 1 ? args : args[0]);
    }

    callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
        resolve = res,
        reject = rej;
    });

    return callback
}

/**
 * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on
 * their requirements. Each function can optionally depend on other functions
 * being completed first, and each function is run as soon as its requirements
 * are satisfied.
 *
 * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence
 * will stop. Further tasks will not execute (so any other functions depending
 * on it will not run), and the main `callback` is immediately called with the
 * error.
 *
 * {@link AsyncFunction}s also receive an object containing the results of functions which
 * have completed so far as the first argument, if they have dependencies. If a
 * task function has no dependencies, it will only be passed a callback.
 *
 * @name auto
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {Object} tasks - An object. Each of its properties is either a
 * function or an array of requirements, with the {@link AsyncFunction} itself the last item
 * in the array. The object's key of a property serves as the name of the task
 * defined by that property, i.e. can be used when specifying requirements for
 * other tasks. The function receives one or two arguments:
 * * a `results` object, containing the results of the previously executed
 *   functions, only passed if the task has any dependencies,
 * * a `callback(err, result)` function, which must be called when finished,
 *   passing an `error` (which can be `null`) and the result of the function's
 *   execution.
 * @param {number} [concurrency=Infinity] - An optional `integer` for
 * determining the maximum number of tasks that can be run in parallel. By
 * default, as many as possible.
 * @param {Function} [callback] - An optional callback which is called when all
 * the tasks have been completed. It receives the `err` argument if any `tasks`
 * pass an error to their callback. Results are always returned; however, if an
 * error occurs, no further `tasks` will be performed, and the results object
 * will only contain partial results. Invoked with (err, results).
 * @returns {Promise} a promise, if a callback is not passed
 * @example
 *
 * //Using Callbacks
 * async.auto({
 *     get_data: function(callback) {
 *         // async code to get some data
 *         callback(null, 'data', 'converted to array');
 *     },
 *     make_folder: function(callback) {
 *         // async code to create a directory to store a file in
 *         // this is run at the same time as getting the data
 *         callback(null, 'folder');
 *     },
 *     write_file: ['get_data', 'make_folder', function(results, callback) {
 *         // once there is some data and the directory exists,
 *         // write the data to a file in the directory
 *         callback(null, 'filename');
 *     }],
 *     email_link: ['write_file', function(results, callback) {
 *         // once the file is written let's email a link to it...
 *         callback(null, {'file':results.write_file, 'email':'user@example.com'});
 *     }]
 * }, function(err, results) {
 *     if (err) {
 *         console.log('err = ', err);
 *     }
 *     console.log('results = ', results);
 *     // results = {
 *     //     get_data: ['data', 'converted to array']
 *     //     make_folder; 'folder',
 *     //     write_file: 'filename'
 *     //     email_link: { file: 'filename', email: 'user@example.com' }
 *     // }
 * });
 *
 * //Using Promises
 * async.auto({
 *     get_data: function(callback) {
 *         console.log('in get_data');
 *         // async code to get some data
 *         callback(null, 'data', 'converted to array');
 *     },
 *     make_folder: function(callback) {
 *         console.log('in make_folder');
 *         // async code to create a directory to store a file in
 *         // this is run at the same time as getting the data
 *         callback(null, 'folder');
 *     },
 *     write_file: ['get_data', 'make_folder', function(results, callback) {
 *         // once there is some data and the directory exists,
 *         // write the data to a file in the directory
 *         callback(null, 'filename');
 *     }],
 *     email_link: ['write_file', function(results, callback) {
 *         // once the file is written let's email a link to it...
 *         callback(null, {'file':results.write_file, 'email':'user@example.com'});
 *     }]
 * }).then(results => {
 *     console.log('results = ', results);
 *     // results = {
 *     //     get_data: ['data', 'converted to array']
 *     //     make_folder; 'folder',
 *     //     write_file: 'filename'
 *     //     email_link: { file: 'filename', email: 'user@example.com' }
 *     // }
 * }).catch(err => {
 *     console.log('err = ', err);
 * });
 *
 * //Using async/await
 * async () => {
 *     try {
 *         let results = await async.auto({
 *             get_data: function(callback) {
 *                 // async code to get some data
 *                 callback(null, 'data', 'converted to array');
 *             },
 *             make_folder: function(callback) {
 *                 // async code to create a directory to store a file in
 *                 // this is run at the same time as getting the data
 *                 callback(null, 'folder');
 *             },
 *             write_file: ['get_data', 'make_folder', function(results, callback) {
 *                 // once there is some data and the directory exists,
 *                 // write the data to a file in the directory
 *                 callback(null, 'filename');
 *             }],
 *             email_link: ['write_file', function(results, callback) {
 *                 // once the file is written let's email a link to it...
 *                 callback(null, {'file':results.write_file, 'email':'user@example.com'});
 *             }]
 *         });
 *         console.log('results = ', results);
 *         // results = {
 *         //     get_data: ['data', 'converted to array']
 *         //     make_folder; 'folder',
 *         //     write_file: 'filename'
 *         //     email_link: { file: 'filename', email: 'user@example.com' }
 *         // }
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function auto(tasks, concurrency, callback) {
    if (typeof concurrency !== 'number') {
        // concurrency is optional, shift the args.
        callback = concurrency;
        concurrency = null;
    }
    callback = once$1(callback || promiseCallback());
    var numTasks = Object.keys(tasks).length;
    if (!numTasks) {
        return callback(null);
    }
    if (!concurrency) {
        concurrency = numTasks;
    }

    var results = {};
    var runningTasks = 0;
    var canceled = false;
    var hasError = false;

    var listeners = Object.create(null);

    var readyTasks = [];

    // for cycle detection:
    var readyToCheck = []; // tasks that have been identified as reachable
    // without the possibility of returning to an ancestor task
    var uncheckedDependencies = {};

    Object.keys(tasks).forEach(key => {
        var task = tasks[key];
        if (!Array.isArray(task)) {
            // no dependencies
            enqueueTask(key, [task]);
            readyToCheck.push(key);
            return;
        }

        var dependencies = task.slice(0, task.length - 1);
        var remainingDependencies = dependencies.length;
        if (remainingDependencies === 0) {
            enqueueTask(key, task);
            readyToCheck.push(key);
            return;
        }
        uncheckedDependencies[key] = remainingDependencies;

        dependencies.forEach(dependencyName => {
            if (!tasks[dependencyName]) {
                throw new Error('async.auto task `' + key +
                    '` has a non-existent dependency `' +
                    dependencyName + '` in ' +
                    dependencies.join(', '));
            }
            addListener(dependencyName, () => {
                remainingDependencies--;
                if (remainingDependencies === 0) {
                    enqueueTask(key, task);
                }
            });
        });
    });

    checkForDeadlocks();
    processQueue();

    function enqueueTask(key, task) {
        readyTasks.push(() => runTask(key, task));
    }

    function processQueue() {
        if (canceled) return
        if (readyTasks.length === 0 && runningTasks === 0) {
            return callback(null, results);
        }
        while(readyTasks.length && runningTasks < concurrency) {
            var run = readyTasks.shift();
            run();
        }

    }

    function addListener(taskName, fn) {
        var taskListeners = listeners[taskName];
        if (!taskListeners) {
            taskListeners = listeners[taskName] = [];
        }

        taskListeners.push(fn);
    }

    function taskComplete(taskName) {
        var taskListeners = listeners[taskName] || [];
        taskListeners.forEach(fn => fn());
        processQueue();
    }


    function runTask(key, task) {
        if (hasError) return;

        var taskCallback = onlyOnce((err, ...result) => {
            runningTasks--;
            if (err === false) {
                canceled = true;
                return
            }
            if (result.length < 2) {
                [result] = result;
            }
            if (err) {
                var safeResults = {};
                Object.keys(results).forEach(rkey => {
                    safeResults[rkey] = results[rkey];
                });
                safeResults[key] = result;
                hasError = true;
                listeners = Object.create(null);
                if (canceled) return
                callback(err, safeResults);
            } else {
                results[key] = result;
                taskComplete(key);
            }
        });

        runningTasks++;
        var taskFn = wrapAsync(task[task.length - 1]);
        if (task.length > 1) {
            taskFn(results, taskCallback);
        } else {
            taskFn(taskCallback);
        }
    }

    function checkForDeadlocks() {
        // Kahn's algorithm
        // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
        // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html
        var currentTask;
        var counter = 0;
        while (readyToCheck.length) {
            currentTask = readyToCheck.pop();
            counter++;
            getDependents(currentTask).forEach(dependent => {
                if (--uncheckedDependencies[dependent] === 0) {
                    readyToCheck.push(dependent);
                }
            });
        }

        if (counter !== numTasks) {
            throw new Error(
                'async.auto cannot execute tasks due to a recursive dependency'
            );
        }
    }

    function getDependents(taskName) {
        var result = [];
        Object.keys(tasks).forEach(key => {
            const task = tasks[key];
            if (Array.isArray(task) && task.indexOf(taskName) >= 0) {
                result.push(key);
            }
        });
        return result;
    }

    return callback[PROMISE_SYMBOL]
}

var FN_ARGS = /^(?:async\s)?(?:function)?\s*(?:\w+\s*)?\(([^)]+)\)(?:\s*{)/;
var ARROW_FN_ARGS = /^(?:async\s)?\s*(?:\(\s*)?((?:[^)=\s]\s*)*)(?:\)\s*)?=>/;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /(=.+)?(\s*)$/;

function stripComments(string) {
    let stripped = '';
    let index = 0;
    let endBlockComment = string.indexOf('*/');
    while (index < string.length) {
        if (string[index] === '/' && string[index+1] === '/') {
            // inline comment
            let endIndex = string.indexOf('\n', index);
            index = (endIndex === -1) ? string.length : endIndex;
        } else if ((endBlockComment !== -1) && (string[index] === '/') && (string[index+1] === '*')) {
            // block comment
            let endIndex = string.indexOf('*/', index);
            if (endIndex !== -1) {
                index = endIndex + 2;
                endBlockComment = string.indexOf('*/', index);
            } else {
                stripped += string[index];
                index++;
            }
        } else {
            stripped += string[index];
            index++;
        }
    }
    return stripped;
}

function parseParams(func) {
    const src = stripComments(func.toString());
    let match = src.match(FN_ARGS);
    if (!match) {
        match = src.match(ARROW_FN_ARGS);
    }
    if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src)
    let [, args] = match;
    return args
        .replace(/\s/g, '')
        .split(FN_ARG_SPLIT)
        .map((arg) => arg.replace(FN_ARG, '').trim());
}

/**
 * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent
 * tasks are specified as parameters to the function, after the usual callback
 * parameter, with the parameter names matching the names of the tasks it
 * depends on. This can provide even more readable task graphs which can be
 * easier to maintain.
 *
 * If a final callback is specified, the task results are similarly injected,
 * specified as named parameters after the initial error parameter.
 *
 * The autoInject function is purely syntactic sugar and its semantics are
 * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.
 *
 * @name autoInject
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.auto]{@link module:ControlFlow.auto}
 * @category Control Flow
 * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of
 * the form 'func([dependencies...], callback). The object's key of a property
 * serves as the name of the task defined by that property, i.e. can be used
 * when specifying requirements for other tasks.
 * * The `callback` parameter is a `callback(err, result)` which must be called
 *   when finished, passing an `error` (which can be `null`) and the result of
 *   the function's execution. The remaining parameters name other tasks on
 *   which the task is dependent, and the results from those tasks are the
 *   arguments of those parameters.
 * @param {Function} [callback] - An optional callback which is called when all
 * the tasks have been completed. It receives the `err` argument if any `tasks`
 * pass an error to their callback, and a `results` object with any completed
 * task results, similar to `auto`.
 * @returns {Promise} a promise, if no callback is passed
 * @example
 *
 * //  The example from `auto` can be rewritten as follows:
 * async.autoInject({
 *     get_data: function(callback) {
 *         // async code to get some data
 *         callback(null, 'data', 'converted to array');
 *     },
 *     make_folder: function(callback) {
 *         // async code to create a directory to store a file in
 *         // this is run at the same time as getting the data
 *         callback(null, 'folder');
 *     },
 *     write_file: function(get_data, make_folder, callback) {
 *         // once there is some data and the directory exists,
 *         // write the data to a file in the directory
 *         callback(null, 'filename');
 *     },
 *     email_link: function(write_file, callback) {
 *         // once the file is written let's email a link to it...
 *         // write_file contains the filename returned by write_file.
 *         callback(null, {'file':write_file, 'email':'user@example.com'});
 *     }
 * }, function(err, results) {
 *     console.log('err = ', err);
 *     console.log('email_link = ', results.email_link);
 * });
 *
 * // If you are using a JS minifier that mangles parameter names, `autoInject`
 * // will not work with plain functions, since the parameter names will be
 * // collapsed to a single letter identifier.  To work around this, you can
 * // explicitly specify the names of the parameters your task function needs
 * // in an array, similar to Angular.js dependency injection.
 *
 * // This still has an advantage over plain `auto`, since the results a task
 * // depends on are still spread into arguments.
 * async.autoInject({
 *     //...
 *     write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
 *         callback(null, 'filename');
 *     }],
 *     email_link: ['write_file', function(write_file, callback) {
 *         callback(null, {'file':write_file, 'email':'user@example.com'});
 *     }]
 *     //...
 * }, function(err, results) {
 *     console.log('err = ', err);
 *     console.log('email_link = ', results.email_link);
 * });
 */
function autoInject(tasks, callback) {
    var newTasks = {};

    Object.keys(tasks).forEach(key => {
        var taskFn = tasks[key];
        var params;
        var fnIsAsync = isAsync(taskFn);
        var hasNoDeps =
            (!fnIsAsync && taskFn.length === 1) ||
            (fnIsAsync && taskFn.length === 0);

        if (Array.isArray(taskFn)) {
            params = [...taskFn];
            taskFn = params.pop();

            newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
        } else if (hasNoDeps) {
            // no dependencies, use the function as-is
            newTasks[key] = taskFn;
        } else {
            params = parseParams(taskFn);
            if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) {
                throw new Error("autoInject task functions require explicit parameters.");
            }

            // remove callback param
            if (!fnIsAsync) params.pop();

            newTasks[key] = params.concat(newTask);
        }

        function newTask(results, taskCb) {
            var newArgs = params.map(name => results[name]);
            newArgs.push(taskCb);
            wrapAsync(taskFn)(...newArgs);
        }
    });

    return auto(newTasks, callback);
}

// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation
// used for queues. This implementation assumes that the node provided by the user can be modified
// to adjust the next and last properties. We implement only the minimal functionality
// for queue support.
class DLL {
    constructor() {
        this.head = this.tail = null;
        this.length = 0;
    }

    removeLink(node) {
        if (node.prev) node.prev.next = node.next;
        else this.head = node.next;
        if (node.next) node.next.prev = node.prev;
        else this.tail = node.prev;

        node.prev = node.next = null;
        this.length -= 1;
        return node;
    }

    empty () {
        while(this.head) this.shift();
        return this;
    }

    insertAfter(node, newNode) {
        newNode.prev = node;
        newNode.next = node.next;
        if (node.next) node.next.prev = newNode;
        else this.tail = newNode;
        node.next = newNode;
        this.length += 1;
    }

    insertBefore(node, newNode) {
        newNode.prev = node.prev;
        newNode.next = node;
        if (node.prev) node.prev.next = newNode;
        else this.head = newNode;
        node.prev = newNode;
        this.length += 1;
    }

    unshift(node) {
        if (this.head) this.insertBefore(this.head, node);
        else setInitial(this, node);
    }

    push(node) {
        if (this.tail) this.insertAfter(this.tail, node);
        else setInitial(this, node);
    }

    shift() {
        return this.head && this.removeLink(this.head);
    }

    pop() {
        return this.tail && this.removeLink(this.tail);
    }

    toArray() {
        return [...this]
    }

    *[Symbol.iterator] () {
        var cur = this.head;
        while (cur) {
            yield cur.data;
            cur = cur.next;
        }
    }

    remove (testFn) {
        var curr = this.head;
        while(curr) {
            var {next} = curr;
            if (testFn(curr)) {
                this.removeLink(curr);
            }
            curr = next;
        }
        return this;
    }
}

function setInitial(dll, node) {
    dll.length = 1;
    dll.head = dll.tail = node;
}

function queue$1(worker, concurrency, payload) {
    if (concurrency == null) {
        concurrency = 1;
    }
    else if(concurrency === 0) {
        throw new RangeError('Concurrency must not be zero');
    }

    var _worker = wrapAsync(worker);
    var numRunning = 0;
    var workersList = [];
    const events = {
        error: [],
        drain: [],
        saturated: [],
        unsaturated: [],
        empty: []
    };

    function on (event, handler) {
        events[event].push(handler);
    }

    function once (event, handler) {
        const handleAndRemove = (...args) => {
            off(event, handleAndRemove);
            handler(...args);
        };
        events[event].push(handleAndRemove);
    }

    function off (event, handler) {
        if (!event) return Object.keys(events).forEach(ev => events[ev] = [])
        if (!handler) return events[event] = []
        events[event] = events[event].filter(ev => ev !== handler);
    }

    function trigger (event, ...args) {
        events[event].forEach(handler => handler(...args));
    }

    var processingScheduled = false;
    function _insert(data, insertAtFront, rejectOnError, callback) {
        if (callback != null && typeof callback !== 'function') {
            throw new Error('task callback must be a function');
        }
        q.started = true;

        var res, rej;
        function promiseCallback (err, ...args) {
            // we don't care about the error, let the global error handler
            // deal with it
            if (err) return rejectOnError ? rej(err) : res()
            if (args.length <= 1) return res(args[0])
            res(args);
        }

        var item = q._createTaskItem(
            data,
            rejectOnError ? promiseCallback :
                (callback || promiseCallback)
        );

        if (insertAtFront) {
            q._tasks.unshift(item);
        } else {
            q._tasks.push(item);
        }

        if (!processingScheduled) {
            processingScheduled = true;
            setImmediate$1(() => {
                processingScheduled = false;
                q.process();
            });
        }

        if (rejectOnError || !callback) {
            return new Promise((resolve, reject) => {
                res = resolve;
                rej = reject;
            })
        }
    }

    function _createCB(tasks) {
        return function (err, ...args) {
            numRunning -= 1;

            for (var i = 0, l = tasks.length; i < l; i++) {
                var task = tasks[i];

                var index = workersList.indexOf(task);
                if (index === 0) {
                    workersList.shift();
                } else if (index > 0) {
                    workersList.splice(index, 1);
                }

                task.callback(err, ...args);

                if (err != null) {
                    trigger('error', err, task.data);
                }
            }

            if (numRunning <= (q.concurrency - q.buffer) ) {
                trigger('unsaturated');
            }

            if (q.idle()) {
                trigger('drain');
            }
            q.process();
        };
    }

    function _maybeDrain(data) {
        if (data.length === 0 && q.idle()) {
            // call drain immediately if there are no tasks
            setImmediate$1(() => trigger('drain'));
            return true
        }
        return false
    }

    const eventMethod = (name) => (handler) => {
        if (!handler) {
            return new Promise((resolve, reject) => {
                once(name, (err, data) => {
                    if (err) return reject(err)
                    resolve(data);
                });
            })
        }
        off(name);
        on(name, handler);

    };

    var isProcessing = false;
    var q = {
        _tasks: new DLL(),
        _createTaskItem (data, callback) {
            return {
                data,
                callback
            };
        },
        *[Symbol.iterator] () {
            yield* q._tasks[Symbol.iterator]();
        },
        concurrency,
        payload,
        buffer: concurrency / 4,
        started: false,
        paused: false,
        push (data, callback) {
            if (Array.isArray(data)) {
                if (_maybeDrain(data)) return
                return data.map(datum => _insert(datum, false, false, callback))
            }
            return _insert(data, false, false, callback);
        },
        pushAsync (data, callback) {
            if (Array.isArray(data)) {
                if (_maybeDrain(data)) return
                return data.map(datum => _insert(datum, false, true, callback))
            }
            return _insert(data, false, true, callback);
        },
        kill () {
            off();
            q._tasks.empty();
        },
        unshift (data, callback) {
            if (Array.isArray(data)) {
                if (_maybeDrain(data)) return
                return data.map(datum => _insert(datum, true, false, callback))
            }
            return _insert(data, true, false, callback);
        },
        unshiftAsync (data, callback) {
            if (Array.isArray(data)) {
                if (_maybeDrain(data)) return
                return data.map(datum => _insert(datum, true, true, callback))
            }
            return _insert(data, true, true, callback);
        },
        remove (testFn) {
            q._tasks.remove(testFn);
        },
        process () {
            // Avoid trying to start too many processing operations. This can occur
            // when callbacks resolve synchronously (#1267).
            if (isProcessing) {
                return;
            }
            isProcessing = true;
            while(!q.paused && numRunning < q.concurrency && q._tasks.length){
                var tasks = [], data = [];
                var l = q._tasks.length;
                if (q.payload) l = Math.min(l, q.payload);
                for (var i = 0; i < l; i++) {
                    var node = q._tasks.shift();
                    tasks.push(node);
                    workersList.push(node);
                    data.push(node.data);
                }

                numRunning += 1;

                if (q._tasks.length === 0) {
                    trigger('empty');
                }

                if (numRunning === q.concurrency) {
                    trigger('saturated');
                }

                var cb = onlyOnce(_createCB(tasks));
                _worker(data, cb);
            }
            isProcessing = false;
        },
        length () {
            return q._tasks.length;
        },
        running () {
            return numRunning;
        },
        workersList () {
            return workersList;
        },
        idle() {
            return q._tasks.length + numRunning === 0;
        },
        pause () {
            q.paused = true;
        },
        resume () {
            if (q.paused === false) { return; }
            q.paused = false;
            setImmediate$1(q.process);
        }
    };
    // define these as fixed properties, so people get useful errors when updating
    Object.defineProperties(q, {
        saturated: {
            writable: false,
            value: eventMethod('saturated')
        },
        unsaturated: {
            writable: false,
            value: eventMethod('unsaturated')
        },
        empty: {
            writable: false,
            value: eventMethod('empty')
        },
        drain: {
            writable: false,
            value: eventMethod('drain')
        },
        error: {
            writable: false,
            value: eventMethod('error')
        },
    });
    return q;
}

/**
 * Creates a `cargo` object with the specified payload. Tasks added to the
 * cargo will be processed altogether (up to the `payload` limit). If the
 * `worker` is in progress, the task is queued until it becomes available. Once
 * the `worker` has completed some tasks, each callback of those tasks is
 * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
 * for how `cargo` and `queue` work.
 *
 * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
 * at a time, cargo passes an array of tasks to a single worker, repeating
 * when the worker is finished.
 *
 * @name cargo
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.queue]{@link module:ControlFlow.queue}
 * @category Control Flow
 * @param {AsyncFunction} worker - An asynchronous function for processing an array
 * of queued tasks. Invoked with `(tasks, callback)`.
 * @param {number} [payload=Infinity] - An optional `integer` for determining
 * how many tasks should be processed per round; if omitted, the default is
 * unlimited.
 * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can
 * attached as certain properties to listen for specific events during the
 * lifecycle of the cargo and inner queue.
 * @example
 *
 * // create a cargo object with payload 2
 * var cargo = async.cargo(function(tasks, callback) {
 *     for (var i=0; i<tasks.length; i++) {
 *         console.log('hello ' + tasks[i].name);
 *     }
 *     callback();
 * }, 2);
 *
 * // add some items
 * cargo.push({name: 'foo'}, function(err) {
 *     console.log('finished processing foo');
 * });
 * cargo.push({name: 'bar'}, function(err) {
 *     console.log('finished processing bar');
 * });
 * await cargo.push({name: 'baz'});
 * console.log('finished processing baz');
 */
function cargo$1(worker, payload) {
    return queue$1(worker, 1, payload);
}

/**
 * Creates a `cargoQueue` object with the specified payload. Tasks added to the
 * cargoQueue will be processed together (up to the `payload` limit) in `concurrency` parallel workers.
 * If the all `workers` are in progress, the task is queued until one becomes available. Once
 * a `worker` has completed some tasks, each callback of those tasks is
 * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
 * for how `cargo` and `queue` work.
 *
 * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
 * at a time, and [`cargo`]{@link module:ControlFlow.cargo} passes an array of tasks to a single worker,
 * the cargoQueue passes an array of tasks to multiple parallel workers.
 *
 * @name cargoQueue
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.queue]{@link module:ControlFlow.queue}
 * @see [async.cargo]{@link module:ControlFLow.cargo}
 * @category Control Flow
 * @param {AsyncFunction} worker - An asynchronous function for processing an array
 * of queued tasks. Invoked with `(tasks, callback)`.
 * @param {number} [concurrency=1] - An `integer` for determining how many
 * `worker` functions should be run in parallel.  If omitted, the concurrency
 * defaults to `1`.  If the concurrency is `0`, an error is thrown.
 * @param {number} [payload=Infinity] - An optional `integer` for determining
 * how many tasks should be processed per round; if omitted, the default is
 * unlimited.
 * @returns {module:ControlFlow.QueueObject} A cargoQueue object to manage the tasks. Callbacks can
 * attached as certain properties to listen for specific events during the
 * lifecycle of the cargoQueue and inner queue.
 * @example
 *
 * // create a cargoQueue object with payload 2 and concurrency 2
 * var cargoQueue = async.cargoQueue(function(tasks, callback) {
 *     for (var i=0; i<tasks.length; i++) {
 *         console.log('hello ' + tasks[i].name);
 *     }
 *     callback();
 * }, 2, 2);
 *
 * // add some items
 * cargoQueue.push({name: 'foo'}, function(err) {
 *     console.log('finished processing foo');
 * });
 * cargoQueue.push({name: 'bar'}, function(err) {
 *     console.log('finished processing bar');
 * });
 * cargoQueue.push({name: 'baz'}, function(err) {
 *     console.log('finished processing baz');
 * });
 * cargoQueue.push({name: 'boo'}, function(err) {
 *     console.log('finished processing boo');
 * });
 */
function cargo(worker, concurrency, payload) {
    return queue$1(worker, concurrency, payload);
}

/**
 * Reduces `coll` into a single value using an async `iteratee` to return each
 * successive step. `memo` is the initial state of the reduction. This function
 * only operates in series.
 *
 * For performance reasons, it may make sense to split a call to this function
 * into a parallel map, and then use the normal `Array.prototype.reduce` on the
 * results. This function is for situations where each step in the reduction
 * needs to be async; if you can get the data before reducing it, then it's
 * probably a good idea to do so.
 *
 * @name reduce
 * @static
 * @memberOf module:Collections
 * @method
 * @alias inject
 * @alias foldl
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {*} memo - The initial state of the reduction.
 * @param {AsyncFunction} iteratee - A function applied to each item in the
 * array to produce the next step in the reduction.
 * The `iteratee` should complete with the next state of the reduction.
 * If the iteratee completes with an error, the reduction is stopped and the
 * main `callback` is immediately called with the error.
 * Invoked with (memo, item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Result is the reduced value. Invoked with
 * (err, result).
 * @returns {Promise} a promise, if no callback is passed
 * @example
 *
 * // file1.txt is a file that is 1000 bytes in size
 * // file2.txt is a file that is 2000 bytes in size
 * // file3.txt is a file that is 3000 bytes in size
 * // file4.txt does not exist
 *
 * const fileList = ['file1.txt','file2.txt','file3.txt'];
 * const withMissingFileList = ['file1.txt','file2.txt','file3.txt', 'file4.txt'];
 *
 * // asynchronous function that computes the file size in bytes
 * // file size is added to the memoized value, then returned
 * function getFileSizeInBytes(memo, file, callback) {
 *     fs.stat(file, function(err, stat) {
 *         if (err) {
 *             return callback(err);
 *         }
 *         callback(null, memo + stat.size);
 *     });
 * }
 *
 * // Using callbacks
 * async.reduce(fileList, 0, getFileSizeInBytes, function(err, result) {
 *     if (err) {
 *         console.log(err);
 *     } else {
 *         console.log(result);
 *         // 6000
 *         // which is the sum of the file sizes of the three files
 *     }
 * });
 *
 * // Error Handling
 * async.reduce(withMissingFileList, 0, getFileSizeInBytes, function(err, result) {
 *     if (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *     } else {
 *         console.log(result);
 *     }
 * });
 *
 * // Using Promises
 * async.reduce(fileList, 0, getFileSizeInBytes)
 * .then( result => {
 *     console.log(result);
 *     // 6000
 *     // which is the sum of the file sizes of the three files
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * // Error Handling
 * async.reduce(withMissingFileList, 0, getFileSizeInBytes)
 * .then( result => {
 *     console.log(result);
 * }).catch( err => {
 *     console.log(err);
 *     // [ Error: ENOENT: no such file or directory ]
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let result = await async.reduce(fileList, 0, getFileSizeInBytes);
 *         console.log(result);
 *         // 6000
 *         // which is the sum of the file sizes of the three files
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * // Error Handling
 * async () => {
 *     try {
 *         let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes);
 *         console.log(result);
 *     }
 *     catch (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *     }
 * }
 *
 */
function reduce(coll, memo, iteratee, callback) {
    callback = once$1(callback);
    var _iteratee = wrapAsync(iteratee);
    return eachOfSeries$1(coll, (x, i, iterCb) => {
        _iteratee(memo, x, (err, v) => {
            memo = v;
            iterCb(err);
        });
    }, err => callback(err, memo));
}
var reduce$1 = awaitify(reduce, 4);

/**
 * Version of the compose function that is more natural to read. Each function
 * consumes the return value of the previous function. It is the equivalent of
 * [compose]{@link module:ControlFlow.compose} with the arguments reversed.
 *
 * Each function is executed with the `this` binding of the composed function.
 *
 * @name seq
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.compose]{@link module:ControlFlow.compose}
 * @category Control Flow
 * @param {...AsyncFunction} functions - the asynchronous functions to compose
 * @returns {Function} a function that composes the `functions` in order
 * @example
 *
 * // Requires lodash (or underscore), express3 and dresende's orm2.
 * // Part of an app, that fetches cats of the logged user.
 * // This example uses `seq` function to avoid overnesting and error
 * // handling clutter.
 * app.get('/cats', function(request, response) {
 *     var User = request.models.User;
 *     async.seq(
 *         User.get.bind(User),  // 'User.get' has signature (id, callback(err, data))
 *         function(user, fn) {
 *             user.getCats(fn);      // 'getCats' has signature (callback(err, data))
 *         }
 *     )(req.session.user_id, function (err, cats) {
 *         if (err) {
 *             console.error(err);
 *             response.json({ status: 'error', message: err.message });
 *         } else {
 *             response.json({ status: 'ok', message: 'Cats found', data: cats });
 *         }
 *     });
 * });
 */
function seq(...functions) {
    var _functions = functions.map(wrapAsync);
    return function (...args) {
        var that = this;

        var cb = args[args.length - 1];
        if (typeof cb == 'function') {
            args.pop();
        } else {
            cb = promiseCallback();
        }

        reduce$1(_functions, args, (newargs, fn, iterCb) => {
            fn.apply(that, newargs.concat((err, ...nextargs) => {
                iterCb(err, nextargs);
            }));
        },
        (err, results) => cb(err, ...results));

        return cb[PROMISE_SYMBOL]
    };
}

/**
 * Creates a function which is a composition of the passed asynchronous
 * functions. Each function consumes the return value of the function that
 * follows. Composing functions `f()`, `g()`, and `h()` would produce the result
 * of `f(g(h()))`, only this version uses callbacks to obtain the return values.
 *
 * If the last argument to the composed function is not a function, a promise
 * is returned when you call it.
 *
 * Each function is executed with the `this` binding of the composed function.
 *
 * @name compose
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {...AsyncFunction} functions - the asynchronous functions to compose
 * @returns {Function} an asynchronous function that is the composed
 * asynchronous `functions`
 * @example
 *
 * function add1(n, callback) {
 *     setTimeout(function () {
 *         callback(null, n + 1);
 *     }, 10);
 * }
 *
 * function mul3(n, callback) {
 *     setTimeout(function () {
 *         callback(null, n * 3);
 *     }, 10);
 * }
 *
 * var add1mul3 = async.compose(mul3, add1);
 * add1mul3(4, function (err, result) {
 *     // result now equals 15
 * });
 */
function compose(...args) {
    return seq(...args.reverse());
}

/**
 * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.
 *
 * @name mapLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.map]{@link module:Collections.map}
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * The iteratee should complete with the transformed item.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. Results is an array of the
 * transformed items from the `coll`. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback is passed
 */
function mapLimit (coll, limit, iteratee, callback) {
    return _asyncMap(eachOfLimit$2(limit), coll, iteratee, callback)
}
var mapLimit$1 = awaitify(mapLimit, 4);

/**
 * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
 *
 * @name concatLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.concat]{@link module:Collections.concat}
 * @category Collection
 * @alias flatMapLimit
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
 * which should use an array as its result. Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished, or an error occurs. Results is an array
 * containing the concatenated results of the `iteratee` function. Invoked with
 * (err, results).
 * @returns A Promise, if no callback is passed
 */
function concatLimit(coll, limit, iteratee, callback) {
    var _iteratee = wrapAsync(iteratee);
    return mapLimit$1(coll, limit, (val, iterCb) => {
        _iteratee(val, (err, ...args) => {
            if (err) return iterCb(err);
            return iterCb(err, args);
        });
    }, (err, mapResults) => {
        var result = [];
        for (var i = 0; i < mapResults.length; i++) {
            if (mapResults[i]) {
                result = result.concat(...mapResults[i]);
            }
        }

        return callback(err, result);
    });
}
var concatLimit$1 = awaitify(concatLimit, 4);

/**
 * Applies `iteratee` to each item in `coll`, concatenating the results. Returns
 * the concatenated list. The `iteratee`s are called in parallel, and the
 * results are concatenated as they return. The results array will be returned in
 * the original order of `coll` passed to the `iteratee` function.
 *
 * @name concat
 * @static
 * @memberOf module:Collections
 * @method
 * @category Collection
 * @alias flatMap
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
 * which should use an array as its result. Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished, or an error occurs. Results is an array
 * containing the concatenated results of the `iteratee` function. Invoked with
 * (err, results).
 * @returns A Promise, if no callback is passed
 * @example
 *
 * // dir1 is a directory that contains file1.txt, file2.txt
 * // dir2 is a directory that contains file3.txt, file4.txt
 * // dir3 is a directory that contains file5.txt
 * // dir4 does not exist
 *
 * let directoryList = ['dir1','dir2','dir3'];
 * let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4'];
 *
 * // Using callbacks
 * async.concat(directoryList, fs.readdir, function(err, results) {
 *    if (err) {
 *        console.log(err);
 *    } else {
 *        console.log(results);
 *        // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
 *    }
 * });
 *
 * // Error Handling
 * async.concat(withMissingDirectoryList, fs.readdir, function(err, results) {
 *    if (err) {
 *        console.log(err);
 *        // [ Error: ENOENT: no such file or directory ]
 *        // since dir4 does not exist
 *    } else {
 *        console.log(results);
 *    }
 * });
 *
 * // Using Promises
 * async.concat(directoryList, fs.readdir)
 * .then(results => {
 *     console.log(results);
 *     // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
 * }).catch(err => {
 *      console.log(err);
 * });
 *
 * // Error Handling
 * async.concat(withMissingDirectoryList, fs.readdir)
 * .then(results => {
 *     console.log(results);
 * }).catch(err => {
 *     console.log(err);
 *     // [ Error: ENOENT: no such file or directory ]
 *     // since dir4 does not exist
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let results = await async.concat(directoryList, fs.readdir);
 *         console.log(results);
 *         // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
 *     } catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * // Error Handling
 * async () => {
 *     try {
 *         let results = await async.concat(withMissingDirectoryList, fs.readdir);
 *         console.log(results);
 *     } catch (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *         // since dir4 does not exist
 *     }
 * }
 *
 */
function concat(coll, iteratee, callback) {
    return concatLimit$1(coll, Infinity, iteratee, callback)
}
var concat$1 = awaitify(concat, 3);

/**
 * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
 *
 * @name concatSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.concat]{@link module:Collections.concat}
 * @category Collection
 * @alias flatMapSeries
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
 * The iteratee should complete with an array an array of results.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished, or an error occurs. Results is an array
 * containing the concatenated results of the `iteratee` function. Invoked with
 * (err, results).
 * @returns A Promise, if no callback is passed
 */
function concatSeries(coll, iteratee, callback) {
    return concatLimit$1(coll, 1, iteratee, callback)
}
var concatSeries$1 = awaitify(concatSeries, 3);

/**
 * Returns a function that when called, calls-back with the values provided.
 * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to
 * [`auto`]{@link module:ControlFlow.auto}.
 *
 * @name constant
 * @static
 * @memberOf module:Utils
 * @method
 * @category Util
 * @param {...*} arguments... - Any number of arguments to automatically invoke
 * callback with.
 * @returns {AsyncFunction} Returns a function that when invoked, automatically
 * invokes the callback with the previous given arguments.
 * @example
 *
 * async.waterfall([
 *     async.constant(42),
 *     function (value, next) {
 *         // value === 42
 *     },
 *     //...
 * ], callback);
 *
 * async.waterfall([
 *     async.constant(filename, "utf8"),
 *     fs.readFile,
 *     function (fileData, next) {
 *         //...
 *     }
 *     //...
 * ], callback);
 *
 * async.auto({
 *     hostname: async.constant("https://server.net/"),
 *     port: findFreePort,
 *     launchServer: ["hostname", "port", function (options, cb) {
 *         startServer(options, cb);
 *     }],
 *     //...
 * }, callback);
 */
function constant$1(...args) {
    return function (...ignoredArgs/*, callback*/) {
        var callback = ignoredArgs.pop();
        return callback(null, ...args);
    };
}

function _createTester(check, getResult) {
    return (eachfn, arr, _iteratee, cb) => {
        var testPassed = false;
        var testResult;
        const iteratee = wrapAsync(_iteratee);
        eachfn(arr, (value, _, callback) => {
            iteratee(value, (err, result) => {
                if (err || err === false) return callback(err);

                if (check(result) && !testResult) {
                    testPassed = true;
                    testResult = getResult(true, value);
                    return callback(null, breakLoop);
                }
                callback();
            });
        }, err => {
            if (err) return cb(err);
            cb(null, testPassed ? testResult : getResult(false));
        });
    };
}

/**
 * Returns the first value in `coll` that passes an async truth test. The
 * `iteratee` is applied in parallel, meaning the first iteratee to return
 * `true` will fire the detect `callback` with that result. That means the
 * result might not be the first item in the original `coll` (in terms of order)
 * that passes the test.

 * If order within the original `coll` is important, then look at
 * [`detectSeries`]{@link module:Collections.detectSeries}.
 *
 * @name detect
 * @static
 * @memberOf module:Collections
 * @method
 * @alias find
 * @category Collections
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
 * The iteratee must complete with a boolean value as its result.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called as soon as any
 * iteratee returns `true`, or after all the `iteratee` functions have finished.
 * Result will be the first item in the array that passes the truth test
 * (iteratee) or the value `undefined` if none passed. Invoked with
 * (err, result).
 * @returns {Promise} a promise, if a callback is omitted
 * @example
 *
 * // dir1 is a directory that contains file1.txt, file2.txt
 * // dir2 is a directory that contains file3.txt, file4.txt
 * // dir3 is a directory that contains file5.txt
 *
 * // asynchronous function that checks if a file exists
 * function fileExists(file, callback) {
 *    fs.access(file, fs.constants.F_OK, (err) => {
 *        callback(null, !err);
 *    });
 * }
 *
 * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists,
 *    function(err, result) {
 *        console.log(result);
 *        // dir1/file1.txt
 *        // result now equals the first file in the list that exists
 *    }
 *);
 *
 * // Using Promises
 * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists)
 * .then(result => {
 *     console.log(result);
 *     // dir1/file1.txt
 *     // result now equals the first file in the list that exists
 * }).catch(err => {
 *     console.log(err);
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists);
 *         console.log(result);
 *         // dir1/file1.txt
 *         // result now equals the file in the list that exists
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function detect(coll, iteratee, callback) {
    return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback)
}
var detect$1 = awaitify(detect, 3);

/**
 * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
 * time.
 *
 * @name detectLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.detect]{@link module:Collections.detect}
 * @alias findLimit
 * @category Collections
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
 * The iteratee must complete with a boolean value as its result.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called as soon as any
 * iteratee returns `true`, or after all the `iteratee` functions have finished.
 * Result will be the first item in the array that passes the truth test
 * (iteratee) or the value `undefined` if none passed. Invoked with
 * (err, result).
 * @returns {Promise} a promise, if a callback is omitted
 */
function detectLimit(coll, limit, iteratee, callback) {
    return _createTester(bool => bool, (res, item) => item)(eachOfLimit$2(limit), coll, iteratee, callback)
}
var detectLimit$1 = awaitify(detectLimit, 4);

/**
 * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
 *
 * @name detectSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.detect]{@link module:Collections.detect}
 * @alias findSeries
 * @category Collections
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
 * The iteratee must complete with a boolean value as its result.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called as soon as any
 * iteratee returns `true`, or after all the `iteratee` functions have finished.
 * Result will be the first item in the array that passes the truth test
 * (iteratee) or the value `undefined` if none passed. Invoked with
 * (err, result).
 * @returns {Promise} a promise, if a callback is omitted
 */
function detectSeries(coll, iteratee, callback) {
    return _createTester(bool => bool, (res, item) => item)(eachOfLimit$2(1), coll, iteratee, callback)
}

var detectSeries$1 = awaitify(detectSeries, 3);

function consoleFunc(name) {
    return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => {
        /* istanbul ignore else */
        if (typeof console === 'object') {
            /* istanbul ignore else */
            if (err) {
                /* istanbul ignore else */
                if (console.error) {
                    console.error(err);
                }
            } else if (console[name]) { /* istanbul ignore else */
                resultArgs.forEach(x => console[name](x));
            }
        }
    })
}

/**
 * Logs the result of an [`async` function]{@link AsyncFunction} to the
 * `console` using `console.dir` to display the properties of the resulting object.
 * Only works in Node.js or in browsers that support `console.dir` and
 * `console.error` (such as FF and Chrome).
 * If multiple arguments are returned from the async function,
 * `console.dir` is called on each argument in order.
 *
 * @name dir
 * @static
 * @memberOf module:Utils
 * @method
 * @category Util
 * @param {AsyncFunction} function - The function you want to eventually apply
 * all arguments to.
 * @param {...*} arguments... - Any number of arguments to apply to the function.
 * @example
 *
 * // in a module
 * var hello = function(name, callback) {
 *     setTimeout(function() {
 *         callback(null, {hello: name});
 *     }, 1000);
 * };
 *
 * // in the node repl
 * node> async.dir(hello, 'world');
 * {hello: 'world'}
 */
var dir = consoleFunc('dir');

/**
 * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
 * the order of operations, the arguments `test` and `iteratee` are switched.
 *
 * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
 *
 * @name doWhilst
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.whilst]{@link module:ControlFlow.whilst}
 * @category Control Flow
 * @param {AsyncFunction} iteratee - A function which is called each time `test`
 * passes. Invoked with (callback).
 * @param {AsyncFunction} test - asynchronous truth test to perform after each
 * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
 * non-error args from the previous callback of `iteratee`.
 * @param {Function} [callback] - A callback which is called after the test
 * function has failed and repeated execution of `iteratee` has stopped.
 * `callback` will be passed an error and any arguments passed to the final
 * `iteratee`'s callback. Invoked with (err, [results]);
 * @returns {Promise} a promise, if no callback is passed
 */
function doWhilst(iteratee, test, callback) {
    callback = onlyOnce(callback);
    var _fn = wrapAsync(iteratee);
    var _test = wrapAsync(test);
    var results;

    function next(err, ...args) {
        if (err) return callback(err);
        if (err === false) return;
        results = args;
        _test(...args, check);
    }

    function check(err, truth) {
        if (err) return callback(err);
        if (err === false) return;
        if (!truth) return callback(null, ...results);
        _fn(next);
    }

    return check(null, true);
}

var doWhilst$1 = awaitify(doWhilst, 3);

/**
 * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the
 * argument ordering differs from `until`.
 *
 * @name doUntil
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.doWhilst]{@link module:ControlFlow.doWhilst}
 * @category Control Flow
 * @param {AsyncFunction} iteratee - An async function which is called each time
 * `test` fails. Invoked with (callback).
 * @param {AsyncFunction} test - asynchronous truth test to perform after each
 * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
 * non-error args from the previous callback of `iteratee`
 * @param {Function} [callback] - A callback which is called after the test
 * function has passed and repeated execution of `iteratee` has stopped. `callback`
 * will be passed an error and any arguments passed to the final `iteratee`'s
 * callback. Invoked with (err, [results]);
 * @returns {Promise} a promise, if no callback is passed
 */
function doUntil(iteratee, test, callback) {
    const _test = wrapAsync(test);
    return doWhilst$1(iteratee, (...args) => {
        const cb = args.pop();
        _test(...args, (err, truth) => cb (err, !truth));
    }, callback);
}

function _withoutIndex(iteratee) {
    return (value, index, callback) => iteratee(value, callback);
}

/**
 * Applies the function `iteratee` to each item in `coll`, in parallel.
 * The `iteratee` is called with an item from the list, and a callback for when
 * it has finished. If the `iteratee` passes an error to its `callback`, the
 * main `callback` (for the `each` function) is immediately called with the
 * error.
 *
 * Note, that since this function applies `iteratee` to each item in parallel,
 * there is no guarantee that the iteratee functions will complete in order.
 *
 * @name each
 * @static
 * @memberOf module:Collections
 * @method
 * @alias forEach
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async function to apply to
 * each item in `coll`. Invoked with (item, callback).
 * The array index is not passed to the iteratee.
 * If you need the index, use `eachOf`.
 * @param {Function} [callback] - A callback which is called when all
 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
 * @returns {Promise} a promise, if a callback is omitted
 * @example
 *
 * // dir1 is a directory that contains file1.txt, file2.txt
 * // dir2 is a directory that contains file3.txt, file4.txt
 * // dir3 is a directory that contains file5.txt
 * // dir4 does not exist
 *
 * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt'];
 * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt'];
 *
 * // asynchronous function that deletes a file
 * const deleteFile = function(file, callback) {
 *     fs.unlink(file, callback);
 * };
 *
 * // Using callbacks
 * async.each(fileList, deleteFile, function(err) {
 *     if( err ) {
 *         console.log(err);
 *     } else {
 *         console.log('All files have been deleted successfully');
 *     }
 * });
 *
 * // Error Handling
 * async.each(withMissingFileList, deleteFile, function(err){
 *     console.log(err);
 *     // [ Error: ENOENT: no such file or directory ]
 *     // since dir4/file2.txt does not exist
 *     // dir1/file1.txt could have been deleted
 * });
 *
 * // Using Promises
 * async.each(fileList, deleteFile)
 * .then( () => {
 *     console.log('All files have been deleted successfully');
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * // Error Handling
 * async.each(fileList, deleteFile)
 * .then( () => {
 *     console.log('All files have been deleted successfully');
 * }).catch( err => {
 *     console.log(err);
 *     // [ Error: ENOENT: no such file or directory ]
 *     // since dir4/file2.txt does not exist
 *     // dir1/file1.txt could have been deleted
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         await async.each(files, deleteFile);
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * // Error Handling
 * async () => {
 *     try {
 *         await async.each(withMissingFileList, deleteFile);
 *     }
 *     catch (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *         // since dir4/file2.txt does not exist
 *         // dir1/file1.txt could have been deleted
 *     }
 * }
 *
 */
function eachLimit$2(coll, iteratee, callback) {
    return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback);
}

var each = awaitify(eachLimit$2, 3);

/**
 * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
 *
 * @name eachLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.each]{@link module:Collections.each}
 * @alias forEachLimit
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * The array index is not passed to the iteratee.
 * If you need the index, use `eachOfLimit`.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called when all
 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
 * @returns {Promise} a promise, if a callback is omitted
 */
function eachLimit(coll, limit, iteratee, callback) {
    return eachOfLimit$2(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);
}
var eachLimit$1 = awaitify(eachLimit, 4);

/**
 * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
 *
 * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item
 * in series and therefore the iteratee functions will complete in order.

 * @name eachSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.each]{@link module:Collections.each}
 * @alias forEachSeries
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async function to apply to each
 * item in `coll`.
 * The array index is not passed to the iteratee.
 * If you need the index, use `eachOfSeries`.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called when all
 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
 * @returns {Promise} a promise, if a callback is omitted
 */
function eachSeries(coll, iteratee, callback) {
    return eachLimit$1(coll, 1, iteratee, callback)
}
var eachSeries$1 = awaitify(eachSeries, 3);

/**
 * Wrap an async function and ensure it calls its callback on a later tick of
 * the event loop.  If the function already calls its callback on a next tick,
 * no extra deferral is added. This is useful for preventing stack overflows
 * (`RangeError: Maximum call stack size exceeded`) and generally keeping
 * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
 * contained. ES2017 `async` functions are returned as-is -- they are immune
 * to Zalgo's corrupting influences, as they always resolve on a later tick.
 *
 * @name ensureAsync
 * @static
 * @memberOf module:Utils
 * @method
 * @category Util
 * @param {AsyncFunction} fn - an async function, one that expects a node-style
 * callback as its last argument.
 * @returns {AsyncFunction} Returns a wrapped function with the exact same call
 * signature as the function passed in.
 * @example
 *
 * function sometimesAsync(arg, callback) {
 *     if (cache[arg]) {
 *         return callback(null, cache[arg]); // this would be synchronous!!
 *     } else {
 *         doSomeIO(arg, callback); // this IO would be asynchronous
 *     }
 * }
 *
 * // this has a risk of stack overflows if many results are cached in a row
 * async.mapSeries(args, sometimesAsync, done);
 *
 * // this will defer sometimesAsync's callback if necessary,
 * // preventing stack overflows
 * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
 */
function ensureAsync(fn) {
    if (isAsync(fn)) return fn;
    return function (...args/*, callback*/) {
        var callback = args.pop();
        var sync = true;
        args.push((...innerArgs) => {
            if (sync) {
                setImmediate$1(() => callback(...innerArgs));
            } else {
                callback(...innerArgs);
            }
        });
        fn.apply(this, args);
        sync = false;
    };
}

/**
 * Returns `true` if every element in `coll` satisfies an async test. If any
 * iteratee call returns `false`, the main `callback` is immediately called.
 *
 * @name every
 * @static
 * @memberOf module:Collections
 * @method
 * @alias all
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
 * in the collection in parallel.
 * The iteratee must complete with a boolean result value.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Result will be either `true` or `false`
 * depending on the values of the async tests. Invoked with (err, result).
 * @returns {Promise} a promise, if no callback provided
 * @example
 *
 * // dir1 is a directory that contains file1.txt, file2.txt
 * // dir2 is a directory that contains file3.txt, file4.txt
 * // dir3 is a directory that contains file5.txt
 * // dir4 does not exist
 *
 * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt'];
 * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];
 *
 * // asynchronous function that checks if a file exists
 * function fileExists(file, callback) {
 *    fs.access(file, fs.constants.F_OK, (err) => {
 *        callback(null, !err);
 *    });
 * }
 *
 * // Using callbacks
 * async.every(fileList, fileExists, function(err, result) {
 *     console.log(result);
 *     // true
 *     // result is true since every file exists
 * });
 *
 * async.every(withMissingFileList, fileExists, function(err, result) {
 *     console.log(result);
 *     // false
 *     // result is false since NOT every file exists
 * });
 *
 * // Using Promises
 * async.every(fileList, fileExists)
 * .then( result => {
 *     console.log(result);
 *     // true
 *     // result is true since every file exists
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * async.every(withMissingFileList, fileExists)
 * .then( result => {
 *     console.log(result);
 *     // false
 *     // result is false since NOT every file exists
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let result = await async.every(fileList, fileExists);
 *         console.log(result);
 *         // true
 *         // result is true since every file exists
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * async () => {
 *     try {
 *         let result = await async.every(withMissingFileList, fileExists);
 *         console.log(result);
 *         // false
 *         // result is false since NOT every file exists
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function every(coll, iteratee, callback) {
    return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback)
}
var every$1 = awaitify(every, 3);

/**
 * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
 *
 * @name everyLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.every]{@link module:Collections.every}
 * @alias allLimit
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
 * in the collection in parallel.
 * The iteratee must complete with a boolean result value.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Result will be either `true` or `false`
 * depending on the values of the async tests. Invoked with (err, result).
 * @returns {Promise} a promise, if no callback provided
 */
function everyLimit(coll, limit, iteratee, callback) {
    return _createTester(bool => !bool, res => !res)(eachOfLimit$2(limit), coll, iteratee, callback)
}
var everyLimit$1 = awaitify(everyLimit, 4);

/**
 * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
 *
 * @name everySeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.every]{@link module:Collections.every}
 * @alias allSeries
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
 * in the collection in series.
 * The iteratee must complete with a boolean result value.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Result will be either `true` or `false`
 * depending on the values of the async tests. Invoked with (err, result).
 * @returns {Promise} a promise, if no callback provided
 */
function everySeries(coll, iteratee, callback) {
    return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback)
}
var everySeries$1 = awaitify(everySeries, 3);

function filterArray(eachfn, arr, iteratee, callback) {
    var truthValues = new Array(arr.length);
    eachfn(arr, (x, index, iterCb) => {
        iteratee(x, (err, v) => {
            truthValues[index] = !!v;
            iterCb(err);
        });
    }, err => {
        if (err) return callback(err);
        var results = [];
        for (var i = 0; i < arr.length; i++) {
            if (truthValues[i]) results.push(arr[i]);
        }
        callback(null, results);
    });
}

function filterGeneric(eachfn, coll, iteratee, callback) {
    var results = [];
    eachfn(coll, (x, index, iterCb) => {
        iteratee(x, (err, v) => {
            if (err) return iterCb(err);
            if (v) {
                results.push({index, value: x});
            }
            iterCb(err);
        });
    }, err => {
        if (err) return callback(err);
        callback(null, results
            .sort((a, b) => a.index - b.index)
            .map(v => v.value));
    });
}

function _filter(eachfn, coll, iteratee, callback) {
    var filter = isArrayLike(coll) ? filterArray : filterGeneric;
    return filter(eachfn, coll, wrapAsync(iteratee), callback);
}

/**
 * Returns a new array of all the values in `coll` which pass an async truth
 * test. This operation is performed in parallel, but the results array will be
 * in the same order as the original.
 *
 * @name filter
 * @static
 * @memberOf module:Collections
 * @method
 * @alias select
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
 * with a boolean argument once it has completed. Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback provided
 * @example
 *
 * // dir1 is a directory that contains file1.txt, file2.txt
 * // dir2 is a directory that contains file3.txt, file4.txt
 * // dir3 is a directory that contains file5.txt
 *
 * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];
 *
 * // asynchronous function that checks if a file exists
 * function fileExists(file, callback) {
 *    fs.access(file, fs.constants.F_OK, (err) => {
 *        callback(null, !err);
 *    });
 * }
 *
 * // Using callbacks
 * async.filter(files, fileExists, function(err, results) {
 *    if(err) {
 *        console.log(err);
 *    } else {
 *        console.log(results);
 *        // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
 *        // results is now an array of the existing files
 *    }
 * });
 *
 * // Using Promises
 * async.filter(files, fileExists)
 * .then(results => {
 *     console.log(results);
 *     // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
 *     // results is now an array of the existing files
 * }).catch(err => {
 *     console.log(err);
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let results = await async.filter(files, fileExists);
 *         console.log(results);
 *         // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
 *         // results is now an array of the existing files
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function filter (coll, iteratee, callback) {
    return _filter(eachOf$1, coll, iteratee, callback)
}
var filter$1 = awaitify(filter, 3);

/**
 * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a
 * time.
 *
 * @name filterLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.filter]{@link module:Collections.filter}
 * @alias selectLimit
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
 * with a boolean argument once it has completed. Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback provided
 */
function filterLimit (coll, limit, iteratee, callback) {
    return _filter(eachOfLimit$2(limit), coll, iteratee, callback)
}
var filterLimit$1 = awaitify(filterLimit, 4);

/**
 * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.
 *
 * @name filterSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.filter]{@link module:Collections.filter}
 * @alias selectSeries
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
 * with a boolean argument once it has completed. Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Invoked with (err, results)
 * @returns {Promise} a promise, if no callback provided
 */
function filterSeries (coll, iteratee, callback) {
    return _filter(eachOfSeries$1, coll, iteratee, callback)
}
var filterSeries$1 = awaitify(filterSeries, 3);

/**
 * Calls the asynchronous function `fn` with a callback parameter that allows it
 * to call itself again, in series, indefinitely.

 * If an error is passed to the callback then `errback` is called with the
 * error, and execution stops, otherwise it will never be called.
 *
 * @name forever
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {AsyncFunction} fn - an async function to call repeatedly.
 * Invoked with (next).
 * @param {Function} [errback] - when `fn` passes an error to it's callback,
 * this function will be called, and execution stops. Invoked with (err).
 * @returns {Promise} a promise that rejects if an error occurs and an errback
 * is not passed
 * @example
 *
 * async.forever(
 *     function(next) {
 *         // next is suitable for passing to things that need a callback(err [, whatever]);
 *         // it will result in this function being called again.
 *     },
 *     function(err) {
 *         // if next is called with a value in its first parameter, it will appear
 *         // in here as 'err', and execution will stop.
 *     }
 * );
 */
function forever(fn, errback) {
    var done = onlyOnce(errback);
    var task = wrapAsync(ensureAsync(fn));

    function next(err) {
        if (err) return done(err);
        if (err === false) return;
        task(next);
    }
    return next();
}
var forever$1 = awaitify(forever, 2);

/**
 * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
 *
 * @name groupByLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.groupBy]{@link module:Collections.groupBy}
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * The iteratee should complete with a `key` to group the value under.
 * Invoked with (value, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. Result is an `Object` whoses
 * properties are arrays of values which returned the corresponding key.
 * @returns {Promise} a promise, if no callback is passed
 */
function groupByLimit(coll, limit, iteratee, callback) {
    var _iteratee = wrapAsync(iteratee);
    return mapLimit$1(coll, limit, (val, iterCb) => {
        _iteratee(val, (err, key) => {
            if (err) return iterCb(err);
            return iterCb(err, {key, val});
        });
    }, (err, mapResults) => {
        var result = {};
        // from MDN, handle object having an `hasOwnProperty` prop
        var {hasOwnProperty} = Object.prototype;

        for (var i = 0; i < mapResults.length; i++) {
            if (mapResults[i]) {
                var {key} = mapResults[i];
                var {val} = mapResults[i];

                if (hasOwnProperty.call(result, key)) {
                    result[key].push(val);
                } else {
                    result[key] = [val];
                }
            }
        }

        return callback(err, result);
    });
}

var groupByLimit$1 = awaitify(groupByLimit, 4);

/**
 * Returns a new object, where each value corresponds to an array of items, from
 * `coll`, that returned the corresponding key. That is, the keys of the object
 * correspond to the values passed to the `iteratee` callback.
 *
 * Note: Since this function applies the `iteratee` to each item in parallel,
 * there is no guarantee that the `iteratee` functions will complete in order.
 * However, the values for each key in the `result` will be in the same order as
 * the original `coll`. For Objects, the values will roughly be in the order of
 * the original Objects' keys (but this can vary across JavaScript engines).
 *
 * @name groupBy
 * @static
 * @memberOf module:Collections
 * @method
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * The iteratee should complete with a `key` to group the value under.
 * Invoked with (value, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. Result is an `Object` whoses
 * properties are arrays of values which returned the corresponding key.
 * @returns {Promise} a promise, if no callback is passed
 * @example
 *
 * // dir1 is a directory that contains file1.txt, file2.txt
 * // dir2 is a directory that contains file3.txt, file4.txt
 * // dir3 is a directory that contains file5.txt
 * // dir4 does not exist
 *
 * const files = ['dir1/file1.txt','dir2','dir4']
 *
 * // asynchronous function that detects file type as none, file, or directory
 * function detectFile(file, callback) {
 *     fs.stat(file, function(err, stat) {
 *         if (err) {
 *             return callback(null, 'none');
 *         }
 *         callback(null, stat.isDirectory() ? 'directory' : 'file');
 *     });
 * }
 *
 * //Using callbacks
 * async.groupBy(files, detectFile, function(err, result) {
 *     if(err) {
 *         console.log(err);
 *     } else {
 *	       console.log(result);
 *         // {
 *         //     file: [ 'dir1/file1.txt' ],
 *         //     none: [ 'dir4' ],
 *         //     directory: [ 'dir2']
 *         // }
 *         // result is object containing the files grouped by type
 *     }
 * });
 *
 * // Using Promises
 * async.groupBy(files, detectFile)
 * .then( result => {
 *     console.log(result);
 *     // {
 *     //     file: [ 'dir1/file1.txt' ],
 *     //     none: [ 'dir4' ],
 *     //     directory: [ 'dir2']
 *     // }
 *     // result is object containing the files grouped by type
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let result = await async.groupBy(files, detectFile);
 *         console.log(result);
 *         // {
 *         //     file: [ 'dir1/file1.txt' ],
 *         //     none: [ 'dir4' ],
 *         //     directory: [ 'dir2']
 *         // }
 *         // result is object containing the files grouped by type
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function groupBy (coll, iteratee, callback) {
    return groupByLimit$1(coll, Infinity, iteratee, callback)
}

/**
 * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.
 *
 * @name groupBySeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.groupBy]{@link module:Collections.groupBy}
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * The iteratee should complete with a `key` to group the value under.
 * Invoked with (value, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. Result is an `Object` whose
 * properties are arrays of values which returned the corresponding key.
 * @returns {Promise} a promise, if no callback is passed
 */
function groupBySeries (coll, iteratee, callback) {
    return groupByLimit$1(coll, 1, iteratee, callback)
}

/**
 * Logs the result of an `async` function to the `console`. Only works in
 * Node.js or in browsers that support `console.log` and `console.error` (such
 * as FF and Chrome). If multiple arguments are returned from the async
 * function, `console.log` is called on each argument in order.
 *
 * @name log
 * @static
 * @memberOf module:Utils
 * @method
 * @category Util
 * @param {AsyncFunction} function - The function you want to eventually apply
 * all arguments to.
 * @param {...*} arguments... - Any number of arguments to apply to the function.
 * @example
 *
 * // in a module
 * var hello = function(name, callback) {
 *     setTimeout(function() {
 *         callback(null, 'hello ' + name);
 *     }, 1000);
 * };
 *
 * // in the node repl
 * node> async.log(hello, 'world');
 * 'hello world'
 */
var log = consoleFunc('log');

/**
 * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a
 * time.
 *
 * @name mapValuesLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.mapValues]{@link module:Collections.mapValues}
 * @category Collection
 * @param {Object} obj - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - A function to apply to each value and key
 * in `coll`.
 * The iteratee should complete with the transformed value as its result.
 * Invoked with (value, key, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. `result` is a new object consisting
 * of each key from `obj`, with each transformed value on the right-hand side.
 * Invoked with (err, result).
 * @returns {Promise} a promise, if no callback is passed
 */
function mapValuesLimit(obj, limit, iteratee, callback) {
    callback = once$1(callback);
    var newObj = {};
    var _iteratee = wrapAsync(iteratee);
    return eachOfLimit$2(limit)(obj, (val, key, next) => {
        _iteratee(val, key, (err, result) => {
            if (err) return next(err);
            newObj[key] = result;
            next(err);
        });
    }, err => callback(err, newObj));
}

var mapValuesLimit$1 = awaitify(mapValuesLimit, 4);

/**
 * A relative of [`map`]{@link module:Collections.map}, designed for use with objects.
 *
 * Produces a new Object by mapping each value of `obj` through the `iteratee`
 * function. The `iteratee` is called each `value` and `key` from `obj` and a
 * callback for when it has finished processing. Each of these callbacks takes
 * two arguments: an `error`, and the transformed item from `obj`. If `iteratee`
 * passes an error to its callback, the main `callback` (for the `mapValues`
 * function) is immediately called with the error.
 *
 * Note, the order of the keys in the result is not guaranteed.  The keys will
 * be roughly in the order they complete, (but this is very engine-specific)
 *
 * @name mapValues
 * @static
 * @memberOf module:Collections
 * @method
 * @category Collection
 * @param {Object} obj - A collection to iterate over.
 * @param {AsyncFunction} iteratee - A function to apply to each value and key
 * in `coll`.
 * The iteratee should complete with the transformed value as its result.
 * Invoked with (value, key, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. `result` is a new object consisting
 * of each key from `obj`, with each transformed value on the right-hand side.
 * Invoked with (err, result).
 * @returns {Promise} a promise, if no callback is passed
 * @example
 *
 * // file1.txt is a file that is 1000 bytes in size
 * // file2.txt is a file that is 2000 bytes in size
 * // file3.txt is a file that is 3000 bytes in size
 * // file4.txt does not exist
 *
 * const fileMap = {
 *     f1: 'file1.txt',
 *     f2: 'file2.txt',
 *     f3: 'file3.txt'
 * };
 *
 * const withMissingFileMap = {
 *     f1: 'file1.txt',
 *     f2: 'file2.txt',
 *     f3: 'file4.txt'
 * };
 *
 * // asynchronous function that returns the file size in bytes
 * function getFileSizeInBytes(file, key, callback) {
 *     fs.stat(file, function(err, stat) {
 *         if (err) {
 *             return callback(err);
 *         }
 *         callback(null, stat.size);
 *     });
 * }
 *
 * // Using callbacks
 * async.mapValues(fileMap, getFileSizeInBytes, function(err, result) {
 *     if (err) {
 *         console.log(err);
 *     } else {
 *         console.log(result);
 *         // result is now a map of file size in bytes for each file, e.g.
 *         // {
 *         //     f1: 1000,
 *         //     f2: 2000,
 *         //     f3: 3000
 *         // }
 *     }
 * });
 *
 * // Error handling
 * async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) {
 *     if (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *     } else {
 *         console.log(result);
 *     }
 * });
 *
 * // Using Promises
 * async.mapValues(fileMap, getFileSizeInBytes)
 * .then( result => {
 *     console.log(result);
 *     // result is now a map of file size in bytes for each file, e.g.
 *     // {
 *     //     f1: 1000,
 *     //     f2: 2000,
 *     //     f3: 3000
 *     // }
 * }).catch (err => {
 *     console.log(err);
 * });
 *
 * // Error Handling
 * async.mapValues(withMissingFileMap, getFileSizeInBytes)
 * .then( result => {
 *     console.log(result);
 * }).catch (err => {
 *     console.log(err);
 *     // [ Error: ENOENT: no such file or directory ]
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let result = await async.mapValues(fileMap, getFileSizeInBytes);
 *         console.log(result);
 *         // result is now a map of file size in bytes for each file, e.g.
 *         // {
 *         //     f1: 1000,
 *         //     f2: 2000,
 *         //     f3: 3000
 *         // }
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * // Error Handling
 * async () => {
 *     try {
 *         let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes);
 *         console.log(result);
 *     }
 *     catch (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *     }
 * }
 *
 */
function mapValues(obj, iteratee, callback) {
    return mapValuesLimit$1(obj, Infinity, iteratee, callback)
}

/**
 * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.
 *
 * @name mapValuesSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.mapValues]{@link module:Collections.mapValues}
 * @category Collection
 * @param {Object} obj - A collection to iterate over.
 * @param {AsyncFunction} iteratee - A function to apply to each value and key
 * in `coll`.
 * The iteratee should complete with the transformed value as its result.
 * Invoked with (value, key, callback).
 * @param {Function} [callback] - A callback which is called when all `iteratee`
 * functions have finished, or an error occurs. `result` is a new object consisting
 * of each key from `obj`, with each transformed value on the right-hand side.
 * Invoked with (err, result).
 * @returns {Promise} a promise, if no callback is passed
 */
function mapValuesSeries(obj, iteratee, callback) {
    return mapValuesLimit$1(obj, 1, iteratee, callback)
}

/**
 * Caches the results of an async function. When creating a hash to store
 * function results against, the callback is omitted from the hash and an
 * optional hash function can be used.
 *
 * **Note: if the async function errs, the result will not be cached and
 * subsequent calls will call the wrapped function.**
 *
 * If no hash function is specified, the first argument is used as a hash key,
 * which may work reasonably if it is a string or a data type that converts to a
 * distinct string. Note that objects and arrays will not behave reasonably.
 * Neither will cases where the other arguments are significant. In such cases,
 * specify your own hash function.
 *
 * The cache of results is exposed as the `memo` property of the function
 * returned by `memoize`.
 *
 * @name memoize
 * @static
 * @memberOf module:Utils
 * @method
 * @category Util
 * @param {AsyncFunction} fn - The async function to proxy and cache results from.
 * @param {Function} hasher - An optional function for generating a custom hash
 * for storing results. It has all the arguments applied to it apart from the
 * callback, and must be synchronous.
 * @returns {AsyncFunction} a memoized version of `fn`
 * @example
 *
 * var slow_fn = function(name, callback) {
 *     // do something
 *     callback(null, result);
 * };
 * var fn = async.memoize(slow_fn);
 *
 * // fn can now be used as if it were slow_fn
 * fn('some name', function() {
 *     // callback
 * });
 */
function memoize(fn, hasher = v => v) {
    var memo = Object.create(null);
    var queues = Object.create(null);
    var _fn = wrapAsync(fn);
    var memoized = initialParams((args, callback) => {
        var key = hasher(...args);
        if (key in memo) {
            setImmediate$1(() => callback(null, ...memo[key]));
        } else if (key in queues) {
            queues[key].push(callback);
        } else {
            queues[key] = [callback];
            _fn(...args, (err, ...resultArgs) => {
                // #1465 don't memoize if an error occurred
                if (!err) {
                    memo[key] = resultArgs;
                }
                var q = queues[key];
                delete queues[key];
                for (var i = 0, l = q.length; i < l; i++) {
                    q[i](err, ...resultArgs);
                }
            });
        }
    });
    memoized.memo = memo;
    memoized.unmemoized = fn;
    return memoized;
}

/* istanbul ignore file */

/**
 * Calls `callback` on a later loop around the event loop. In Node.js this just
 * calls `process.nextTick`.  In the browser it will use `setImmediate` if
 * available, otherwise `setTimeout(callback, 0)`, which means other higher
 * priority events may precede the execution of `callback`.
 *
 * This is used internally for browser-compatibility purposes.
 *
 * @name nextTick
 * @static
 * @memberOf module:Utils
 * @method
 * @see [async.setImmediate]{@link module:Utils.setImmediate}
 * @category Util
 * @param {Function} callback - The function to call on a later loop around
 * the event loop. Invoked with (args...).
 * @param {...*} args... - any number of additional arguments to pass to the
 * callback on the next tick.
 * @example
 *
 * var call_order = [];
 * async.nextTick(function() {
 *     call_order.push('two');
 *     // call_order now equals ['one','two']
 * });
 * call_order.push('one');
 *
 * async.setImmediate(function (a, b, c) {
 *     // a, b, and c equal 1, 2, and 3
 * }, 1, 2, 3);
 */
var _defer;

if (hasNextTick) {
    _defer = process.nextTick;
} else if (hasSetImmediate) {
    _defer = setImmediate;
} else {
    _defer = fallback;
}

var nextTick = wrap(_defer);

var _parallel = awaitify((eachfn, tasks, callback) => {
    var results = isArrayLike(tasks) ? [] : {};

    eachfn(tasks, (task, key, taskCb) => {
        wrapAsync(task)((err, ...result) => {
            if (result.length < 2) {
                [result] = result;
            }
            results[key] = result;
            taskCb(err);
        });
    }, err => callback(err, results));
}, 3);

/**
 * Run the `tasks` collection of functions in parallel, without waiting until
 * the previous function has completed. If any of the functions pass an error to
 * its callback, the main `callback` is immediately called with the value of the
 * error. Once the `tasks` have completed, the results are passed to the final
 * `callback` as an array.
 *
 * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about
 * parallel execution of code.  If your tasks do not use any timers or perform
 * any I/O, they will actually be executed in series.  Any synchronous setup
 * sections for each task will happen one after the other.  JavaScript remains
 * single-threaded.
 *
 * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the
 * execution of other tasks when a task fails.
 *
 * It is also possible to use an object instead of an array. Each property will
 * be run as a function and the results will be passed to the final `callback`
 * as an object instead of an array. This can be a more readable way of handling
 * results from {@link async.parallel}.
 *
 * @name parallel
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of
 * [async functions]{@link AsyncFunction} to run.
 * Each async function can complete with any number of optional `result` values.
 * @param {Function} [callback] - An optional callback to run once all the
 * functions have completed successfully. This function gets a results array
 * (or object) containing all the result arguments passed to the task callbacks.
 * Invoked with (err, results).
 * @returns {Promise} a promise, if a callback is not passed
 *
 * @example
 *
 * //Using Callbacks
 * async.parallel([
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'one');
 *         }, 200);
 *     },
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'two');
 *         }, 100);
 *     }
 * ], function(err, results) {
 *     console.log(results);
 *     // results is equal to ['one','two'] even though
 *     // the second function had a shorter timeout.
 * });
 *
 * // an example using an object instead of an array
 * async.parallel({
 *     one: function(callback) {
 *         setTimeout(function() {
 *             callback(null, 1);
 *         }, 200);
 *     },
 *     two: function(callback) {
 *         setTimeout(function() {
 *             callback(null, 2);
 *         }, 100);
 *     }
 * }, function(err, results) {
 *     console.log(results);
 *     // results is equal to: { one: 1, two: 2 }
 * });
 *
 * //Using Promises
 * async.parallel([
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'one');
 *         }, 200);
 *     },
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'two');
 *         }, 100);
 *     }
 * ]).then(results => {
 *     console.log(results);
 *     // results is equal to ['one','two'] even though
 *     // the second function had a shorter timeout.
 * }).catch(err => {
 *     console.log(err);
 * });
 *
 * // an example using an object instead of an array
 * async.parallel({
 *     one: function(callback) {
 *         setTimeout(function() {
 *             callback(null, 1);
 *         }, 200);
 *     },
 *     two: function(callback) {
 *         setTimeout(function() {
 *             callback(null, 2);
 *         }, 100);
 *     }
 * }).then(results => {
 *     console.log(results);
 *     // results is equal to: { one: 1, two: 2 }
 * }).catch(err => {
 *     console.log(err);
 * });
 *
 * //Using async/await
 * async () => {
 *     try {
 *         let results = await async.parallel([
 *             function(callback) {
 *                 setTimeout(function() {
 *                     callback(null, 'one');
 *                 }, 200);
 *             },
 *             function(callback) {
 *                 setTimeout(function() {
 *                     callback(null, 'two');
 *                 }, 100);
 *             }
 *         ]);
 *         console.log(results);
 *         // results is equal to ['one','two'] even though
 *         // the second function had a shorter timeout.
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * // an example using an object instead of an array
 * async () => {
 *     try {
 *         let results = await async.parallel({
 *             one: function(callback) {
 *                 setTimeout(function() {
 *                     callback(null, 1);
 *                 }, 200);
 *             },
 *            two: function(callback) {
 *                 setTimeout(function() {
 *                     callback(null, 2);
 *                 }, 100);
 *            }
 *         });
 *         console.log(results);
 *         // results is equal to: { one: 1, two: 2 }
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function parallel(tasks, callback) {
    return _parallel(eachOf$1, tasks, callback);
}

/**
 * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a
 * time.
 *
 * @name parallelLimit
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.parallel]{@link module:ControlFlow.parallel}
 * @category Control Flow
 * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of
 * [async functions]{@link AsyncFunction} to run.
 * Each async function can complete with any number of optional `result` values.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {Function} [callback] - An optional callback to run once all the
 * functions have completed successfully. This function gets a results array
 * (or object) containing all the result arguments passed to the task callbacks.
 * Invoked with (err, results).
 * @returns {Promise} a promise, if a callback is not passed
 */
function parallelLimit(tasks, limit, callback) {
    return _parallel(eachOfLimit$2(limit), tasks, callback);
}

/**
 * A queue of tasks for the worker function to complete.
 * @typedef {Iterable} QueueObject
 * @memberOf module:ControlFlow
 * @property {Function} length - a function returning the number of items
 * waiting to be processed. Invoke with `queue.length()`.
 * @property {boolean} started - a boolean indicating whether or not any
 * items have been pushed and processed by the queue.
 * @property {Function} running - a function returning the number of items
 * currently being processed. Invoke with `queue.running()`.
 * @property {Function} workersList - a function returning the array of items
 * currently being processed. Invoke with `queue.workersList()`.
 * @property {Function} idle - a function returning false if there are items
 * waiting or being processed, or true if not. Invoke with `queue.idle()`.
 * @property {number} concurrency - an integer for determining how many `worker`
 * functions should be run in parallel. This property can be changed after a
 * `queue` is created to alter the concurrency on-the-fly.
 * @property {number} payload - an integer that specifies how many items are
 * passed to the worker function at a time. only applies if this is a
 * [cargo]{@link module:ControlFlow.cargo} object
 * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback`
 * once the `worker` has finished processing the task. Instead of a single task,
 * a `tasks` array can be submitted. The respective callback is used for every
 * task in the list. Invoke with `queue.push(task, [callback])`,
 * @property {AsyncFunction} unshift - add a new task to the front of the `queue`.
 * Invoke with `queue.unshift(task, [callback])`.
 * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns
 * a promise that rejects if an error occurs.
 * @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns
 * a promise that rejects if an error occurs.
 * @property {Function} remove - remove items from the queue that match a test
 * function.  The test function will be passed an object with a `data` property,
 * and a `priority` property, if this is a
 * [priorityQueue]{@link module:ControlFlow.priorityQueue} object.
 * Invoked with `queue.remove(testFn)`, where `testFn` is of the form
 * `function ({data, priority}) {}` and returns a Boolean.
 * @property {Function} saturated - a function that sets a callback that is
 * called when the number of running workers hits the `concurrency` limit, and
 * further tasks will be queued.  If the callback is omitted, `q.saturated()`
 * returns a promise for the next occurrence.
 * @property {Function} unsaturated - a function that sets a callback that is
 * called when the number of running workers is less than the `concurrency` &
 * `buffer` limits, and further tasks will not be queued. If the callback is
 * omitted, `q.unsaturated()` returns a promise for the next occurrence.
 * @property {number} buffer - A minimum threshold buffer in order to say that
 * the `queue` is `unsaturated`.
 * @property {Function} empty - a function that sets a callback that is called
 * when the last item from the `queue` is given to a `worker`. If the callback
 * is omitted, `q.empty()` returns a promise for the next occurrence.
 * @property {Function} drain - a function that sets a callback that is called
 * when the last item from the `queue` has returned from the `worker`. If the
 * callback is omitted, `q.drain()` returns a promise for the next occurrence.
 * @property {Function} error - a function that sets a callback that is called
 * when a task errors. Has the signature `function(error, task)`. If the
 * callback is omitted, `error()` returns a promise that rejects on the next
 * error.
 * @property {boolean} paused - a boolean for determining whether the queue is
 * in a paused state.
 * @property {Function} pause - a function that pauses the processing of tasks
 * until `resume()` is called. Invoke with `queue.pause()`.
 * @property {Function} resume - a function that resumes the processing of
 * queued tasks when the queue is paused. Invoke with `queue.resume()`.
 * @property {Function} kill - a function that removes the `drain` callback and
 * empties remaining tasks from the queue forcing it to go idle. No more tasks
 * should be pushed to the queue after calling this function. Invoke with `queue.kill()`.
 *
 * @example
 * const q = async.queue(worker, 2)
 * q.push(item1)
 * q.push(item2)
 * q.push(item3)
 * // queues are iterable, spread into an array to inspect
 * const items = [...q] // [item1, item2, item3]
 * // or use for of
 * for (let item of q) {
 *     console.log(item)
 * }
 *
 * q.drain(() => {
 *     console.log('all done')
 * })
 * // or
 * await q.drain()
 */

/**
 * Creates a `queue` object with the specified `concurrency`. Tasks added to the
 * `queue` are processed in parallel (up to the `concurrency` limit). If all
 * `worker`s are in progress, the task is queued until one becomes available.
 * Once a `worker` completes a `task`, that `task`'s callback is called.
 *
 * @name queue
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {AsyncFunction} worker - An async function for processing a queued task.
 * If you want to handle errors from an individual task, pass a callback to
 * `q.push()`. Invoked with (task, callback).
 * @param {number} [concurrency=1] - An `integer` for determining how many
 * `worker` functions should be run in parallel.  If omitted, the concurrency
 * defaults to `1`.  If the concurrency is `0`, an error is thrown.
 * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be
 * attached as certain properties to listen for specific events during the
 * lifecycle of the queue.
 * @example
 *
 * // create a queue object with concurrency 2
 * var q = async.queue(function(task, callback) {
 *     console.log('hello ' + task.name);
 *     callback();
 * }, 2);
 *
 * // assign a callback
 * q.drain(function() {
 *     console.log('all items have been processed');
 * });
 * // or await the end
 * await q.drain()
 *
 * // assign an error callback
 * q.error(function(err, task) {
 *     console.error('task experienced an error');
 * });
 *
 * // add some items to the queue
 * q.push({name: 'foo'}, function(err) {
 *     console.log('finished processing foo');
 * });
 * // callback is optional
 * q.push({name: 'bar'});
 *
 * // add some items to the queue (batch-wise)
 * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
 *     console.log('finished processing item');
 * });
 *
 * // add some items to the front of the queue
 * q.unshift({name: 'bar'}, function (err) {
 *     console.log('finished processing bar');
 * });
 */
function queue (worker, concurrency) {
    var _worker = wrapAsync(worker);
    return queue$1((items, cb) => {
        _worker(items[0], cb);
    }, concurrency, 1);
}

// Binary min-heap implementation used for priority queue.
// Implementation is stable, i.e. push time is considered for equal priorities
class Heap {
    constructor() {
        this.heap = [];
        this.pushCount = Number.MIN_SAFE_INTEGER;
    }

    get length() {
        return this.heap.length;
    }

    empty () {
        this.heap = [];
        return this;
    }

    percUp(index) {
        let p;

        while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) {
            let t = this.heap[index];
            this.heap[index] = this.heap[p];
            this.heap[p] = t;

            index = p;
        }
    }

    percDown(index) {
        let l;

        while ((l=leftChi(index)) < this.heap.length) {
            if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) {
                l = l+1;
            }

            if (smaller(this.heap[index], this.heap[l])) {
                break;
            }

            let t = this.heap[index];
            this.heap[index] = this.heap[l];
            this.heap[l] = t;

            index = l;
        }
    }

    push(node) {
        node.pushCount = ++this.pushCount;
        this.heap.push(node);
        this.percUp(this.heap.length-1);
    }

    unshift(node) {
        return this.heap.push(node);
    }

    shift() {
        let [top] = this.heap;

        this.heap[0] = this.heap[this.heap.length-1];
        this.heap.pop();
        this.percDown(0);

        return top;
    }

    toArray() {
        return [...this];
    }

    *[Symbol.iterator] () {
        for (let i = 0; i < this.heap.length; i++) {
            yield this.heap[i].data;
        }
    }

    remove (testFn) {
        let j = 0;
        for (let i = 0; i < this.heap.length; i++) {
            if (!testFn(this.heap[i])) {
                this.heap[j] = this.heap[i];
                j++;
            }
        }

        this.heap.splice(j);

        for (let i = parent(this.heap.length-1); i >= 0; i--) {
            this.percDown(i);
        }

        return this;
    }
}

function leftChi(i) {
    return (i<<1)+1;
}

function parent(i) {
    return ((i+1)>>1)-1;
}

function smaller(x, y) {
    if (x.priority !== y.priority) {
        return x.priority < y.priority;
    }
    else {
        return x.pushCount < y.pushCount;
    }
}

/**
 * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and
 * completed in ascending priority order.
 *
 * @name priorityQueue
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.queue]{@link module:ControlFlow.queue}
 * @category Control Flow
 * @param {AsyncFunction} worker - An async function for processing a queued task.
 * If you want to handle errors from an individual task, pass a callback to
 * `q.push()`.
 * Invoked with (task, callback).
 * @param {number} concurrency - An `integer` for determining how many `worker`
 * functions should be run in parallel.  If omitted, the concurrency defaults to
 * `1`.  If the concurrency is `0`, an error is thrown.
 * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are three
 * differences between `queue` and `priorityQueue` objects:
 * * `push(task, priority, [callback])` - `priority` should be a number. If an
 *   array of `tasks` is given, all tasks will be assigned the same priority.
 * * `pushAsync(task, priority, [callback])` - the same as `priorityQueue.push`,
 *   except this returns a promise that rejects if an error occurs.
 * * The `unshift` and `unshiftAsync` methods were removed.
 */
function priorityQueue(worker, concurrency) {
    // Start with a normal queue
    var q = queue(worker, concurrency);

    var {
        push,
        pushAsync
    } = q;

    q._tasks = new Heap();
    q._createTaskItem = ({data, priority}, callback) => {
        return {
            data,
            priority,
            callback
        };
    };

    function createDataItems(tasks, priority) {
        if (!Array.isArray(tasks)) {
            return {data: tasks, priority};
        }
        return tasks.map(data => { return {data, priority}; });
    }

    // Override push to accept second parameter representing priority
    q.push = function(data, priority = 0, callback) {
        return push(createDataItems(data, priority), callback);
    };

    q.pushAsync = function(data, priority = 0, callback) {
        return pushAsync(createDataItems(data, priority), callback);
    };

    // Remove unshift functions
    delete q.unshift;
    delete q.unshiftAsync;

    return q;
}

/**
 * Runs the `tasks` array of functions in parallel, without waiting until the
 * previous function has completed. Once any of the `tasks` complete or pass an
 * error to its callback, the main `callback` is immediately called. It's
 * equivalent to `Promise.race()`.
 *
 * @name race
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}
 * to run. Each function can complete with an optional `result` value.
 * @param {Function} callback - A callback to run once any of the functions have
 * completed. This function gets an error or result from the first function that
 * completed. Invoked with (err, result).
 * @returns {Promise} a promise, if a callback is omitted
 * @example
 *
 * async.race([
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'one');
 *         }, 200);
 *     },
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'two');
 *         }, 100);
 *     }
 * ],
 * // main callback
 * function(err, result) {
 *     // the result will be equal to 'two' as it finishes earlier
 * });
 */
function race(tasks, callback) {
    callback = once$1(callback);
    if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
    if (!tasks.length) return callback();
    for (var i = 0, l = tasks.length; i < l; i++) {
        wrapAsync(tasks[i])(callback);
    }
}

var race$1 = awaitify(race, 2);

/**
 * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.
 *
 * @name reduceRight
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.reduce]{@link module:Collections.reduce}
 * @alias foldr
 * @category Collection
 * @param {Array} array - A collection to iterate over.
 * @param {*} memo - The initial state of the reduction.
 * @param {AsyncFunction} iteratee - A function applied to each item in the
 * array to produce the next step in the reduction.
 * The `iteratee` should complete with the next state of the reduction.
 * If the iteratee completes with an error, the reduction is stopped and the
 * main `callback` is immediately called with the error.
 * Invoked with (memo, item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Result is the reduced value. Invoked with
 * (err, result).
 * @returns {Promise} a promise, if no callback is passed
 */
function reduceRight (array, memo, iteratee, callback) {
    var reversed = [...array].reverse();
    return reduce$1(reversed, memo, iteratee, callback);
}

/**
 * Wraps the async function in another function that always completes with a
 * result object, even when it errors.
 *
 * The result object has either the property `error` or `value`.
 *
 * @name reflect
 * @static
 * @memberOf module:Utils
 * @method
 * @category Util
 * @param {AsyncFunction} fn - The async function you want to wrap
 * @returns {Function} - A function that always passes null to it's callback as
 * the error. The second argument to the callback will be an `object` with
 * either an `error` or a `value` property.
 * @example
 *
 * async.parallel([
 *     async.reflect(function(callback) {
 *         // do some stuff ...
 *         callback(null, 'one');
 *     }),
 *     async.reflect(function(callback) {
 *         // do some more stuff but error ...
 *         callback('bad stuff happened');
 *     }),
 *     async.reflect(function(callback) {
 *         // do some more stuff ...
 *         callback(null, 'two');
 *     })
 * ],
 * // optional callback
 * function(err, results) {
 *     // values
 *     // results[0].value = 'one'
 *     // results[1].error = 'bad stuff happened'
 *     // results[2].value = 'two'
 * });
 */
function reflect(fn) {
    var _fn = wrapAsync(fn);
    return initialParams(function reflectOn(args, reflectCallback) {
        args.push((error, ...cbArgs) => {
            let retVal = {};
            if (error) {
                retVal.error = error;
            }
            if (cbArgs.length > 0){
                var value = cbArgs;
                if (cbArgs.length <= 1) {
                    [value] = cbArgs;
                }
                retVal.value = value;
            }
            reflectCallback(null, retVal);
        });

        return _fn.apply(this, args);
    });
}

/**
 * A helper function that wraps an array or an object of functions with `reflect`.
 *
 * @name reflectAll
 * @static
 * @memberOf module:Utils
 * @method
 * @see [async.reflect]{@link module:Utils.reflect}
 * @category Util
 * @param {Array|Object|Iterable} tasks - The collection of
 * [async functions]{@link AsyncFunction} to wrap in `async.reflect`.
 * @returns {Array} Returns an array of async functions, each wrapped in
 * `async.reflect`
 * @example
 *
 * let tasks = [
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'one');
 *         }, 200);
 *     },
 *     function(callback) {
 *         // do some more stuff but error ...
 *         callback(new Error('bad stuff happened'));
 *     },
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'two');
 *         }, 100);
 *     }
 * ];
 *
 * async.parallel(async.reflectAll(tasks),
 * // optional callback
 * function(err, results) {
 *     // values
 *     // results[0].value = 'one'
 *     // results[1].error = Error('bad stuff happened')
 *     // results[2].value = 'two'
 * });
 *
 * // an example using an object instead of an array
 * let tasks = {
 *     one: function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'one');
 *         }, 200);
 *     },
 *     two: function(callback) {
 *         callback('two');
 *     },
 *     three: function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'three');
 *         }, 100);
 *     }
 * };
 *
 * async.parallel(async.reflectAll(tasks),
 * // optional callback
 * function(err, results) {
 *     // values
 *     // results.one.value = 'one'
 *     // results.two.error = 'two'
 *     // results.three.value = 'three'
 * });
 */
function reflectAll(tasks) {
    var results;
    if (Array.isArray(tasks)) {
        results = tasks.map(reflect);
    } else {
        results = {};
        Object.keys(tasks).forEach(key => {
            results[key] = reflect.call(this, tasks[key]);
        });
    }
    return results;
}

function reject$2(eachfn, arr, _iteratee, callback) {
    const iteratee = wrapAsync(_iteratee);
    return _filter(eachfn, arr, (value, cb) => {
        iteratee(value, (err, v) => {
            cb(err, !v);
        });
    }, callback);
}

/**
 * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.
 *
 * @name reject
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.filter]{@link module:Collections.filter}
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {Function} iteratee - An async truth test to apply to each item in
 * `coll`.
 * The should complete with a boolean value as its `result`.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback is passed
 * @example
 *
 * // dir1 is a directory that contains file1.txt, file2.txt
 * // dir2 is a directory that contains file3.txt, file4.txt
 * // dir3 is a directory that contains file5.txt
 *
 * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];
 *
 * // asynchronous function that checks if a file exists
 * function fileExists(file, callback) {
 *    fs.access(file, fs.constants.F_OK, (err) => {
 *        callback(null, !err);
 *    });
 * }
 *
 * // Using callbacks
 * async.reject(fileList, fileExists, function(err, results) {
 *    // [ 'dir3/file6.txt' ]
 *    // results now equals an array of the non-existing files
 * });
 *
 * // Using Promises
 * async.reject(fileList, fileExists)
 * .then( results => {
 *     console.log(results);
 *     // [ 'dir3/file6.txt' ]
 *     // results now equals an array of the non-existing files
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let results = await async.reject(fileList, fileExists);
 *         console.log(results);
 *         // [ 'dir3/file6.txt' ]
 *         // results now equals an array of the non-existing files
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function reject (coll, iteratee, callback) {
    return reject$2(eachOf$1, coll, iteratee, callback)
}
var reject$1 = awaitify(reject, 3);

/**
 * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a
 * time.
 *
 * @name rejectLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.reject]{@link module:Collections.reject}
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {Function} iteratee - An async truth test to apply to each item in
 * `coll`.
 * The should complete with a boolean value as its `result`.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback is passed
 */
function rejectLimit (coll, limit, iteratee, callback) {
    return reject$2(eachOfLimit$2(limit), coll, iteratee, callback)
}
var rejectLimit$1 = awaitify(rejectLimit, 4);

/**
 * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.
 *
 * @name rejectSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.reject]{@link module:Collections.reject}
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {Function} iteratee - An async truth test to apply to each item in
 * `coll`.
 * The should complete with a boolean value as its `result`.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback is passed
 */
function rejectSeries (coll, iteratee, callback) {
    return reject$2(eachOfSeries$1, coll, iteratee, callback)
}
var rejectSeries$1 = awaitify(rejectSeries, 3);

function constant(value) {
    return function () {
        return value;
    }
}

/**
 * Attempts to get a successful response from `task` no more than `times` times
 * before returning an error. If the task is successful, the `callback` will be
 * passed the result of the successful task. If all attempts fail, the callback
 * will be passed the error and result (if any) of the final attempt.
 *
 * @name retry
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @see [async.retryable]{@link module:ControlFlow.retryable}
 * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
 * object with `times` and `interval` or a number.
 * * `times` - The number of attempts to make before giving up.  The default
 *   is `5`.
 * * `interval` - The time to wait between retries, in milliseconds.  The
 *   default is `0`. The interval may also be specified as a function of the
 *   retry count (see example).
 * * `errorFilter` - An optional synchronous function that is invoked on
 *   erroneous result. If it returns `true` the retry attempts will continue;
 *   if the function returns `false` the retry flow is aborted with the current
 *   attempt's error and result being returned to the final callback.
 *   Invoked with (err).
 * * If `opts` is a number, the number specifies the number of times to retry,
 *   with the default interval of `0`.
 * @param {AsyncFunction} task - An async function to retry.
 * Invoked with (callback).
 * @param {Function} [callback] - An optional callback which is called when the
 * task has succeeded, or after the final failed attempt. It receives the `err`
 * and `result` arguments of the last attempt at completing the `task`. Invoked
 * with (err, results).
 * @returns {Promise} a promise if no callback provided
 *
 * @example
 *
 * // The `retry` function can be used as a stand-alone control flow by passing
 * // a callback, as shown below:
 *
 * // try calling apiMethod 3 times
 * async.retry(3, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod 3 times, waiting 200 ms between each retry
 * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod 10 times with exponential backoff
 * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)
 * async.retry({
 *   times: 10,
 *   interval: function(retryCount) {
 *     return 50 * Math.pow(2, retryCount);
 *   }
 * }, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod the default 5 times no delay between each retry
 * async.retry(apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // try calling apiMethod only when error condition satisfies, all other
 * // errors will abort the retry control flow and return to final callback
 * async.retry({
 *   errorFilter: function(err) {
 *     return err.message === 'Temporary error'; // only retry on a specific error
 *   }
 * }, apiMethod, function(err, result) {
 *     // do something with the result
 * });
 *
 * // to retry individual methods that are not as reliable within other
 * // control flow functions, use the `retryable` wrapper:
 * async.auto({
 *     users: api.getUsers.bind(api),
 *     payments: async.retryable(3, api.getPayments.bind(api))
 * }, function(err, results) {
 *     // do something with the results
 * });
 *
 */
const DEFAULT_TIMES = 5;
const DEFAULT_INTERVAL = 0;

function retry(opts, task, callback) {
    var options = {
        times: DEFAULT_TIMES,
        intervalFunc: constant(DEFAULT_INTERVAL)
    };

    if (arguments.length < 3 && typeof opts === 'function') {
        callback = task || promiseCallback();
        task = opts;
    } else {
        parseTimes(options, opts);
        callback = callback || promiseCallback();
    }

    if (typeof task !== 'function') {
        throw new Error("Invalid arguments for async.retry");
    }

    var _task = wrapAsync(task);

    var attempt = 1;
    function retryAttempt() {
        _task((err, ...args) => {
            if (err === false) return
            if (err && attempt++ < options.times &&
                (typeof options.errorFilter != 'function' ||
                    options.errorFilter(err))) {
                setTimeout(retryAttempt, options.intervalFunc(attempt - 1));
            } else {
                callback(err, ...args);
            }
        });
    }

    retryAttempt();
    return callback[PROMISE_SYMBOL]
}

function parseTimes(acc, t) {
    if (typeof t === 'object') {
        acc.times = +t.times || DEFAULT_TIMES;

        acc.intervalFunc = typeof t.interval === 'function' ?
            t.interval :
            constant(+t.interval || DEFAULT_INTERVAL);

        acc.errorFilter = t.errorFilter;
    } else if (typeof t === 'number' || typeof t === 'string') {
        acc.times = +t || DEFAULT_TIMES;
    } else {
        throw new Error("Invalid arguments for async.retry");
    }
}

/**
 * A close relative of [`retry`]{@link module:ControlFlow.retry}.  This method
 * wraps a task and makes it retryable, rather than immediately calling it
 * with retries.
 *
 * @name retryable
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.retry]{@link module:ControlFlow.retry}
 * @category Control Flow
 * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional
 * options, exactly the same as from `retry`, except for a `opts.arity` that
 * is the arity of the `task` function, defaulting to `task.length`
 * @param {AsyncFunction} task - the asynchronous function to wrap.
 * This function will be passed any arguments passed to the returned wrapper.
 * Invoked with (...args, callback).
 * @returns {AsyncFunction} The wrapped function, which when invoked, will
 * retry on an error, based on the parameters specified in `opts`.
 * This function will accept the same parameters as `task`.
 * @example
 *
 * async.auto({
 *     dep1: async.retryable(3, getFromFlakyService),
 *     process: ["dep1", async.retryable(3, function (results, cb) {
 *         maybeProcessData(results.dep1, cb);
 *     })]
 * }, callback);
 */
function retryable (opts, task) {
    if (!task) {
        task = opts;
        opts = null;
    }
    let arity = (opts && opts.arity) || task.length;
    if (isAsync(task)) {
        arity += 1;
    }
    var _task = wrapAsync(task);
    return initialParams((args, callback) => {
        if (args.length < arity - 1 || callback == null) {
            args.push(callback);
            callback = promiseCallback();
        }
        function taskFn(cb) {
            _task(...args, cb);
        }

        if (opts) retry(opts, taskFn, callback);
        else retry(taskFn, callback);

        return callback[PROMISE_SYMBOL]
    });
}

/**
 * Run the functions in the `tasks` collection in series, each one running once
 * the previous function has completed. If any functions in the series pass an
 * error to its callback, no more functions are run, and `callback` is
 * immediately called with the value of the error. Otherwise, `callback`
 * receives an array of results when `tasks` have completed.
 *
 * It is also possible to use an object instead of an array. Each property will
 * be run as a function, and the results will be passed to the final `callback`
 * as an object instead of an array. This can be a more readable way of handling
 *  results from {@link async.series}.
 *
 * **Note** that while many implementations preserve the order of object
 * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)
 * explicitly states that
 *
 * > The mechanics and order of enumerating the properties is not specified.
 *
 * So if you rely on the order in which your series of functions are executed,
 * and want this to work on all platforms, consider using an array.
 *
 * @name series
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing
 * [async functions]{@link AsyncFunction} to run in series.
 * Each function can complete with any number of optional `result` values.
 * @param {Function} [callback] - An optional callback to run once all the
 * functions have completed. This function gets a results array (or object)
 * containing all the result arguments passed to the `task` callbacks. Invoked
 * with (err, result).
 * @return {Promise} a promise, if no callback is passed
 * @example
 *
 * //Using Callbacks
 * async.series([
 *     function(callback) {
 *         setTimeout(function() {
 *             // do some async task
 *             callback(null, 'one');
 *         }, 200);
 *     },
 *     function(callback) {
 *         setTimeout(function() {
 *             // then do another async task
 *             callback(null, 'two');
 *         }, 100);
 *     }
 * ], function(err, results) {
 *     console.log(results);
 *     // results is equal to ['one','two']
 * });
 *
 * // an example using objects instead of arrays
 * async.series({
 *     one: function(callback) {
 *         setTimeout(function() {
 *             // do some async task
 *             callback(null, 1);
 *         }, 200);
 *     },
 *     two: function(callback) {
 *         setTimeout(function() {
 *             // then do another async task
 *             callback(null, 2);
 *         }, 100);
 *     }
 * }, function(err, results) {
 *     console.log(results);
 *     // results is equal to: { one: 1, two: 2 }
 * });
 *
 * //Using Promises
 * async.series([
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'one');
 *         }, 200);
 *     },
 *     function(callback) {
 *         setTimeout(function() {
 *             callback(null, 'two');
 *         }, 100);
 *     }
 * ]).then(results => {
 *     console.log(results);
 *     // results is equal to ['one','two']
 * }).catch(err => {
 *     console.log(err);
 * });
 *
 * // an example using an object instead of an array
 * async.series({
 *     one: function(callback) {
 *         setTimeout(function() {
 *             // do some async task
 *             callback(null, 1);
 *         }, 200);
 *     },
 *     two: function(callback) {
 *         setTimeout(function() {
 *             // then do another async task
 *             callback(null, 2);
 *         }, 100);
 *     }
 * }).then(results => {
 *     console.log(results);
 *     // results is equal to: { one: 1, two: 2 }
 * }).catch(err => {
 *     console.log(err);
 * });
 *
 * //Using async/await
 * async () => {
 *     try {
 *         let results = await async.series([
 *             function(callback) {
 *                 setTimeout(function() {
 *                     // do some async task
 *                     callback(null, 'one');
 *                 }, 200);
 *             },
 *             function(callback) {
 *                 setTimeout(function() {
 *                     // then do another async task
 *                     callback(null, 'two');
 *                 }, 100);
 *             }
 *         ]);
 *         console.log(results);
 *         // results is equal to ['one','two']
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * // an example using an object instead of an array
 * async () => {
 *     try {
 *         let results = await async.parallel({
 *             one: function(callback) {
 *                 setTimeout(function() {
 *                     // do some async task
 *                     callback(null, 1);
 *                 }, 200);
 *             },
 *            two: function(callback) {
 *                 setTimeout(function() {
 *                     // then do another async task
 *                     callback(null, 2);
 *                 }, 100);
 *            }
 *         });
 *         console.log(results);
 *         // results is equal to: { one: 1, two: 2 }
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function series(tasks, callback) {
    return _parallel(eachOfSeries$1, tasks, callback);
}

/**
 * Returns `true` if at least one element in the `coll` satisfies an async test.
 * If any iteratee call returns `true`, the main `callback` is immediately
 * called.
 *
 * @name some
 * @static
 * @memberOf module:Collections
 * @method
 * @alias any
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
 * in the collections in parallel.
 * The iteratee should complete with a boolean `result` value.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called as soon as any
 * iteratee returns `true`, or after all the iteratee functions have finished.
 * Result will be either `true` or `false` depending on the values of the async
 * tests. Invoked with (err, result).
 * @returns {Promise} a promise, if no callback provided
 * @example
 *
 * // dir1 is a directory that contains file1.txt, file2.txt
 * // dir2 is a directory that contains file3.txt, file4.txt
 * // dir3 is a directory that contains file5.txt
 * // dir4 does not exist
 *
 * // asynchronous function that checks if a file exists
 * function fileExists(file, callback) {
 *    fs.access(file, fs.constants.F_OK, (err) => {
 *        callback(null, !err);
 *    });
 * }
 *
 * // Using callbacks
 * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists,
 *    function(err, result) {
 *        console.log(result);
 *        // true
 *        // result is true since some file in the list exists
 *    }
 *);
 *
 * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists,
 *    function(err, result) {
 *        console.log(result);
 *        // false
 *        // result is false since none of the files exists
 *    }
 *);
 *
 * // Using Promises
 * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists)
 * .then( result => {
 *     console.log(result);
 *     // true
 *     // result is true since some file in the list exists
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists)
 * .then( result => {
 *     console.log(result);
 *     // false
 *     // result is false since none of the files exists
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists);
 *         console.log(result);
 *         // true
 *         // result is true since some file in the list exists
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 * async () => {
 *     try {
 *         let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists);
 *         console.log(result);
 *         // false
 *         // result is false since none of the files exists
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function some(coll, iteratee, callback) {
    return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback)
}
var some$1 = awaitify(some, 3);

/**
 * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.
 *
 * @name someLimit
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.some]{@link module:Collections.some}
 * @alias anyLimit
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
 * in the collections in parallel.
 * The iteratee should complete with a boolean `result` value.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called as soon as any
 * iteratee returns `true`, or after all the iteratee functions have finished.
 * Result will be either `true` or `false` depending on the values of the async
 * tests. Invoked with (err, result).
 * @returns {Promise} a promise, if no callback provided
 */
function someLimit(coll, limit, iteratee, callback) {
    return _createTester(Boolean, res => res)(eachOfLimit$2(limit), coll, iteratee, callback)
}
var someLimit$1 = awaitify(someLimit, 4);

/**
 * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.
 *
 * @name someSeries
 * @static
 * @memberOf module:Collections
 * @method
 * @see [async.some]{@link module:Collections.some}
 * @alias anySeries
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
 * in the collections in series.
 * The iteratee should complete with a boolean `result` value.
 * Invoked with (item, callback).
 * @param {Function} [callback] - A callback which is called as soon as any
 * iteratee returns `true`, or after all the iteratee functions have finished.
 * Result will be either `true` or `false` depending on the values of the async
 * tests. Invoked with (err, result).
 * @returns {Promise} a promise, if no callback provided
 */
function someSeries(coll, iteratee, callback) {
    return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback)
}
var someSeries$1 = awaitify(someSeries, 3);

/**
 * Sorts a list by the results of running each `coll` value through an async
 * `iteratee`.
 *
 * @name sortBy
 * @static
 * @memberOf module:Collections
 * @method
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {AsyncFunction} iteratee - An async function to apply to each item in
 * `coll`.
 * The iteratee should complete with a value to use as the sort criteria as
 * its `result`.
 * Invoked with (item, callback).
 * @param {Function} callback - A callback which is called after all the
 * `iteratee` functions have finished, or an error occurs. Results is the items
 * from the original `coll` sorted by the values returned by the `iteratee`
 * calls. Invoked with (err, results).
 * @returns {Promise} a promise, if no callback passed
 * @example
 *
 * // bigfile.txt is a file that is 251100 bytes in size
 * // mediumfile.txt is a file that is 11000 bytes in size
 * // smallfile.txt is a file that is 121 bytes in size
 *
 * // asynchronous function that returns the file size in bytes
 * function getFileSizeInBytes(file, callback) {
 *     fs.stat(file, function(err, stat) {
 *         if (err) {
 *             return callback(err);
 *         }
 *         callback(null, stat.size);
 *     });
 * }
 *
 * // Using callbacks
 * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes,
 *     function(err, results) {
 *         if (err) {
 *             console.log(err);
 *         } else {
 *             console.log(results);
 *             // results is now the original array of files sorted by
 *             // file size (ascending by default), e.g.
 *             // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
 *         }
 *     }
 * );
 *
 * // By modifying the callback parameter the
 * // sorting order can be influenced:
 *
 * // ascending order
 * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) {
 *     getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
 *         if (getFileSizeErr) return callback(getFileSizeErr);
 *         callback(null, fileSize);
 *     });
 * }, function(err, results) {
 *         if (err) {
 *             console.log(err);
 *         } else {
 *             console.log(results);
 *             // results is now the original array of files sorted by
 *             // file size (ascending by default), e.g.
 *             // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
 *         }
 *     }
 * );
 *
 * // descending order
 * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) {
 *     getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
 *         if (getFileSizeErr) {
 *             return callback(getFileSizeErr);
 *         }
 *         callback(null, fileSize * -1);
 *     });
 * }, function(err, results) {
 *         if (err) {
 *             console.log(err);
 *         } else {
 *             console.log(results);
 *             // results is now the original array of files sorted by
 *             // file size (ascending by default), e.g.
 *             // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt']
 *         }
 *     }
 * );
 *
 * // Error handling
 * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes,
 *     function(err, results) {
 *         if (err) {
 *             console.log(err);
 *             // [ Error: ENOENT: no such file or directory ]
 *         } else {
 *             console.log(results);
 *         }
 *     }
 * );
 *
 * // Using Promises
 * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes)
 * .then( results => {
 *     console.log(results);
 *     // results is now the original array of files sorted by
 *     // file size (ascending by default), e.g.
 *     // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
 * }).catch( err => {
 *     console.log(err);
 * });
 *
 * // Error handling
 * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes)
 * .then( results => {
 *     console.log(results);
 * }).catch( err => {
 *     console.log(err);
 *     // [ Error: ENOENT: no such file or directory ]
 * });
 *
 * // Using async/await
 * (async () => {
 *     try {
 *         let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
 *         console.log(results);
 *         // results is now the original array of files sorted by
 *         // file size (ascending by default), e.g.
 *         // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * })();
 *
 * // Error handling
 * async () => {
 *     try {
 *         let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
 *         console.log(results);
 *     }
 *     catch (err) {
 *         console.log(err);
 *         // [ Error: ENOENT: no such file or directory ]
 *     }
 * }
 *
 */
function sortBy (coll, iteratee, callback) {
    var _iteratee = wrapAsync(iteratee);
    return map$1(coll, (x, iterCb) => {
        _iteratee(x, (err, criteria) => {
            if (err) return iterCb(err);
            iterCb(err, {value: x, criteria});
        });
    }, (err, results) => {
        if (err) return callback(err);
        callback(null, results.sort(comparator).map(v => v.value));
    });

    function comparator(left, right) {
        var a = left.criteria, b = right.criteria;
        return a < b ? -1 : a > b ? 1 : 0;
    }
}
var sortBy$1 = awaitify(sortBy, 3);

/**
 * Sets a time limit on an asynchronous function. If the function does not call
 * its callback within the specified milliseconds, it will be called with a
 * timeout error. The code property for the error object will be `'ETIMEDOUT'`.
 *
 * @name timeout
 * @static
 * @memberOf module:Utils
 * @method
 * @category Util
 * @param {AsyncFunction} asyncFn - The async function to limit in time.
 * @param {number} milliseconds - The specified time limit.
 * @param {*} [info] - Any variable you want attached (`string`, `object`, etc)
 * to timeout Error for more information..
 * @returns {AsyncFunction} Returns a wrapped function that can be used with any
 * of the control flow functions.
 * Invoke this function with the same parameters as you would `asyncFunc`.
 * @example
 *
 * function myFunction(foo, callback) {
 *     doAsyncTask(foo, function(err, data) {
 *         // handle errors
 *         if (err) return callback(err);
 *
 *         // do some stuff ...
 *
 *         // return processed data
 *         return callback(null, data);
 *     });
 * }
 *
 * var wrapped = async.timeout(myFunction, 1000);
 *
 * // call `wrapped` as you would `myFunction`
 * wrapped({ bar: 'bar' }, function(err, data) {
 *     // if `myFunction` takes < 1000 ms to execute, `err`
 *     // and `data` will have their expected values
 *
 *     // else `err` will be an Error with the code 'ETIMEDOUT'
 * });
 */
function timeout(asyncFn, milliseconds, info) {
    var fn = wrapAsync(asyncFn);

    return initialParams((args, callback) => {
        var timedOut = false;
        var timer;

        function timeoutCallback() {
            var name = asyncFn.name || 'anonymous';
            var error  = new Error('Callback function "' + name + '" timed out.');
            error.code = 'ETIMEDOUT';
            if (info) {
                error.info = info;
            }
            timedOut = true;
            callback(error);
        }

        args.push((...cbArgs) => {
            if (!timedOut) {
                callback(...cbArgs);
                clearTimeout(timer);
            }
        });

        // setup timer and call original function
        timer = setTimeout(timeoutCallback, milliseconds);
        fn(...args);
    });
}

function range(size) {
    var result = Array(size);
    while (size--) {
        result[size] = size;
    }
    return result;
}

/**
 * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a
 * time.
 *
 * @name timesLimit
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.times]{@link module:ControlFlow.times}
 * @category Control Flow
 * @param {number} count - The number of times to run the function.
 * @param {number} limit - The maximum number of async operations at a time.
 * @param {AsyncFunction} iteratee - The async function to call `n` times.
 * Invoked with the iteration index and a callback: (n, next).
 * @param {Function} callback - see [async.map]{@link module:Collections.map}.
 * @returns {Promise} a promise, if no callback is provided
 */
function timesLimit(count, limit, iteratee, callback) {
    var _iteratee = wrapAsync(iteratee);
    return mapLimit$1(range(count), limit, _iteratee, callback);
}

/**
 * Calls the `iteratee` function `n` times, and accumulates results in the same
 * manner you would use with [map]{@link module:Collections.map}.
 *
 * @name times
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.map]{@link module:Collections.map}
 * @category Control Flow
 * @param {number} n - The number of times to run the function.
 * @param {AsyncFunction} iteratee - The async function to call `n` times.
 * Invoked with the iteration index and a callback: (n, next).
 * @param {Function} callback - see {@link module:Collections.map}.
 * @returns {Promise} a promise, if no callback is provided
 * @example
 *
 * // Pretend this is some complicated async factory
 * var createUser = function(id, callback) {
 *     callback(null, {
 *         id: 'user' + id
 *     });
 * };
 *
 * // generate 5 users
 * async.times(5, function(n, next) {
 *     createUser(n, function(err, user) {
 *         next(err, user);
 *     });
 * }, function(err, users) {
 *     // we should now have 5 users
 * });
 */
function times (n, iteratee, callback) {
    return timesLimit(n, Infinity, iteratee, callback)
}

/**
 * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.
 *
 * @name timesSeries
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.times]{@link module:ControlFlow.times}
 * @category Control Flow
 * @param {number} n - The number of times to run the function.
 * @param {AsyncFunction} iteratee - The async function to call `n` times.
 * Invoked with the iteration index and a callback: (n, next).
 * @param {Function} callback - see {@link module:Collections.map}.
 * @returns {Promise} a promise, if no callback is provided
 */
function timesSeries (n, iteratee, callback) {
    return timesLimit(n, 1, iteratee, callback)
}

/**
 * A relative of `reduce`.  Takes an Object or Array, and iterates over each
 * element in parallel, each step potentially mutating an `accumulator` value.
 * The type of the accumulator defaults to the type of collection passed in.
 *
 * @name transform
 * @static
 * @memberOf module:Collections
 * @method
 * @category Collection
 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 * @param {*} [accumulator] - The initial state of the transform.  If omitted,
 * it will default to an empty Object or Array, depending on the type of `coll`
 * @param {AsyncFunction} iteratee - A function applied to each item in the
 * collection that potentially modifies the accumulator.
 * Invoked with (accumulator, item, key, callback).
 * @param {Function} [callback] - A callback which is called after all the
 * `iteratee` functions have finished. Result is the transformed accumulator.
 * Invoked with (err, result).
 * @returns {Promise} a promise, if no callback provided
 * @example
 *
 * // file1.txt is a file that is 1000 bytes in size
 * // file2.txt is a file that is 2000 bytes in size
 * // file3.txt is a file that is 3000 bytes in size
 *
 * // helper function that returns human-readable size format from bytes
 * function formatBytes(bytes, decimals = 2) {
 *   // implementation not included for brevity
 *   return humanReadbleFilesize;
 * }
 *
 * const fileList = ['file1.txt','file2.txt','file3.txt'];
 *
 * // asynchronous function that returns the file size, transformed to human-readable format
 * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.
 * function transformFileSize(acc, value, key, callback) {
 *     fs.stat(value, function(err, stat) {
 *         if (err) {
 *             return callback(err);
 *         }
 *         acc[key] = formatBytes(stat.size);
 *         callback(null);
 *     });
 * }
 *
 * // Using callbacks
 * async.transform(fileList, transformFileSize, function(err, result) {
 *     if(err) {
 *         console.log(err);
 *     } else {
 *         console.log(result);
 *         // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
 *     }
 * });
 *
 * // Using Promises
 * async.transform(fileList, transformFileSize)
 * .then(result => {
 *     console.log(result);
 *     // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
 * }).catch(err => {
 *     console.log(err);
 * });
 *
 * // Using async/await
 * (async () => {
 *     try {
 *         let result = await async.transform(fileList, transformFileSize);
 *         console.log(result);
 *         // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * })();
 *
 * @example
 *
 * // file1.txt is a file that is 1000 bytes in size
 * // file2.txt is a file that is 2000 bytes in size
 * // file3.txt is a file that is 3000 bytes in size
 *
 * // helper function that returns human-readable size format from bytes
 * function formatBytes(bytes, decimals = 2) {
 *   // implementation not included for brevity
 *   return humanReadbleFilesize;
 * }
 *
 * const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' };
 *
 * // asynchronous function that returns the file size, transformed to human-readable format
 * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.
 * function transformFileSize(acc, value, key, callback) {
 *     fs.stat(value, function(err, stat) {
 *         if (err) {
 *             return callback(err);
 *         }
 *         acc[key] = formatBytes(stat.size);
 *         callback(null);
 *     });
 * }
 *
 * // Using callbacks
 * async.transform(fileMap, transformFileSize, function(err, result) {
 *     if(err) {
 *         console.log(err);
 *     } else {
 *         console.log(result);
 *         // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
 *     }
 * });
 *
 * // Using Promises
 * async.transform(fileMap, transformFileSize)
 * .then(result => {
 *     console.log(result);
 *     // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
 * }).catch(err => {
 *     console.log(err);
 * });
 *
 * // Using async/await
 * async () => {
 *     try {
 *         let result = await async.transform(fileMap, transformFileSize);
 *         console.log(result);
 *         // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
 *     }
 *     catch (err) {
 *         console.log(err);
 *     }
 * }
 *
 */
function transform (coll, accumulator, iteratee, callback) {
    if (arguments.length <= 3 && typeof accumulator === 'function') {
        callback = iteratee;
        iteratee = accumulator;
        accumulator = Array.isArray(coll) ? [] : {};
    }
    callback = once$1(callback || promiseCallback());
    var _iteratee = wrapAsync(iteratee);

    eachOf$1(coll, (v, k, cb) => {
        _iteratee(accumulator, v, k, cb);
    }, err => callback(err, accumulator));
    return callback[PROMISE_SYMBOL]
}

/**
 * It runs each task in series but stops whenever any of the functions were
 * successful. If one of the tasks were successful, the `callback` will be
 * passed the result of the successful task. If all tasks fail, the callback
 * will be passed the error and result (if any) of the final attempt.
 *
 * @name tryEach
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to
 * run, each function is passed a `callback(err, result)` it must call on
 * completion with an error `err` (which can be `null`) and an optional `result`
 * value.
 * @param {Function} [callback] - An optional callback which is called when one
 * of the tasks has succeeded, or all have failed. It receives the `err` and
 * `result` arguments of the last attempt at completing the `task`. Invoked with
 * (err, results).
 * @returns {Promise} a promise, if no callback is passed
 * @example
 * async.tryEach([
 *     function getDataFromFirstWebsite(callback) {
 *         // Try getting the data from the first website
 *         callback(err, data);
 *     },
 *     function getDataFromSecondWebsite(callback) {
 *         // First website failed,
 *         // Try getting the data from the backup website
 *         callback(err, data);
 *     }
 * ],
 * // optional callback
 * function(err, results) {
 *     Now do something with the data.
 * });
 *
 */
function tryEach(tasks, callback) {
    var error = null;
    var result;
    return eachSeries$1(tasks, (task, taskCb) => {
        wrapAsync(task)((err, ...args) => {
            if (err === false) return taskCb(err);

            if (args.length < 2) {
                [result] = args;
            } else {
                result = args;
            }
            error = err;
            taskCb(err ? null : {});
        });
    }, () => callback(error, result));
}

var tryEach$1 = awaitify(tryEach);

/**
 * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,
 * unmemoized form. Handy for testing.
 *
 * @name unmemoize
 * @static
 * @memberOf module:Utils
 * @method
 * @see [async.memoize]{@link module:Utils.memoize}
 * @category Util
 * @param {AsyncFunction} fn - the memoized function
 * @returns {AsyncFunction} a function that calls the original unmemoized function
 */
function unmemoize(fn) {
    return (...args) => {
        return (fn.unmemoized || fn)(...args);
    };
}

/**
 * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
 * stopped, or an error occurs.
 *
 * @name whilst
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {AsyncFunction} test - asynchronous truth test to perform before each
 * execution of `iteratee`. Invoked with (callback).
 * @param {AsyncFunction} iteratee - An async function which is called each time
 * `test` passes. Invoked with (callback).
 * @param {Function} [callback] - A callback which is called after the test
 * function has failed and repeated execution of `iteratee` has stopped. `callback`
 * will be passed an error and any arguments passed to the final `iteratee`'s
 * callback. Invoked with (err, [results]);
 * @returns {Promise} a promise, if no callback is passed
 * @example
 *
 * var count = 0;
 * async.whilst(
 *     function test(cb) { cb(null, count < 5); },
 *     function iter(callback) {
 *         count++;
 *         setTimeout(function() {
 *             callback(null, count);
 *         }, 1000);
 *     },
 *     function (err, n) {
 *         // 5 seconds have passed, n = 5
 *     }
 * );
 */
function whilst(test, iteratee, callback) {
    callback = onlyOnce(callback);
    var _fn = wrapAsync(iteratee);
    var _test = wrapAsync(test);
    var results = [];

    function next(err, ...rest) {
        if (err) return callback(err);
        results = rest;
        if (err === false) return;
        _test(check);
    }

    function check(err, truth) {
        if (err) return callback(err);
        if (err === false) return;
        if (!truth) return callback(null, ...results);
        _fn(next);
    }

    return _test(check);
}
var whilst$1 = awaitify(whilst, 3);

/**
 * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when
 * stopped, or an error occurs. `callback` will be passed an error and any
 * arguments passed to the final `iteratee`'s callback.
 *
 * The inverse of [whilst]{@link module:ControlFlow.whilst}.
 *
 * @name until
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @see [async.whilst]{@link module:ControlFlow.whilst}
 * @category Control Flow
 * @param {AsyncFunction} test - asynchronous truth test to perform before each
 * execution of `iteratee`. Invoked with (callback).
 * @param {AsyncFunction} iteratee - An async function which is called each time
 * `test` fails. Invoked with (callback).
 * @param {Function} [callback] - A callback which is called after the test
 * function has passed and repeated execution of `iteratee` has stopped. `callback`
 * will be passed an error and any arguments passed to the final `iteratee`'s
 * callback. Invoked with (err, [results]);
 * @returns {Promise} a promise, if a callback is not passed
 *
 * @example
 * const results = []
 * let finished = false
 * async.until(function test(cb) {
 *     cb(null, finished)
 * }, function iter(next) {
 *     fetchPage(url, (err, body) => {
 *         if (err) return next(err)
 *         results = results.concat(body.objects)
 *         finished = !!body.next
 *         next(err)
 *     })
 * }, function done (err) {
 *     // all pages have been fetched
 * })
 */
function until(test, iteratee, callback) {
    const _test = wrapAsync(test);
    return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback);
}

/**
 * Runs the `tasks` array of functions in series, each passing their results to
 * the next in the array. However, if any of the `tasks` pass an error to their
 * own callback, the next function is not executed, and the main `callback` is
 * immediately called with the error.
 *
 * @name waterfall
 * @static
 * @memberOf module:ControlFlow
 * @method
 * @category Control Flow
 * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
 * to run.
 * Each function should complete with any number of `result` values.
 * The `result` values will be passed as arguments, in order, to the next task.
 * @param {Function} [callback] - An optional callback to run once all the
 * functions have completed. This will be passed the results of the last task's
 * callback. Invoked with (err, [results]).
 * @returns {Promise} a promise, if a callback is omitted
 * @example
 *
 * async.waterfall([
 *     function(callback) {
 *         callback(null, 'one', 'two');
 *     },
 *     function(arg1, arg2, callback) {
 *         // arg1 now equals 'one' and arg2 now equals 'two'
 *         callback(null, 'three');
 *     },
 *     function(arg1, callback) {
 *         // arg1 now equals 'three'
 *         callback(null, 'done');
 *     }
 * ], function (err, result) {
 *     // result now equals 'done'
 * });
 *
 * // Or, with named functions:
 * async.waterfall([
 *     myFirstFunction,
 *     mySecondFunction,
 *     myLastFunction,
 * ], function (err, result) {
 *     // result now equals 'done'
 * });
 * function myFirstFunction(callback) {
 *     callback(null, 'one', 'two');
 * }
 * function mySecondFunction(arg1, arg2, callback) {
 *     // arg1 now equals 'one' and arg2 now equals 'two'
 *     callback(null, 'three');
 * }
 * function myLastFunction(arg1, callback) {
 *     // arg1 now equals 'three'
 *     callback(null, 'done');
 * }
 */
function waterfall (tasks, callback) {
    callback = once$1(callback);
    if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));
    if (!tasks.length) return callback();
    var taskIndex = 0;

    function nextTask(args) {
        var task = wrapAsync(tasks[taskIndex++]);
        task(...args, onlyOnce(next));
    }

    function next(err, ...args) {
        if (err === false) return
        if (err || taskIndex === tasks.length) {
            return callback(err, ...args);
        }
        nextTask(args);
    }

    nextTask([]);
}

var waterfall$1 = awaitify(waterfall);

/**
 * An "async function" in the context of Async is an asynchronous function with
 * a variable number of parameters, with the final parameter being a callback.
 * (`function (arg1, arg2, ..., callback) {}`)
 * The final callback is of the form `callback(err, results...)`, which must be
 * called once the function is completed.  The callback should be called with a
 * Error as its first argument to signal that an error occurred.
 * Otherwise, if no error occurred, it should be called with `null` as the first
 * argument, and any additional `result` arguments that may apply, to signal
 * successful completion.
 * The callback must be called exactly once, ideally on a later tick of the
 * JavaScript event loop.
 *
 * This type of function is also referred to as a "Node-style async function",
 * or a "continuation passing-style function" (CPS). Most of the methods of this
 * library are themselves CPS/Node-style async functions, or functions that
 * return CPS/Node-style async functions.
 *
 * Wherever we accept a Node-style async function, we also directly accept an
 * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.
 * In this case, the `async` function will not be passed a final callback
 * argument, and any thrown error will be used as the `err` argument of the
 * implicit callback, and the return value will be used as the `result` value.
 * (i.e. a `rejected` of the returned Promise becomes the `err` callback
 * argument, and a `resolved` value becomes the `result`.)
 *
 * Note, due to JavaScript limitations, we can only detect native `async`
 * functions and not transpilied implementations.
 * Your environment must have `async`/`await` support for this to work.
 * (e.g. Node > v7.6, or a recent version of a modern browser).
 * If you are using `async` functions through a transpiler (e.g. Babel), you
 * must still wrap the function with [asyncify]{@link module:Utils.asyncify},
 * because the `async function` will be compiled to an ordinary function that
 * returns a promise.
 *
 * @typedef {Function} AsyncFunction
 * @static
 */


var index$1 = {
    apply,
    applyEach,
    applyEachSeries,
    asyncify,
    auto,
    autoInject,
    cargo: cargo$1,
    cargoQueue: cargo,
    compose,
    concat: concat$1,
    concatLimit: concatLimit$1,
    concatSeries: concatSeries$1,
    constant: constant$1,
    detect: detect$1,
    detectLimit: detectLimit$1,
    detectSeries: detectSeries$1,
    dir,
    doUntil,
    doWhilst: doWhilst$1,
    each,
    eachLimit: eachLimit$1,
    eachOf: eachOf$1,
    eachOfLimit: eachOfLimit$1,
    eachOfSeries: eachOfSeries$1,
    eachSeries: eachSeries$1,
    ensureAsync,
    every: every$1,
    everyLimit: everyLimit$1,
    everySeries: everySeries$1,
    filter: filter$1,
    filterLimit: filterLimit$1,
    filterSeries: filterSeries$1,
    forever: forever$1,
    groupBy,
    groupByLimit: groupByLimit$1,
    groupBySeries,
    log,
    map: map$1,
    mapLimit: mapLimit$1,
    mapSeries: mapSeries$1,
    mapValues,
    mapValuesLimit: mapValuesLimit$1,
    mapValuesSeries,
    memoize,
    nextTick,
    parallel,
    parallelLimit,
    priorityQueue,
    queue,
    race: race$1,
    reduce: reduce$1,
    reduceRight,
    reflect,
    reflectAll,
    reject: reject$1,
    rejectLimit: rejectLimit$1,
    rejectSeries: rejectSeries$1,
    retry,
    retryable,
    seq,
    series,
    setImmediate: setImmediate$1,
    some: some$1,
    someLimit: someLimit$1,
    someSeries: someSeries$1,
    sortBy: sortBy$1,
    timeout,
    times,
    timesLimit,
    timesSeries,
    transform,
    tryEach: tryEach$1,
    unmemoize,
    until,
    waterfall: waterfall$1,
    whilst: whilst$1,

    // aliases
    all: every$1,
    allLimit: everyLimit$1,
    allSeries: everySeries$1,
    any: some$1,
    anyLimit: someLimit$1,
    anySeries: someSeries$1,
    find: detect$1,
    findLimit: detectLimit$1,
    findSeries: detectSeries$1,
    flatMap: concat$1,
    flatMapLimit: concatLimit$1,
    flatMapSeries: concatSeries$1,
    forEach: each,
    forEachSeries: eachSeries$1,
    forEachLimit: eachLimit$1,
    forEachOf: eachOf$1,
    forEachOfSeries: eachOfSeries$1,
    forEachOfLimit: eachOfLimit$1,
    inject: reduce$1,
    foldl: reduce$1,
    foldr: reduceRight,
    select: filter$1,
    selectLimit: filterLimit$1,
    selectSeries: filterSeries$1,
    wrapSync: asyncify,
    during: whilst$1,
    doDuring: doWhilst$1
};

var async = /*#__PURE__*/Object.freeze({
	__proto__: null,
	all: every$1,
	allLimit: everyLimit$1,
	allSeries: everySeries$1,
	any: some$1,
	anyLimit: someLimit$1,
	anySeries: someSeries$1,
	apply: apply,
	applyEach: applyEach,
	applyEachSeries: applyEachSeries,
	asyncify: asyncify,
	auto: auto,
	autoInject: autoInject,
	cargo: cargo$1,
	cargoQueue: cargo,
	compose: compose,
	concat: concat$1,
	concatLimit: concatLimit$1,
	concatSeries: concatSeries$1,
	constant: constant$1,
	default: index$1,
	detect: detect$1,
	detectLimit: detectLimit$1,
	detectSeries: detectSeries$1,
	dir: dir,
	doDuring: doWhilst$1,
	doUntil: doUntil,
	doWhilst: doWhilst$1,
	during: whilst$1,
	each: each,
	eachLimit: eachLimit$1,
	eachOf: eachOf$1,
	eachOfLimit: eachOfLimit$1,
	eachOfSeries: eachOfSeries$1,
	eachSeries: eachSeries$1,
	ensureAsync: ensureAsync,
	every: every$1,
	everyLimit: everyLimit$1,
	everySeries: everySeries$1,
	filter: filter$1,
	filterLimit: filterLimit$1,
	filterSeries: filterSeries$1,
	find: detect$1,
	findLimit: detectLimit$1,
	findSeries: detectSeries$1,
	flatMap: concat$1,
	flatMapLimit: concatLimit$1,
	flatMapSeries: concatSeries$1,
	foldl: reduce$1,
	foldr: reduceRight,
	forEach: each,
	forEachLimit: eachLimit$1,
	forEachOf: eachOf$1,
	forEachOfLimit: eachOfLimit$1,
	forEachOfSeries: eachOfSeries$1,
	forEachSeries: eachSeries$1,
	forever: forever$1,
	groupBy: groupBy,
	groupByLimit: groupByLimit$1,
	groupBySeries: groupBySeries,
	inject: reduce$1,
	log: log,
	map: map$1,
	mapLimit: mapLimit$1,
	mapSeries: mapSeries$1,
	mapValues: mapValues,
	mapValuesLimit: mapValuesLimit$1,
	mapValuesSeries: mapValuesSeries,
	memoize: memoize,
	nextTick: nextTick,
	parallel: parallel,
	parallelLimit: parallelLimit,
	priorityQueue: priorityQueue,
	queue: queue,
	race: race$1,
	reduce: reduce$1,
	reduceRight: reduceRight,
	reflect: reflect,
	reflectAll: reflectAll,
	reject: reject$1,
	rejectLimit: rejectLimit$1,
	rejectSeries: rejectSeries$1,
	retry: retry,
	retryable: retryable,
	select: filter$1,
	selectLimit: filterLimit$1,
	selectSeries: filterSeries$1,
	seq: seq,
	series: series,
	setImmediate: setImmediate$1,
	some: some$1,
	someLimit: someLimit$1,
	someSeries: someSeries$1,
	sortBy: sortBy$1,
	timeout: timeout,
	times: times,
	timesLimit: timesLimit,
	timesSeries: timesSeries,
	transform: transform,
	tryEach: tryEach$1,
	unmemoize: unmemoize,
	until: until,
	waterfall: waterfall$1,
	whilst: whilst$1,
	wrapSync: asyncify
});

var require$$2 = /*@__PURE__*/getAugmentedNamespace(async);

var archiverUtils = {exports: {}};

var polyfills;
var hasRequiredPolyfills;

function requirePolyfills () {
	if (hasRequiredPolyfills) return polyfills;
	hasRequiredPolyfills = 1;
	var constants = require$$0$3;

	var origCwd = process.cwd;
	var cwd = null;

	var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform;

	process.cwd = function() {
	  if (!cwd)
	    cwd = origCwd.call(process);
	  return cwd
	};
	try {
	  process.cwd();
	} catch (er) {}

	// This check is needed until node.js 12 is required
	if (typeof process.chdir === 'function') {
	  var chdir = process.chdir;
	  process.chdir = function (d) {
	    cwd = null;
	    chdir.call(process, d);
	  };
	  if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir);
	}

	polyfills = patch;

	function patch (fs) {
	  // (re-)implement some things that are known busted or missing.

	  // lchmod, broken prior to 0.6.2
	  // back-port the fix here.
	  if (constants.hasOwnProperty('O_SYMLINK') &&
	      process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
	    patchLchmod(fs);
	  }

	  // lutimes implementation, or no-op
	  if (!fs.lutimes) {
	    patchLutimes(fs);
	  }

	  // https://github.com/isaacs/node-graceful-fs/issues/4
	  // Chown should not fail on einval or eperm if non-root.
	  // It should not fail on enosys ever, as this just indicates
	  // that a fs doesn't support the intended operation.

	  fs.chown = chownFix(fs.chown);
	  fs.fchown = chownFix(fs.fchown);
	  fs.lchown = chownFix(fs.lchown);

	  fs.chmod = chmodFix(fs.chmod);
	  fs.fchmod = chmodFix(fs.fchmod);
	  fs.lchmod = chmodFix(fs.lchmod);

	  fs.chownSync = chownFixSync(fs.chownSync);
	  fs.fchownSync = chownFixSync(fs.fchownSync);
	  fs.lchownSync = chownFixSync(fs.lchownSync);

	  fs.chmodSync = chmodFixSync(fs.chmodSync);
	  fs.fchmodSync = chmodFixSync(fs.fchmodSync);
	  fs.lchmodSync = chmodFixSync(fs.lchmodSync);

	  fs.stat = statFix(fs.stat);
	  fs.fstat = statFix(fs.fstat);
	  fs.lstat = statFix(fs.lstat);

	  fs.statSync = statFixSync(fs.statSync);
	  fs.fstatSync = statFixSync(fs.fstatSync);
	  fs.lstatSync = statFixSync(fs.lstatSync);

	  // if lchmod/lchown do not exist, then make them no-ops
	  if (fs.chmod && !fs.lchmod) {
	    fs.lchmod = function (path, mode, cb) {
	      if (cb) process.nextTick(cb);
	    };
	    fs.lchmodSync = function () {};
	  }
	  if (fs.chown && !fs.lchown) {
	    fs.lchown = function (path, uid, gid, cb) {
	      if (cb) process.nextTick(cb);
	    };
	    fs.lchownSync = function () {};
	  }

	  // on Windows, A/V software can lock the directory, causing this
	  // to fail with an EACCES or EPERM if the directory contains newly
	  // created files.  Try again on failure, for up to 60 seconds.

	  // Set the timeout this long because some Windows Anti-Virus, such as Parity
	  // bit9, may lock files for up to a minute, causing npm package install
	  // failures. Also, take care to yield the scheduler. Windows scheduling gives
	  // CPU to a busy looping process, which can cause the program causing the lock
	  // contention to be starved of CPU by node, so the contention doesn't resolve.
	  if (platform === "win32") {
	    fs.rename = typeof fs.rename !== 'function' ? fs.rename
	    : (function (fs$rename) {
	      function rename (from, to, cb) {
	        var start = Date.now();
	        var backoff = 0;
	        fs$rename(from, to, function CB (er) {
	          if (er
	              && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY")
	              && Date.now() - start < 60000) {
	            setTimeout(function() {
	              fs.stat(to, function (stater, st) {
	                if (stater && stater.code === "ENOENT")
	                  fs$rename(from, to, CB);
	                else
	                  cb(er);
	              });
	            }, backoff);
	            if (backoff < 100)
	              backoff += 10;
	            return;
	          }
	          if (cb) cb(er);
	        });
	      }
	      if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename);
	      return rename
	    })(fs.rename);
	  }

	  // if read() returns EAGAIN, then just try it again.
	  fs.read = typeof fs.read !== 'function' ? fs.read
	  : (function (fs$read) {
	    function read (fd, buffer, offset, length, position, callback_) {
	      var callback;
	      if (callback_ && typeof callback_ === 'function') {
	        var eagCounter = 0;
	        callback = function (er, _, __) {
	          if (er && er.code === 'EAGAIN' && eagCounter < 10) {
	            eagCounter ++;
	            return fs$read.call(fs, fd, buffer, offset, length, position, callback)
	          }
	          callback_.apply(this, arguments);
	        };
	      }
	      return fs$read.call(fs, fd, buffer, offset, length, position, callback)
	    }

	    // This ensures `util.promisify` works as it does for native `fs.read`.
	    if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read);
	    return read
	  })(fs.read);

	  fs.readSync = typeof fs.readSync !== 'function' ? fs.readSync
	  : (function (fs$readSync) { return function (fd, buffer, offset, length, position) {
	    var eagCounter = 0;
	    while (true) {
	      try {
	        return fs$readSync.call(fs, fd, buffer, offset, length, position)
	      } catch (er) {
	        if (er.code === 'EAGAIN' && eagCounter < 10) {
	          eagCounter ++;
	          continue
	        }
	        throw er
	      }
	    }
	  }})(fs.readSync);

	  function patchLchmod (fs) {
	    fs.lchmod = function (path, mode, callback) {
	      fs.open( path
	             , constants.O_WRONLY | constants.O_SYMLINK
	             , mode
	             , function (err, fd) {
	        if (err) {
	          if (callback) callback(err);
	          return
	        }
	        // prefer to return the chmod error, if one occurs,
	        // but still try to close, and report closing errors if they occur.
	        fs.fchmod(fd, mode, function (err) {
	          fs.close(fd, function(err2) {
	            if (callback) callback(err || err2);
	          });
	        });
	      });
	    };

	    fs.lchmodSync = function (path, mode) {
	      var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode);

	      // prefer to return the chmod error, if one occurs,
	      // but still try to close, and report closing errors if they occur.
	      var threw = true;
	      var ret;
	      try {
	        ret = fs.fchmodSync(fd, mode);
	        threw = false;
	      } finally {
	        if (threw) {
	          try {
	            fs.closeSync(fd);
	          } catch (er) {}
	        } else {
	          fs.closeSync(fd);
	        }
	      }
	      return ret
	    };
	  }

	  function patchLutimes (fs) {
	    if (constants.hasOwnProperty("O_SYMLINK") && fs.futimes) {
	      fs.lutimes = function (path, at, mt, cb) {
	        fs.open(path, constants.O_SYMLINK, function (er, fd) {
	          if (er) {
	            if (cb) cb(er);
	            return
	          }
	          fs.futimes(fd, at, mt, function (er) {
	            fs.close(fd, function (er2) {
	              if (cb) cb(er || er2);
	            });
	          });
	        });
	      };

	      fs.lutimesSync = function (path, at, mt) {
	        var fd = fs.openSync(path, constants.O_SYMLINK);
	        var ret;
	        var threw = true;
	        try {
	          ret = fs.futimesSync(fd, at, mt);
	          threw = false;
	        } finally {
	          if (threw) {
	            try {
	              fs.closeSync(fd);
	            } catch (er) {}
	          } else {
	            fs.closeSync(fd);
	          }
	        }
	        return ret
	      };

	    } else if (fs.futimes) {
	      fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb); };
	      fs.lutimesSync = function () {};
	    }
	  }

	  function chmodFix (orig) {
	    if (!orig) return orig
	    return function (target, mode, cb) {
	      return orig.call(fs, target, mode, function (er) {
	        if (chownErOk(er)) er = null;
	        if (cb) cb.apply(this, arguments);
	      })
	    }
	  }

	  function chmodFixSync (orig) {
	    if (!orig) return orig
	    return function (target, mode) {
	      try {
	        return orig.call(fs, target, mode)
	      } catch (er) {
	        if (!chownErOk(er)) throw er
	      }
	    }
	  }


	  function chownFix (orig) {
	    if (!orig) return orig
	    return function (target, uid, gid, cb) {
	      return orig.call(fs, target, uid, gid, function (er) {
	        if (chownErOk(er)) er = null;
	        if (cb) cb.apply(this, arguments);
	      })
	    }
	  }

	  function chownFixSync (orig) {
	    if (!orig) return orig
	    return function (target, uid, gid) {
	      try {
	        return orig.call(fs, target, uid, gid)
	      } catch (er) {
	        if (!chownErOk(er)) throw er
	      }
	    }
	  }

	  function statFix (orig) {
	    if (!orig) return orig
	    // Older versions of Node erroneously returned signed integers for
	    // uid + gid.
	    return function (target, options, cb) {
	      if (typeof options === 'function') {
	        cb = options;
	        options = null;
	      }
	      function callback (er, stats) {
	        if (stats) {
	          if (stats.uid < 0) stats.uid += 0x100000000;
	          if (stats.gid < 0) stats.gid += 0x100000000;
	        }
	        if (cb) cb.apply(this, arguments);
	      }
	      return options ? orig.call(fs, target, options, callback)
	        : orig.call(fs, target, callback)
	    }
	  }

	  function statFixSync (orig) {
	    if (!orig) return orig
	    // Older versions of Node erroneously returned signed integers for
	    // uid + gid.
	    return function (target, options) {
	      var stats = options ? orig.call(fs, target, options)
	        : orig.call(fs, target);
	      if (stats) {
	        if (stats.uid < 0) stats.uid += 0x100000000;
	        if (stats.gid < 0) stats.gid += 0x100000000;
	      }
	      return stats;
	    }
	  }

	  // ENOSYS means that the fs doesn't support the op. Just ignore
	  // that, because it doesn't matter.
	  //
	  // if there's no getuid, or if getuid() is something other
	  // than 0, and the error is EINVAL or EPERM, then just ignore
	  // it.
	  //
	  // This specific case is a silent failure in cp, install, tar,
	  // and most other unix tools that manage permissions.
	  //
	  // When running as root, or if other types of errors are
	  // encountered, then it's strict.
	  function chownErOk (er) {
	    if (!er)
	      return true

	    if (er.code === "ENOSYS")
	      return true

	    var nonroot = !process.getuid || process.getuid() !== 0;
	    if (nonroot) {
	      if (er.code === "EINVAL" || er.code === "EPERM")
	        return true
	    }

	    return false
	  }
	}
	return polyfills;
}

var legacyStreams;
var hasRequiredLegacyStreams;

function requireLegacyStreams () {
	if (hasRequiredLegacyStreams) return legacyStreams;
	hasRequiredLegacyStreams = 1;
	var Stream = require$$0$4.Stream;

	legacyStreams = legacy;

	function legacy (fs) {
	  return {
	    ReadStream: ReadStream,
	    WriteStream: WriteStream
	  }

	  function ReadStream (path, options) {
	    if (!(this instanceof ReadStream)) return new ReadStream(path, options);

	    Stream.call(this);

	    var self = this;

	    this.path = path;
	    this.fd = null;
	    this.readable = true;
	    this.paused = false;

	    this.flags = 'r';
	    this.mode = 438; /*=0666*/
	    this.bufferSize = 64 * 1024;

	    options = options || {};

	    // Mixin options into this
	    var keys = Object.keys(options);
	    for (var index = 0, length = keys.length; index < length; index++) {
	      var key = keys[index];
	      this[key] = options[key];
	    }

	    if (this.encoding) this.setEncoding(this.encoding);

	    if (this.start !== undefined) {
	      if ('number' !== typeof this.start) {
	        throw TypeError('start must be a Number');
	      }
	      if (this.end === undefined) {
	        this.end = Infinity;
	      } else if ('number' !== typeof this.end) {
	        throw TypeError('end must be a Number');
	      }

	      if (this.start > this.end) {
	        throw new Error('start must be <= end');
	      }

	      this.pos = this.start;
	    }

	    if (this.fd !== null) {
	      process.nextTick(function() {
	        self._read();
	      });
	      return;
	    }

	    fs.open(this.path, this.flags, this.mode, function (err, fd) {
	      if (err) {
	        self.emit('error', err);
	        self.readable = false;
	        return;
	      }

	      self.fd = fd;
	      self.emit('open', fd);
	      self._read();
	    });
	  }

	  function WriteStream (path, options) {
	    if (!(this instanceof WriteStream)) return new WriteStream(path, options);

	    Stream.call(this);

	    this.path = path;
	    this.fd = null;
	    this.writable = true;

	    this.flags = 'w';
	    this.encoding = 'binary';
	    this.mode = 438; /*=0666*/
	    this.bytesWritten = 0;

	    options = options || {};

	    // Mixin options into this
	    var keys = Object.keys(options);
	    for (var index = 0, length = keys.length; index < length; index++) {
	      var key = keys[index];
	      this[key] = options[key];
	    }

	    if (this.start !== undefined) {
	      if ('number' !== typeof this.start) {
	        throw TypeError('start must be a Number');
	      }
	      if (this.start < 0) {
	        throw new Error('start must be >= zero');
	      }

	      this.pos = this.start;
	    }

	    this.busy = false;
	    this._queue = [];

	    if (this.fd === null) {
	      this._open = fs.open;
	      this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
	      this.flush();
	    }
	  }
	}
	return legacyStreams;
}

var clone_1;
var hasRequiredClone;

function requireClone () {
	if (hasRequiredClone) return clone_1;
	hasRequiredClone = 1;

	clone_1 = clone;

	var getPrototypeOf = Object.getPrototypeOf || function (obj) {
	  return obj.__proto__
	};

	function clone (obj) {
	  if (obj === null || typeof obj !== 'object')
	    return obj

	  if (obj instanceof Object)
	    var copy = { __proto__: getPrototypeOf(obj) };
	  else
	    var copy = Object.create(null);

	  Object.getOwnPropertyNames(obj).forEach(function (key) {
	    Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key));
	  });

	  return copy
	}
	return clone_1;
}

var gracefulFs;
var hasRequiredGracefulFs;

function requireGracefulFs () {
	if (hasRequiredGracefulFs) return gracefulFs;
	hasRequiredGracefulFs = 1;
	var fs = require$$0$2;
	var polyfills = requirePolyfills();
	var legacy = requireLegacyStreams();
	var clone = requireClone();

	var util = require$$0$5;

	/* istanbul ignore next - node 0.x polyfill */
	var gracefulQueue;
	var previousSymbol;

	/* istanbul ignore else - node 0.x polyfill */
	if (typeof Symbol === 'function' && typeof Symbol.for === 'function') {
	  gracefulQueue = Symbol.for('graceful-fs.queue');
	  // This is used in testing by future versions
	  previousSymbol = Symbol.for('graceful-fs.previous');
	} else {
	  gracefulQueue = '___graceful-fs.queue';
	  previousSymbol = '___graceful-fs.previous';
	}

	function noop () {}

	function publishQueue(context, queue) {
	  Object.defineProperty(context, gracefulQueue, {
	    get: function() {
	      return queue
	    }
	  });
	}

	var debug = noop;
	if (util.debuglog)
	  debug = util.debuglog('gfs4');
	else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ''))
	  debug = function() {
	    var m = util.format.apply(util, arguments);
	    m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ');
	    console.error(m);
	  };

	// Once time initialization
	if (!fs[gracefulQueue]) {
	  // This queue can be shared by multiple loaded instances
	  var queue = commonjsGlobal[gracefulQueue] || [];
	  publishQueue(fs, queue);

	  // Patch fs.close/closeSync to shared queue version, because we need
	  // to retry() whenever a close happens *anywhere* in the program.
	  // This is essential when multiple graceful-fs instances are
	  // in play at the same time.
	  fs.close = (function (fs$close) {
	    function close (fd, cb) {
	      return fs$close.call(fs, fd, function (err) {
	        // This function uses the graceful-fs shared queue
	        if (!err) {
	          resetQueue();
	        }

	        if (typeof cb === 'function')
	          cb.apply(this, arguments);
	      })
	    }

	    Object.defineProperty(close, previousSymbol, {
	      value: fs$close
	    });
	    return close
	  })(fs.close);

	  fs.closeSync = (function (fs$closeSync) {
	    function closeSync (fd) {
	      // This function uses the graceful-fs shared queue
	      fs$closeSync.apply(fs, arguments);
	      resetQueue();
	    }

	    Object.defineProperty(closeSync, previousSymbol, {
	      value: fs$closeSync
	    });
	    return closeSync
	  })(fs.closeSync);

	  if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) {
	    process.on('exit', function() {
	      debug(fs[gracefulQueue]);
	      require$$5.equal(fs[gracefulQueue].length, 0);
	    });
	  }
	}

	if (!commonjsGlobal[gracefulQueue]) {
	  publishQueue(commonjsGlobal, fs[gracefulQueue]);
	}

	gracefulFs = patch(clone(fs));
	if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) {
	    gracefulFs = patch(fs);
	    fs.__patched = true;
	}

	function patch (fs) {
	  // Everything that references the open() function needs to be in here
	  polyfills(fs);
	  fs.gracefulify = patch;

	  fs.createReadStream = createReadStream;
	  fs.createWriteStream = createWriteStream;
	  var fs$readFile = fs.readFile;
	  fs.readFile = readFile;
	  function readFile (path, options, cb) {
	    if (typeof options === 'function')
	      cb = options, options = null;

	    return go$readFile(path, options, cb)

	    function go$readFile (path, options, cb, startTime) {
	      return fs$readFile(path, options, function (err) {
	        if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
	          enqueue([go$readFile, [path, options, cb], err, startTime || Date.now(), Date.now()]);
	        else {
	          if (typeof cb === 'function')
	            cb.apply(this, arguments);
	        }
	      })
	    }
	  }

	  var fs$writeFile = fs.writeFile;
	  fs.writeFile = writeFile;
	  function writeFile (path, data, options, cb) {
	    if (typeof options === 'function')
	      cb = options, options = null;

	    return go$writeFile(path, data, options, cb)

	    function go$writeFile (path, data, options, cb, startTime) {
	      return fs$writeFile(path, data, options, function (err) {
	        if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
	          enqueue([go$writeFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]);
	        else {
	          if (typeof cb === 'function')
	            cb.apply(this, arguments);
	        }
	      })
	    }
	  }

	  var fs$appendFile = fs.appendFile;
	  if (fs$appendFile)
	    fs.appendFile = appendFile;
	  function appendFile (path, data, options, cb) {
	    if (typeof options === 'function')
	      cb = options, options = null;

	    return go$appendFile(path, data, options, cb)

	    function go$appendFile (path, data, options, cb, startTime) {
	      return fs$appendFile(path, data, options, function (err) {
	        if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
	          enqueue([go$appendFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]);
	        else {
	          if (typeof cb === 'function')
	            cb.apply(this, arguments);
	        }
	      })
	    }
	  }

	  var fs$copyFile = fs.copyFile;
	  if (fs$copyFile)
	    fs.copyFile = copyFile;
	  function copyFile (src, dest, flags, cb) {
	    if (typeof flags === 'function') {
	      cb = flags;
	      flags = 0;
	    }
	    return go$copyFile(src, dest, flags, cb)

	    function go$copyFile (src, dest, flags, cb, startTime) {
	      return fs$copyFile(src, dest, flags, function (err) {
	        if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
	          enqueue([go$copyFile, [src, dest, flags, cb], err, startTime || Date.now(), Date.now()]);
	        else {
	          if (typeof cb === 'function')
	            cb.apply(this, arguments);
	        }
	      })
	    }
	  }

	  var fs$readdir = fs.readdir;
	  fs.readdir = readdir;
	  var noReaddirOptionVersions = /^v[0-5]\./;
	  function readdir (path, options, cb) {
	    if (typeof options === 'function')
	      cb = options, options = null;

	    var go$readdir = noReaddirOptionVersions.test(process.version)
	      ? function go$readdir (path, options, cb, startTime) {
	        return fs$readdir(path, fs$readdirCallback(
	          path, options, cb, startTime
	        ))
	      }
	      : function go$readdir (path, options, cb, startTime) {
	        return fs$readdir(path, options, fs$readdirCallback(
	          path, options, cb, startTime
	        ))
	      };

	    return go$readdir(path, options, cb)

	    function fs$readdirCallback (path, options, cb, startTime) {
	      return function (err, files) {
	        if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
	          enqueue([
	            go$readdir,
	            [path, options, cb],
	            err,
	            startTime || Date.now(),
	            Date.now()
	          ]);
	        else {
	          if (files && files.sort)
	            files.sort();

	          if (typeof cb === 'function')
	            cb.call(this, err, files);
	        }
	      }
	    }
	  }

	  if (process.version.substr(0, 4) === 'v0.8') {
	    var legStreams = legacy(fs);
	    ReadStream = legStreams.ReadStream;
	    WriteStream = legStreams.WriteStream;
	  }

	  var fs$ReadStream = fs.ReadStream;
	  if (fs$ReadStream) {
	    ReadStream.prototype = Object.create(fs$ReadStream.prototype);
	    ReadStream.prototype.open = ReadStream$open;
	  }

	  var fs$WriteStream = fs.WriteStream;
	  if (fs$WriteStream) {
	    WriteStream.prototype = Object.create(fs$WriteStream.prototype);
	    WriteStream.prototype.open = WriteStream$open;
	  }

	  Object.defineProperty(fs, 'ReadStream', {
	    get: function () {
	      return ReadStream
	    },
	    set: function (val) {
	      ReadStream = val;
	    },
	    enumerable: true,
	    configurable: true
	  });
	  Object.defineProperty(fs, 'WriteStream', {
	    get: function () {
	      return WriteStream
	    },
	    set: function (val) {
	      WriteStream = val;
	    },
	    enumerable: true,
	    configurable: true
	  });

	  // legacy names
	  var FileReadStream = ReadStream;
	  Object.defineProperty(fs, 'FileReadStream', {
	    get: function () {
	      return FileReadStream
	    },
	    set: function (val) {
	      FileReadStream = val;
	    },
	    enumerable: true,
	    configurable: true
	  });
	  var FileWriteStream = WriteStream;
	  Object.defineProperty(fs, 'FileWriteStream', {
	    get: function () {
	      return FileWriteStream
	    },
	    set: function (val) {
	      FileWriteStream = val;
	    },
	    enumerable: true,
	    configurable: true
	  });

	  function ReadStream (path, options) {
	    if (this instanceof ReadStream)
	      return fs$ReadStream.apply(this, arguments), this
	    else
	      return ReadStream.apply(Object.create(ReadStream.prototype), arguments)
	  }

	  function ReadStream$open () {
	    var that = this;
	    open(that.path, that.flags, that.mode, function (err, fd) {
	      if (err) {
	        if (that.autoClose)
	          that.destroy();

	        that.emit('error', err);
	      } else {
	        that.fd = fd;
	        that.emit('open', fd);
	        that.read();
	      }
	    });
	  }

	  function WriteStream (path, options) {
	    if (this instanceof WriteStream)
	      return fs$WriteStream.apply(this, arguments), this
	    else
	      return WriteStream.apply(Object.create(WriteStream.prototype), arguments)
	  }

	  function WriteStream$open () {
	    var that = this;
	    open(that.path, that.flags, that.mode, function (err, fd) {
	      if (err) {
	        that.destroy();
	        that.emit('error', err);
	      } else {
	        that.fd = fd;
	        that.emit('open', fd);
	      }
	    });
	  }

	  function createReadStream (path, options) {
	    return new fs.ReadStream(path, options)
	  }

	  function createWriteStream (path, options) {
	    return new fs.WriteStream(path, options)
	  }

	  var fs$open = fs.open;
	  fs.open = open;
	  function open (path, flags, mode, cb) {
	    if (typeof mode === 'function')
	      cb = mode, mode = null;

	    return go$open(path, flags, mode, cb)

	    function go$open (path, flags, mode, cb, startTime) {
	      return fs$open(path, flags, mode, function (err, fd) {
	        if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
	          enqueue([go$open, [path, flags, mode, cb], err, startTime || Date.now(), Date.now()]);
	        else {
	          if (typeof cb === 'function')
	            cb.apply(this, arguments);
	        }
	      })
	    }
	  }

	  return fs
	}

	function enqueue (elem) {
	  debug('ENQUEUE', elem[0].name, elem[1]);
	  fs[gracefulQueue].push(elem);
	  retry();
	}

	// keep track of the timeout between retry() calls
	var retryTimer;

	// reset the startTime and lastTime to now
	// this resets the start of the 60 second overall timeout as well as the
	// delay between attempts so that we'll retry these jobs sooner
	function resetQueue () {
	  var now = Date.now();
	  for (var i = 0; i < fs[gracefulQueue].length; ++i) {
	    // entries that are only a length of 2 are from an older version, don't
	    // bother modifying those since they'll be retried anyway.
	    if (fs[gracefulQueue][i].length > 2) {
	      fs[gracefulQueue][i][3] = now; // startTime
	      fs[gracefulQueue][i][4] = now; // lastTime
	    }
	  }
	  // call retry to make sure we're actively processing the queue
	  retry();
	}

	function retry () {
	  // clear the timer and remove it to help prevent unintended concurrency
	  clearTimeout(retryTimer);
	  retryTimer = undefined;

	  if (fs[gracefulQueue].length === 0)
	    return

	  var elem = fs[gracefulQueue].shift();
	  var fn = elem[0];
	  var args = elem[1];
	  // these items may be unset if they were added by an older graceful-fs
	  var err = elem[2];
	  var startTime = elem[3];
	  var lastTime = elem[4];

	  // if we don't have a startTime we have no way of knowing if we've waited
	  // long enough, so go ahead and retry this item now
	  if (startTime === undefined) {
	    debug('RETRY', fn.name, args);
	    fn.apply(null, args);
	  } else if (Date.now() - startTime >= 60000) {
	    // it's been more than 60 seconds total, bail now
	    debug('TIMEOUT', fn.name, args);
	    var cb = args.pop();
	    if (typeof cb === 'function')
	      cb.call(null, err);
	  } else {
	    // the amount of time between the last attempt and right now
	    var sinceAttempt = Date.now() - lastTime;
	    // the amount of time between when we first tried, and when we last tried
	    // rounded up to at least 1
	    var sinceStart = Math.max(lastTime - startTime, 1);
	    // backoff. wait longer than the total time we've been retrying, but only
	    // up to a maximum of 100ms
	    var desiredDelay = Math.min(sinceStart * 1.2, 100);
	    // it's been long enough since the last retry, do it again
	    if (sinceAttempt >= desiredDelay) {
	      debug('RETRY', fn.name, args);
	      fn.apply(null, args.concat([startTime]));
	    } else {
	      // if we can't do this job yet, push it to the end of the queue
	      // and let the next iteration check again
	      fs[gracefulQueue].push(elem);
	    }
	  }

	  // schedule our next run if one isn't already scheduled
	  if (retryTimer === undefined) {
	    retryTimer = setTimeout(retry, 0);
	  }
	}
	return gracefulFs;
}

var readable$1 = {exports: {}};

var processNextickArgs = {exports: {}};

var hasRequiredProcessNextickArgs;

function requireProcessNextickArgs () {
	if (hasRequiredProcessNextickArgs) return processNextickArgs.exports;
	hasRequiredProcessNextickArgs = 1;

	if (typeof process === 'undefined' ||
	    !process.version ||
	    process.version.indexOf('v0.') === 0 ||
	    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
	  processNextickArgs.exports = { nextTick: nextTick };
	} else {
	  processNextickArgs.exports = process;
	}

	function nextTick(fn, arg1, arg2, arg3) {
	  if (typeof fn !== 'function') {
	    throw new TypeError('"callback" argument must be a function');
	  }
	  var len = arguments.length;
	  var args, i;
	  switch (len) {
	  case 0:
	  case 1:
	    return process.nextTick(fn);
	  case 2:
	    return process.nextTick(function afterTickOne() {
	      fn.call(null, arg1);
	    });
	  case 3:
	    return process.nextTick(function afterTickTwo() {
	      fn.call(null, arg1, arg2);
	    });
	  case 4:
	    return process.nextTick(function afterTickThree() {
	      fn.call(null, arg1, arg2, arg3);
	    });
	  default:
	    args = new Array(len - 1);
	    i = 0;
	    while (i < args.length) {
	      args[i++] = arguments[i];
	    }
	    return process.nextTick(function afterTick() {
	      fn.apply(null, args);
	    });
	  }
	}
	return processNextickArgs.exports;
}

var isarray;
var hasRequiredIsarray;

function requireIsarray () {
	if (hasRequiredIsarray) return isarray;
	hasRequiredIsarray = 1;
	var toString = {}.toString;

	isarray = Array.isArray || function (arr) {
	  return toString.call(arr) == '[object Array]';
	};
	return isarray;
}

var stream$1;
var hasRequiredStream$1;

function requireStream$1 () {
	if (hasRequiredStream$1) return stream$1;
	hasRequiredStream$1 = 1;
	stream$1 = require$$0$4;
	return stream$1;
}

var safeBuffer$1 = {exports: {}};

/* eslint-disable node/no-deprecated-api */

var hasRequiredSafeBuffer$1;

function requireSafeBuffer$1 () {
	if (hasRequiredSafeBuffer$1) return safeBuffer$1.exports;
	hasRequiredSafeBuffer$1 = 1;
	(function (module, exports) {
		var buffer = require$$0$6;
		var Buffer = buffer.Buffer;

		// alternative to using Object.keys for old browsers
		function copyProps (src, dst) {
		  for (var key in src) {
		    dst[key] = src[key];
		  }
		}
		if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
		  module.exports = buffer;
		} else {
		  // Copy properties from require('buffer')
		  copyProps(buffer, exports);
		  exports.Buffer = SafeBuffer;
		}

		function SafeBuffer (arg, encodingOrOffset, length) {
		  return Buffer(arg, encodingOrOffset, length)
		}

		// Copy static methods from Buffer
		copyProps(Buffer, SafeBuffer);

		SafeBuffer.from = function (arg, encodingOrOffset, length) {
		  if (typeof arg === 'number') {
		    throw new TypeError('Argument must not be a number')
		  }
		  return Buffer(arg, encodingOrOffset, length)
		};

		SafeBuffer.alloc = function (size, fill, encoding) {
		  if (typeof size !== 'number') {
		    throw new TypeError('Argument must be a number')
		  }
		  var buf = Buffer(size);
		  if (fill !== undefined) {
		    if (typeof encoding === 'string') {
		      buf.fill(fill, encoding);
		    } else {
		      buf.fill(fill);
		    }
		  } else {
		    buf.fill(0);
		  }
		  return buf
		};

		SafeBuffer.allocUnsafe = function (size) {
		  if (typeof size !== 'number') {
		    throw new TypeError('Argument must be a number')
		  }
		  return Buffer(size)
		};

		SafeBuffer.allocUnsafeSlow = function (size) {
		  if (typeof size !== 'number') {
		    throw new TypeError('Argument must be a number')
		  }
		  return buffer.SlowBuffer(size)
		}; 
	} (safeBuffer$1, safeBuffer$1.exports));
	return safeBuffer$1.exports;
}

var util$2 = {};

var hasRequiredUtil$2;

function requireUtil$2 () {
	if (hasRequiredUtil$2) return util$2;
	hasRequiredUtil$2 = 1;
	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	// NOTE: These type checking functions intentionally don't use `instanceof`
	// because it is fragile and can be easily faked with `Object.create()`.

	function isArray(arg) {
	  if (Array.isArray) {
	    return Array.isArray(arg);
	  }
	  return objectToString(arg) === '[object Array]';
	}
	util$2.isArray = isArray;

	function isBoolean(arg) {
	  return typeof arg === 'boolean';
	}
	util$2.isBoolean = isBoolean;

	function isNull(arg) {
	  return arg === null;
	}
	util$2.isNull = isNull;

	function isNullOrUndefined(arg) {
	  return arg == null;
	}
	util$2.isNullOrUndefined = isNullOrUndefined;

	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	util$2.isNumber = isNumber;

	function isString(arg) {
	  return typeof arg === 'string';
	}
	util$2.isString = isString;

	function isSymbol(arg) {
	  return typeof arg === 'symbol';
	}
	util$2.isSymbol = isSymbol;

	function isUndefined(arg) {
	  return arg === void 0;
	}
	util$2.isUndefined = isUndefined;

	function isRegExp(re) {
	  return objectToString(re) === '[object RegExp]';
	}
	util$2.isRegExp = isRegExp;

	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	util$2.isObject = isObject;

	function isDate(d) {
	  return objectToString(d) === '[object Date]';
	}
	util$2.isDate = isDate;

	function isError(e) {
	  return (objectToString(e) === '[object Error]' || e instanceof Error);
	}
	util$2.isError = isError;

	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	util$2.isFunction = isFunction;

	function isPrimitive(arg) {
	  return arg === null ||
	         typeof arg === 'boolean' ||
	         typeof arg === 'number' ||
	         typeof arg === 'string' ||
	         typeof arg === 'symbol' ||  // ES6 symbol
	         typeof arg === 'undefined';
	}
	util$2.isPrimitive = isPrimitive;

	util$2.isBuffer = require$$0$6.Buffer.isBuffer;

	function objectToString(o) {
	  return Object.prototype.toString.call(o);
	}
	return util$2;
}

var inherits = {exports: {}};

var inherits_browser = {exports: {}};

var hasRequiredInherits_browser;

function requireInherits_browser () {
	if (hasRequiredInherits_browser) return inherits_browser.exports;
	hasRequiredInherits_browser = 1;
	if (typeof Object.create === 'function') {
	  // implementation from standard node.js 'util' module
	  inherits_browser.exports = function inherits(ctor, superCtor) {
	    if (superCtor) {
	      ctor.super_ = superCtor;
	      ctor.prototype = Object.create(superCtor.prototype, {
	        constructor: {
	          value: ctor,
	          enumerable: false,
	          writable: true,
	          configurable: true
	        }
	      });
	    }
	  };
	} else {
	  // old school shim for old browsers
	  inherits_browser.exports = function inherits(ctor, superCtor) {
	    if (superCtor) {
	      ctor.super_ = superCtor;
	      var TempCtor = function () {};
	      TempCtor.prototype = superCtor.prototype;
	      ctor.prototype = new TempCtor();
	      ctor.prototype.constructor = ctor;
	    }
	  };
	}
	return inherits_browser.exports;
}

var hasRequiredInherits;

function requireInherits () {
	if (hasRequiredInherits) return inherits.exports;
	hasRequiredInherits = 1;
	try {
	  var util = require('util');
	  /* istanbul ignore next */
	  if (typeof util.inherits !== 'function') throw '';
	  inherits.exports = util.inherits;
	} catch (e) {
	  /* istanbul ignore next */
	  inherits.exports = requireInherits_browser();
	}
	return inherits.exports;
}

var BufferList = {exports: {}};

var hasRequiredBufferList;

function requireBufferList () {
	if (hasRequiredBufferList) return BufferList.exports;
	hasRequiredBufferList = 1;
	(function (module) {

		function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

		var Buffer = requireSafeBuffer$1().Buffer;
		var util = require$$0$5;

		function copyBuffer(src, target, offset) {
		  src.copy(target, offset);
		}

		module.exports = function () {
		  function BufferList() {
		    _classCallCheck(this, BufferList);

		    this.head = null;
		    this.tail = null;
		    this.length = 0;
		  }

		  BufferList.prototype.push = function push(v) {
		    var entry = { data: v, next: null };
		    if (this.length > 0) this.tail.next = entry;else this.head = entry;
		    this.tail = entry;
		    ++this.length;
		  };

		  BufferList.prototype.unshift = function unshift(v) {
		    var entry = { data: v, next: this.head };
		    if (this.length === 0) this.tail = entry;
		    this.head = entry;
		    ++this.length;
		  };

		  BufferList.prototype.shift = function shift() {
		    if (this.length === 0) return;
		    var ret = this.head.data;
		    if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
		    --this.length;
		    return ret;
		  };

		  BufferList.prototype.clear = function clear() {
		    this.head = this.tail = null;
		    this.length = 0;
		  };

		  BufferList.prototype.join = function join(s) {
		    if (this.length === 0) return '';
		    var p = this.head;
		    var ret = '' + p.data;
		    while (p = p.next) {
		      ret += s + p.data;
		    }return ret;
		  };

		  BufferList.prototype.concat = function concat(n) {
		    if (this.length === 0) return Buffer.alloc(0);
		    var ret = Buffer.allocUnsafe(n >>> 0);
		    var p = this.head;
		    var i = 0;
		    while (p) {
		      copyBuffer(p.data, ret, i);
		      i += p.data.length;
		      p = p.next;
		    }
		    return ret;
		  };

		  return BufferList;
		}();

		if (util && util.inspect && util.inspect.custom) {
		  module.exports.prototype[util.inspect.custom] = function () {
		    var obj = util.inspect({ length: this.length });
		    return this.constructor.name + ' ' + obj;
		  };
		} 
	} (BufferList));
	return BufferList.exports;
}

var destroy_1$1;
var hasRequiredDestroy$1;

function requireDestroy$1 () {
	if (hasRequiredDestroy$1) return destroy_1$1;
	hasRequiredDestroy$1 = 1;

	/*<replacement>*/

	var pna = requireProcessNextickArgs();
	/*</replacement>*/

	// undocumented cb() API, needed for core, not for public API
	function destroy(err, cb) {
	  var _this = this;

	  var readableDestroyed = this._readableState && this._readableState.destroyed;
	  var writableDestroyed = this._writableState && this._writableState.destroyed;

	  if (readableDestroyed || writableDestroyed) {
	    if (cb) {
	      cb(err);
	    } else if (err) {
	      if (!this._writableState) {
	        pna.nextTick(emitErrorNT, this, err);
	      } else if (!this._writableState.errorEmitted) {
	        this._writableState.errorEmitted = true;
	        pna.nextTick(emitErrorNT, this, err);
	      }
	    }

	    return this;
	  }

	  // we set destroyed to true before firing error callbacks in order
	  // to make it re-entrance safe in case destroy() is called within callbacks

	  if (this._readableState) {
	    this._readableState.destroyed = true;
	  }

	  // if this is a duplex stream mark the writable part as destroyed as well
	  if (this._writableState) {
	    this._writableState.destroyed = true;
	  }

	  this._destroy(err || null, function (err) {
	    if (!cb && err) {
	      if (!_this._writableState) {
	        pna.nextTick(emitErrorNT, _this, err);
	      } else if (!_this._writableState.errorEmitted) {
	        _this._writableState.errorEmitted = true;
	        pna.nextTick(emitErrorNT, _this, err);
	      }
	    } else if (cb) {
	      cb(err);
	    }
	  });

	  return this;
	}

	function undestroy() {
	  if (this._readableState) {
	    this._readableState.destroyed = false;
	    this._readableState.reading = false;
	    this._readableState.ended = false;
	    this._readableState.endEmitted = false;
	  }

	  if (this._writableState) {
	    this._writableState.destroyed = false;
	    this._writableState.ended = false;
	    this._writableState.ending = false;
	    this._writableState.finalCalled = false;
	    this._writableState.prefinished = false;
	    this._writableState.finished = false;
	    this._writableState.errorEmitted = false;
	  }
	}

	function emitErrorNT(self, err) {
	  self.emit('error', err);
	}

	destroy_1$1 = {
	  destroy: destroy,
	  undestroy: undestroy
	};
	return destroy_1$1;
}

var node;
var hasRequiredNode;

function requireNode () {
	if (hasRequiredNode) return node;
	hasRequiredNode = 1;
	/**
	 * For Node.js, simply re-export the core `util.deprecate` function.
	 */

	node = require$$0$5.deprecate;
	return node;
}

var _stream_writable$1;
var hasRequired_stream_writable$1;

function require_stream_writable$1 () {
	if (hasRequired_stream_writable$1) return _stream_writable$1;
	hasRequired_stream_writable$1 = 1;

	/*<replacement>*/

	var pna = requireProcessNextickArgs();
	/*</replacement>*/

	_stream_writable$1 = Writable;

	// It seems a linked list but it is not
	// there will be only 2 of these for each stream
	function CorkedRequest(state) {
	  var _this = this;

	  this.next = null;
	  this.entry = null;
	  this.finish = function () {
	    onCorkedFinish(_this, state);
	  };
	}
	/* </replacement> */

	/*<replacement>*/
	var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
	/*</replacement>*/

	/*<replacement>*/
	var Duplex;
	/*</replacement>*/

	Writable.WritableState = WritableState;

	/*<replacement>*/
	var util = Object.create(requireUtil$2());
	util.inherits = requireInherits();
	/*</replacement>*/

	/*<replacement>*/
	var internalUtil = {
	  deprecate: requireNode()
	};
	/*</replacement>*/

	/*<replacement>*/
	var Stream = requireStream$1();
	/*</replacement>*/

	/*<replacement>*/

	var Buffer = requireSafeBuffer$1().Buffer;
	var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
	function _uint8ArrayToBuffer(chunk) {
	  return Buffer.from(chunk);
	}
	function _isUint8Array(obj) {
	  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
	}

	/*</replacement>*/

	var destroyImpl = requireDestroy$1();

	util.inherits(Writable, Stream);

	function nop() {}

	function WritableState(options, stream) {
	  Duplex = Duplex || require_stream_duplex$1();

	  options = options || {};

	  // Duplex streams are both readable and writable, but share
	  // the same options object.
	  // However, some cases require setting options to different
	  // values for the readable and the writable sides of the duplex stream.
	  // These options can be provided separately as readableXXX and writableXXX.
	  var isDuplex = stream instanceof Duplex;

	  // object stream flag to indicate whether or not this stream
	  // contains buffers or objects.
	  this.objectMode = !!options.objectMode;

	  if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;

	  // the point at which write() starts returning false
	  // Note: 0 is a valid value, means that we always return false if
	  // the entire buffer is not flushed immediately on write()
	  var hwm = options.highWaterMark;
	  var writableHwm = options.writableHighWaterMark;
	  var defaultHwm = this.objectMode ? 16 : 16 * 1024;

	  if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm;

	  // cast to ints.
	  this.highWaterMark = Math.floor(this.highWaterMark);

	  // if _final has been called
	  this.finalCalled = false;

	  // drain event flag.
	  this.needDrain = false;
	  // at the start of calling end()
	  this.ending = false;
	  // when end() has been called, and returned
	  this.ended = false;
	  // when 'finish' is emitted
	  this.finished = false;

	  // has it been destroyed
	  this.destroyed = false;

	  // should we decode strings into buffers before passing to _write?
	  // this is here so that some node-core streams can optimize string
	  // handling at a lower level.
	  var noDecode = options.decodeStrings === false;
	  this.decodeStrings = !noDecode;

	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';

	  // not an actual buffer we keep track of, but a measurement
	  // of how much we're waiting to get pushed to some underlying
	  // socket or file.
	  this.length = 0;

	  // a flag to see when we're in the middle of a write.
	  this.writing = false;

	  // when true all writes will be buffered until .uncork() call
	  this.corked = 0;

	  // a flag to be able to tell if the onwrite cb is called immediately,
	  // or on a later tick.  We set this to true at first, because any
	  // actions that shouldn't happen until "later" should generally also
	  // not happen before the first write call.
	  this.sync = true;

	  // a flag to know if we're processing previously buffered items, which
	  // may call the _write() callback in the same tick, so that we don't
	  // end up in an overlapped onwrite situation.
	  this.bufferProcessing = false;

	  // the callback that's passed to _write(chunk,cb)
	  this.onwrite = function (er) {
	    onwrite(stream, er);
	  };

	  // the callback that the user supplies to write(chunk,encoding,cb)
	  this.writecb = null;

	  // the amount that is being written when _write is called.
	  this.writelen = 0;

	  this.bufferedRequest = null;
	  this.lastBufferedRequest = null;

	  // number of pending user-supplied write callbacks
	  // this must be 0 before 'finish' can be emitted
	  this.pendingcb = 0;

	  // emit prefinish if the only thing we're waiting for is _write cbs
	  // This is relevant for synchronous Transform streams
	  this.prefinished = false;

	  // True if the error was already emitted and should not be thrown again
	  this.errorEmitted = false;

	  // count buffered requests
	  this.bufferedRequestCount = 0;

	  // allocate the first CorkedRequest, there is always
	  // one allocated and free to use, and we maintain at most two
	  this.corkedRequestsFree = new CorkedRequest(this);
	}

	WritableState.prototype.getBuffer = function getBuffer() {
	  var current = this.bufferedRequest;
	  var out = [];
	  while (current) {
	    out.push(current);
	    current = current.next;
	  }
	  return out;
	};

	(function () {
	  try {
	    Object.defineProperty(WritableState.prototype, 'buffer', {
	      get: internalUtil.deprecate(function () {
	        return this.getBuffer();
	      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
	    });
	  } catch (_) {}
	})();

	// Test _writableState for inheritance to account for Duplex streams,
	// whose prototype chain only points to Readable.
	var realHasInstance;
	if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
	  realHasInstance = Function.prototype[Symbol.hasInstance];
	  Object.defineProperty(Writable, Symbol.hasInstance, {
	    value: function (object) {
	      if (realHasInstance.call(this, object)) return true;
	      if (this !== Writable) return false;

	      return object && object._writableState instanceof WritableState;
	    }
	  });
	} else {
	  realHasInstance = function (object) {
	    return object instanceof this;
	  };
	}

	function Writable(options) {
	  Duplex = Duplex || require_stream_duplex$1();

	  // Writable ctor is applied to Duplexes, too.
	  // `realHasInstance` is necessary because using plain `instanceof`
	  // would return false, as no `_writableState` property is attached.

	  // Trying to use the custom `instanceof` for Writable here will also break the
	  // Node.js LazyTransform implementation, which has a non-trivial getter for
	  // `_writableState` that would lead to infinite recursion.
	  if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
	    return new Writable(options);
	  }

	  this._writableState = new WritableState(options, this);

	  // legacy.
	  this.writable = true;

	  if (options) {
	    if (typeof options.write === 'function') this._write = options.write;

	    if (typeof options.writev === 'function') this._writev = options.writev;

	    if (typeof options.destroy === 'function') this._destroy = options.destroy;

	    if (typeof options.final === 'function') this._final = options.final;
	  }

	  Stream.call(this);
	}

	// Otherwise people can pipe Writable streams, which is just wrong.
	Writable.prototype.pipe = function () {
	  this.emit('error', new Error('Cannot pipe, not readable'));
	};

	function writeAfterEnd(stream, cb) {
	  var er = new Error('write after end');
	  // TODO: defer error events consistently everywhere, not just the cb
	  stream.emit('error', er);
	  pna.nextTick(cb, er);
	}

	// Checks that a user-supplied chunk is valid, especially for the particular
	// mode the stream is in. Currently this means that `null` is never accepted
	// and undefined/non-string values are only allowed in object mode.
	function validChunk(stream, state, chunk, cb) {
	  var valid = true;
	  var er = false;

	  if (chunk === null) {
	    er = new TypeError('May not write null values to stream');
	  } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
	    er = new TypeError('Invalid non-string/buffer chunk');
	  }
	  if (er) {
	    stream.emit('error', er);
	    pna.nextTick(cb, er);
	    valid = false;
	  }
	  return valid;
	}

	Writable.prototype.write = function (chunk, encoding, cb) {
	  var state = this._writableState;
	  var ret = false;
	  var isBuf = !state.objectMode && _isUint8Array(chunk);

	  if (isBuf && !Buffer.isBuffer(chunk)) {
	    chunk = _uint8ArrayToBuffer(chunk);
	  }

	  if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }

	  if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;

	  if (typeof cb !== 'function') cb = nop;

	  if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
	    state.pendingcb++;
	    ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
	  }

	  return ret;
	};

	Writable.prototype.cork = function () {
	  var state = this._writableState;

	  state.corked++;
	};

	Writable.prototype.uncork = function () {
	  var state = this._writableState;

	  if (state.corked) {
	    state.corked--;

	    if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
	  }
	};

	Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
	  // node::ParseEncoding() requires lower case.
	  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
	  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
	  this._writableState.defaultEncoding = encoding;
	  return this;
	};

	function decodeChunk(state, chunk, encoding) {
	  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
	    chunk = Buffer.from(chunk, encoding);
	  }
	  return chunk;
	}

	Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function () {
	    return this._writableState.highWaterMark;
	  }
	});

	// if we're already writing something, then just put this
	// in the queue, and wait our turn.  Otherwise, call _write
	// If we return false, then we need a drain event, so set that flag.
	function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
	  if (!isBuf) {
	    var newChunk = decodeChunk(state, chunk, encoding);
	    if (chunk !== newChunk) {
	      isBuf = true;
	      encoding = 'buffer';
	      chunk = newChunk;
	    }
	  }
	  var len = state.objectMode ? 1 : chunk.length;

	  state.length += len;

	  var ret = state.length < state.highWaterMark;
	  // we must ensure that previous needDrain will not be reset to false.
	  if (!ret) state.needDrain = true;

	  if (state.writing || state.corked) {
	    var last = state.lastBufferedRequest;
	    state.lastBufferedRequest = {
	      chunk: chunk,
	      encoding: encoding,
	      isBuf: isBuf,
	      callback: cb,
	      next: null
	    };
	    if (last) {
	      last.next = state.lastBufferedRequest;
	    } else {
	      state.bufferedRequest = state.lastBufferedRequest;
	    }
	    state.bufferedRequestCount += 1;
	  } else {
	    doWrite(stream, state, false, len, chunk, encoding, cb);
	  }

	  return ret;
	}

	function doWrite(stream, state, writev, len, chunk, encoding, cb) {
	  state.writelen = len;
	  state.writecb = cb;
	  state.writing = true;
	  state.sync = true;
	  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
	  state.sync = false;
	}

	function onwriteError(stream, state, sync, er, cb) {
	  --state.pendingcb;

	  if (sync) {
	    // defer the callback if we are being called synchronously
	    // to avoid piling up things on the stack
	    pna.nextTick(cb, er);
	    // this can emit finish, and it will always happen
	    // after error
	    pna.nextTick(finishMaybe, stream, state);
	    stream._writableState.errorEmitted = true;
	    stream.emit('error', er);
	  } else {
	    // the caller expect this to happen before if
	    // it is async
	    cb(er);
	    stream._writableState.errorEmitted = true;
	    stream.emit('error', er);
	    // this can emit finish, but finish must
	    // always follow error
	    finishMaybe(stream, state);
	  }
	}

	function onwriteStateUpdate(state) {
	  state.writing = false;
	  state.writecb = null;
	  state.length -= state.writelen;
	  state.writelen = 0;
	}

	function onwrite(stream, er) {
	  var state = stream._writableState;
	  var sync = state.sync;
	  var cb = state.writecb;

	  onwriteStateUpdate(state);

	  if (er) onwriteError(stream, state, sync, er, cb);else {
	    // Check if we're actually ready to finish, but don't emit yet
	    var finished = needFinish(state);

	    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
	      clearBuffer(stream, state);
	    }

	    if (sync) {
	      /*<replacement>*/
	      asyncWrite(afterWrite, stream, state, finished, cb);
	      /*</replacement>*/
	    } else {
	      afterWrite(stream, state, finished, cb);
	    }
	  }
	}

	function afterWrite(stream, state, finished, cb) {
	  if (!finished) onwriteDrain(stream, state);
	  state.pendingcb--;
	  cb();
	  finishMaybe(stream, state);
	}

	// Must force callback to be called on nextTick, so that we don't
	// emit 'drain' before the write() consumer gets the 'false' return
	// value, and has a chance to attach a 'drain' listener.
	function onwriteDrain(stream, state) {
	  if (state.length === 0 && state.needDrain) {
	    state.needDrain = false;
	    stream.emit('drain');
	  }
	}

	// if there's something in the buffer waiting, then process it
	function clearBuffer(stream, state) {
	  state.bufferProcessing = true;
	  var entry = state.bufferedRequest;

	  if (stream._writev && entry && entry.next) {
	    // Fast case, write everything using _writev()
	    var l = state.bufferedRequestCount;
	    var buffer = new Array(l);
	    var holder = state.corkedRequestsFree;
	    holder.entry = entry;

	    var count = 0;
	    var allBuffers = true;
	    while (entry) {
	      buffer[count] = entry;
	      if (!entry.isBuf) allBuffers = false;
	      entry = entry.next;
	      count += 1;
	    }
	    buffer.allBuffers = allBuffers;

	    doWrite(stream, state, true, state.length, buffer, '', holder.finish);

	    // doWrite is almost always async, defer these to save a bit of time
	    // as the hot path ends with doWrite
	    state.pendingcb++;
	    state.lastBufferedRequest = null;
	    if (holder.next) {
	      state.corkedRequestsFree = holder.next;
	      holder.next = null;
	    } else {
	      state.corkedRequestsFree = new CorkedRequest(state);
	    }
	    state.bufferedRequestCount = 0;
	  } else {
	    // Slow case, write chunks one-by-one
	    while (entry) {
	      var chunk = entry.chunk;
	      var encoding = entry.encoding;
	      var cb = entry.callback;
	      var len = state.objectMode ? 1 : chunk.length;

	      doWrite(stream, state, false, len, chunk, encoding, cb);
	      entry = entry.next;
	      state.bufferedRequestCount--;
	      // if we didn't call the onwrite immediately, then
	      // it means that we need to wait until it does.
	      // also, that means that the chunk and cb are currently
	      // being processed, so move the buffer counter past them.
	      if (state.writing) {
	        break;
	      }
	    }

	    if (entry === null) state.lastBufferedRequest = null;
	  }

	  state.bufferedRequest = entry;
	  state.bufferProcessing = false;
	}

	Writable.prototype._write = function (chunk, encoding, cb) {
	  cb(new Error('_write() is not implemented'));
	};

	Writable.prototype._writev = null;

	Writable.prototype.end = function (chunk, encoding, cb) {
	  var state = this._writableState;

	  if (typeof chunk === 'function') {
	    cb = chunk;
	    chunk = null;
	    encoding = null;
	  } else if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }

	  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);

	  // .end() fully uncorks
	  if (state.corked) {
	    state.corked = 1;
	    this.uncork();
	  }

	  // ignore unnecessary end() calls.
	  if (!state.ending) endWritable(this, state, cb);
	};

	function needFinish(state) {
	  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
	}
	function callFinal(stream, state) {
	  stream._final(function (err) {
	    state.pendingcb--;
	    if (err) {
	      stream.emit('error', err);
	    }
	    state.prefinished = true;
	    stream.emit('prefinish');
	    finishMaybe(stream, state);
	  });
	}
	function prefinish(stream, state) {
	  if (!state.prefinished && !state.finalCalled) {
	    if (typeof stream._final === 'function') {
	      state.pendingcb++;
	      state.finalCalled = true;
	      pna.nextTick(callFinal, stream, state);
	    } else {
	      state.prefinished = true;
	      stream.emit('prefinish');
	    }
	  }
	}

	function finishMaybe(stream, state) {
	  var need = needFinish(state);
	  if (need) {
	    prefinish(stream, state);
	    if (state.pendingcb === 0) {
	      state.finished = true;
	      stream.emit('finish');
	    }
	  }
	  return need;
	}

	function endWritable(stream, state, cb) {
	  state.ending = true;
	  finishMaybe(stream, state);
	  if (cb) {
	    if (state.finished) pna.nextTick(cb);else stream.once('finish', cb);
	  }
	  state.ended = true;
	  stream.writable = false;
	}

	function onCorkedFinish(corkReq, state, err) {
	  var entry = corkReq.entry;
	  corkReq.entry = null;
	  while (entry) {
	    var cb = entry.callback;
	    state.pendingcb--;
	    cb(err);
	    entry = entry.next;
	  }

	  // reuse the free corkReq.
	  state.corkedRequestsFree.next = corkReq;
	}

	Object.defineProperty(Writable.prototype, 'destroyed', {
	  get: function () {
	    if (this._writableState === undefined) {
	      return false;
	    }
	    return this._writableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (!this._writableState) {
	      return;
	    }

	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._writableState.destroyed = value;
	  }
	});

	Writable.prototype.destroy = destroyImpl.destroy;
	Writable.prototype._undestroy = destroyImpl.undestroy;
	Writable.prototype._destroy = function (err, cb) {
	  this.end();
	  cb(err);
	};
	return _stream_writable$1;
}

var _stream_duplex$1;
var hasRequired_stream_duplex$1;

function require_stream_duplex$1 () {
	if (hasRequired_stream_duplex$1) return _stream_duplex$1;
	hasRequired_stream_duplex$1 = 1;

	/*<replacement>*/

	var pna = requireProcessNextickArgs();
	/*</replacement>*/

	/*<replacement>*/
	var objectKeys = Object.keys || function (obj) {
	  var keys = [];
	  for (var key in obj) {
	    keys.push(key);
	  }return keys;
	};
	/*</replacement>*/

	_stream_duplex$1 = Duplex;

	/*<replacement>*/
	var util = Object.create(requireUtil$2());
	util.inherits = requireInherits();
	/*</replacement>*/

	var Readable = require_stream_readable$1();
	var Writable = require_stream_writable$1();

	util.inherits(Duplex, Readable);

	{
	  // avoid scope creep, the keys array can then be collected
	  var keys = objectKeys(Writable.prototype);
	  for (var v = 0; v < keys.length; v++) {
	    var method = keys[v];
	    if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
	  }
	}

	function Duplex(options) {
	  if (!(this instanceof Duplex)) return new Duplex(options);

	  Readable.call(this, options);
	  Writable.call(this, options);

	  if (options && options.readable === false) this.readable = false;

	  if (options && options.writable === false) this.writable = false;

	  this.allowHalfOpen = true;
	  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;

	  this.once('end', onend);
	}

	Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function () {
	    return this._writableState.highWaterMark;
	  }
	});

	// the no-half-open enforcer
	function onend() {
	  // if we allow half-open state, or if the writable side ended,
	  // then we're ok.
	  if (this.allowHalfOpen || this._writableState.ended) return;

	  // no more data can be written.
	  // But allow more writes to happen in this tick.
	  pna.nextTick(onEndNT, this);
	}

	function onEndNT(self) {
	  self.end();
	}

	Object.defineProperty(Duplex.prototype, 'destroyed', {
	  get: function () {
	    if (this._readableState === undefined || this._writableState === undefined) {
	      return false;
	    }
	    return this._readableState.destroyed && this._writableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (this._readableState === undefined || this._writableState === undefined) {
	      return;
	    }

	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._readableState.destroyed = value;
	    this._writableState.destroyed = value;
	  }
	});

	Duplex.prototype._destroy = function (err, cb) {
	  this.push(null);
	  this.end();

	  pna.nextTick(cb, err);
	};
	return _stream_duplex$1;
}

var string_decoder$1 = {};

var hasRequiredString_decoder$1;

function requireString_decoder$1 () {
	if (hasRequiredString_decoder$1) return string_decoder$1;
	hasRequiredString_decoder$1 = 1;

	/*<replacement>*/

	var Buffer = requireSafeBuffer$1().Buffer;
	/*</replacement>*/

	var isEncoding = Buffer.isEncoding || function (encoding) {
	  encoding = '' + encoding;
	  switch (encoding && encoding.toLowerCase()) {
	    case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
	      return true;
	    default:
	      return false;
	  }
	};

	function _normalizeEncoding(enc) {
	  if (!enc) return 'utf8';
	  var retried;
	  while (true) {
	    switch (enc) {
	      case 'utf8':
	      case 'utf-8':
	        return 'utf8';
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return 'utf16le';
	      case 'latin1':
	      case 'binary':
	        return 'latin1';
	      case 'base64':
	      case 'ascii':
	      case 'hex':
	        return enc;
	      default:
	        if (retried) return; // undefined
	        enc = ('' + enc).toLowerCase();
	        retried = true;
	    }
	  }
	}
	// Do not cache `Buffer.isEncoding` when checking encoding names as some
	// modules monkey-patch it to support additional encodings
	function normalizeEncoding(enc) {
	  var nenc = _normalizeEncoding(enc);
	  if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
	  return nenc || enc;
	}

	// StringDecoder provides an interface for efficiently splitting a series of
	// buffers into a series of JS strings without breaking apart multi-byte
	// characters.
	string_decoder$1.StringDecoder = StringDecoder;
	function StringDecoder(encoding) {
	  this.encoding = normalizeEncoding(encoding);
	  var nb;
	  switch (this.encoding) {
	    case 'utf16le':
	      this.text = utf16Text;
	      this.end = utf16End;
	      nb = 4;
	      break;
	    case 'utf8':
	      this.fillLast = utf8FillLast;
	      nb = 4;
	      break;
	    case 'base64':
	      this.text = base64Text;
	      this.end = base64End;
	      nb = 3;
	      break;
	    default:
	      this.write = simpleWrite;
	      this.end = simpleEnd;
	      return;
	  }
	  this.lastNeed = 0;
	  this.lastTotal = 0;
	  this.lastChar = Buffer.allocUnsafe(nb);
	}

	StringDecoder.prototype.write = function (buf) {
	  if (buf.length === 0) return '';
	  var r;
	  var i;
	  if (this.lastNeed) {
	    r = this.fillLast(buf);
	    if (r === undefined) return '';
	    i = this.lastNeed;
	    this.lastNeed = 0;
	  } else {
	    i = 0;
	  }
	  if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
	  return r || '';
	};

	StringDecoder.prototype.end = utf8End;

	// Returns only complete characters in a Buffer
	StringDecoder.prototype.text = utf8Text;

	// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
	StringDecoder.prototype.fillLast = function (buf) {
	  if (this.lastNeed <= buf.length) {
	    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
	    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
	  }
	  buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
	  this.lastNeed -= buf.length;
	};

	// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
	// continuation byte. If an invalid byte is detected, -2 is returned.
	function utf8CheckByte(byte) {
	  if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
	  return byte >> 6 === 0x02 ? -1 : -2;
	}

	// Checks at most 3 bytes at the end of a Buffer in order to detect an
	// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
	// needed to complete the UTF-8 character (if applicable) are returned.
	function utf8CheckIncomplete(self, buf, i) {
	  var j = buf.length - 1;
	  if (j < i) return 0;
	  var nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) self.lastNeed = nb - 1;
	    return nb;
	  }
	  if (--j < i || nb === -2) return 0;
	  nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) self.lastNeed = nb - 2;
	    return nb;
	  }
	  if (--j < i || nb === -2) return 0;
	  nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) {
	      if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
	    }
	    return nb;
	  }
	  return 0;
	}

	// Validates as many continuation bytes for a multi-byte UTF-8 character as
	// needed or are available. If we see a non-continuation byte where we expect
	// one, we "replace" the validated continuation bytes we've seen so far with
	// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
	// behavior. The continuation byte check is included three times in the case
	// where all of the continuation bytes for a character exist in the same buffer.
	// It is also done this way as a slight performance increase instead of using a
	// loop.
	function utf8CheckExtraBytes(self, buf, p) {
	  if ((buf[0] & 0xC0) !== 0x80) {
	    self.lastNeed = 0;
	    return '\ufffd';
	  }
	  if (self.lastNeed > 1 && buf.length > 1) {
	    if ((buf[1] & 0xC0) !== 0x80) {
	      self.lastNeed = 1;
	      return '\ufffd';
	    }
	    if (self.lastNeed > 2 && buf.length > 2) {
	      if ((buf[2] & 0xC0) !== 0x80) {
	        self.lastNeed = 2;
	        return '\ufffd';
	      }
	    }
	  }
	}

	// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
	function utf8FillLast(buf) {
	  var p = this.lastTotal - this.lastNeed;
	  var r = utf8CheckExtraBytes(this, buf);
	  if (r !== undefined) return r;
	  if (this.lastNeed <= buf.length) {
	    buf.copy(this.lastChar, p, 0, this.lastNeed);
	    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
	  }
	  buf.copy(this.lastChar, p, 0, buf.length);
	  this.lastNeed -= buf.length;
	}

	// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
	// partial character, the character's bytes are buffered until the required
	// number of bytes are available.
	function utf8Text(buf, i) {
	  var total = utf8CheckIncomplete(this, buf, i);
	  if (!this.lastNeed) return buf.toString('utf8', i);
	  this.lastTotal = total;
	  var end = buf.length - (total - this.lastNeed);
	  buf.copy(this.lastChar, 0, end);
	  return buf.toString('utf8', i, end);
	}

	// For UTF-8, a replacement character is added when ending on a partial
	// character.
	function utf8End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) return r + '\ufffd';
	  return r;
	}

	// UTF-16LE typically needs two bytes per character, but even if we have an even
	// number of bytes available, we need to check if we end on a leading/high
	// surrogate. In that case, we need to wait for the next two bytes in order to
	// decode the last character properly.
	function utf16Text(buf, i) {
	  if ((buf.length - i) % 2 === 0) {
	    var r = buf.toString('utf16le', i);
	    if (r) {
	      var c = r.charCodeAt(r.length - 1);
	      if (c >= 0xD800 && c <= 0xDBFF) {
	        this.lastNeed = 2;
	        this.lastTotal = 4;
	        this.lastChar[0] = buf[buf.length - 2];
	        this.lastChar[1] = buf[buf.length - 1];
	        return r.slice(0, -1);
	      }
	    }
	    return r;
	  }
	  this.lastNeed = 1;
	  this.lastTotal = 2;
	  this.lastChar[0] = buf[buf.length - 1];
	  return buf.toString('utf16le', i, buf.length - 1);
	}

	// For UTF-16LE we do not explicitly append special replacement characters if we
	// end on a partial character, we simply let v8 handle that.
	function utf16End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) {
	    var end = this.lastTotal - this.lastNeed;
	    return r + this.lastChar.toString('utf16le', 0, end);
	  }
	  return r;
	}

	function base64Text(buf, i) {
	  var n = (buf.length - i) % 3;
	  if (n === 0) return buf.toString('base64', i);
	  this.lastNeed = 3 - n;
	  this.lastTotal = 3;
	  if (n === 1) {
	    this.lastChar[0] = buf[buf.length - 1];
	  } else {
	    this.lastChar[0] = buf[buf.length - 2];
	    this.lastChar[1] = buf[buf.length - 1];
	  }
	  return buf.toString('base64', i, buf.length - n);
	}

	function base64End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
	  return r;
	}

	// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
	function simpleWrite(buf) {
	  return buf.toString(this.encoding);
	}

	function simpleEnd(buf) {
	  return buf && buf.length ? this.write(buf) : '';
	}
	return string_decoder$1;
}

var _stream_readable$1;
var hasRequired_stream_readable$1;

function require_stream_readable$1 () {
	if (hasRequired_stream_readable$1) return _stream_readable$1;
	hasRequired_stream_readable$1 = 1;

	/*<replacement>*/

	var pna = requireProcessNextickArgs();
	/*</replacement>*/

	_stream_readable$1 = Readable;

	/*<replacement>*/
	var isArray = requireIsarray();
	/*</replacement>*/

	/*<replacement>*/
	var Duplex;
	/*</replacement>*/

	Readable.ReadableState = ReadableState;

	/*<replacement>*/
	require$$0$1.EventEmitter;

	var EElistenerCount = function (emitter, type) {
	  return emitter.listeners(type).length;
	};
	/*</replacement>*/

	/*<replacement>*/
	var Stream = requireStream$1();
	/*</replacement>*/

	/*<replacement>*/

	var Buffer = requireSafeBuffer$1().Buffer;
	var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
	function _uint8ArrayToBuffer(chunk) {
	  return Buffer.from(chunk);
	}
	function _isUint8Array(obj) {
	  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
	}

	/*</replacement>*/

	/*<replacement>*/
	var util = Object.create(requireUtil$2());
	util.inherits = requireInherits();
	/*</replacement>*/

	/*<replacement>*/
	var debugUtil = require$$0$5;
	var debug = void 0;
	if (debugUtil && debugUtil.debuglog) {
	  debug = debugUtil.debuglog('stream');
	} else {
	  debug = function () {};
	}
	/*</replacement>*/

	var BufferList = requireBufferList();
	var destroyImpl = requireDestroy$1();
	var StringDecoder;

	util.inherits(Readable, Stream);

	var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];

	function prependListener(emitter, event, fn) {
	  // Sadly this is not cacheable as some libraries bundle their own
	  // event emitter implementation with them.
	  if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);

	  // This is a hack to make sure that our error handler is attached before any
	  // userland ones.  NEVER DO THIS. This is here only because this code needs
	  // to continue to work with older versions of Node.js that do not include
	  // the prependListener() method. The goal is to eventually remove this hack.
	  if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
	}

	function ReadableState(options, stream) {
	  Duplex = Duplex || require_stream_duplex$1();

	  options = options || {};

	  // Duplex streams are both readable and writable, but share
	  // the same options object.
	  // However, some cases require setting options to different
	  // values for the readable and the writable sides of the duplex stream.
	  // These options can be provided separately as readableXXX and writableXXX.
	  var isDuplex = stream instanceof Duplex;

	  // object stream flag. Used to make read(n) ignore n and to
	  // make all the buffer merging and length checks go away
	  this.objectMode = !!options.objectMode;

	  if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;

	  // the point at which it stops calling _read() to fill the buffer
	  // Note: 0 is a valid value, means "don't call _read preemptively ever"
	  var hwm = options.highWaterMark;
	  var readableHwm = options.readableHighWaterMark;
	  var defaultHwm = this.objectMode ? 16 : 16 * 1024;

	  if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm;

	  // cast to ints.
	  this.highWaterMark = Math.floor(this.highWaterMark);

	  // A linked list is used to store data chunks instead of an array because the
	  // linked list can remove elements from the beginning faster than
	  // array.shift()
	  this.buffer = new BufferList();
	  this.length = 0;
	  this.pipes = null;
	  this.pipesCount = 0;
	  this.flowing = null;
	  this.ended = false;
	  this.endEmitted = false;
	  this.reading = false;

	  // a flag to be able to tell if the event 'readable'/'data' is emitted
	  // immediately, or on a later tick.  We set this to true at first, because
	  // any actions that shouldn't happen until "later" should generally also
	  // not happen before the first read call.
	  this.sync = true;

	  // whenever we return null, then we set a flag to say
	  // that we're awaiting a 'readable' event emission.
	  this.needReadable = false;
	  this.emittedReadable = false;
	  this.readableListening = false;
	  this.resumeScheduled = false;

	  // has it been destroyed
	  this.destroyed = false;

	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';

	  // the number of writers that are awaiting a drain event in .pipe()s
	  this.awaitDrain = 0;

	  // if true, a maybeReadMore has been scheduled
	  this.readingMore = false;

	  this.decoder = null;
	  this.encoding = null;
	  if (options.encoding) {
	    if (!StringDecoder) StringDecoder = requireString_decoder$1().StringDecoder;
	    this.decoder = new StringDecoder(options.encoding);
	    this.encoding = options.encoding;
	  }
	}

	function Readable(options) {
	  Duplex = Duplex || require_stream_duplex$1();

	  if (!(this instanceof Readable)) return new Readable(options);

	  this._readableState = new ReadableState(options, this);

	  // legacy
	  this.readable = true;

	  if (options) {
	    if (typeof options.read === 'function') this._read = options.read;

	    if (typeof options.destroy === 'function') this._destroy = options.destroy;
	  }

	  Stream.call(this);
	}

	Object.defineProperty(Readable.prototype, 'destroyed', {
	  get: function () {
	    if (this._readableState === undefined) {
	      return false;
	    }
	    return this._readableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (!this._readableState) {
	      return;
	    }

	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._readableState.destroyed = value;
	  }
	});

	Readable.prototype.destroy = destroyImpl.destroy;
	Readable.prototype._undestroy = destroyImpl.undestroy;
	Readable.prototype._destroy = function (err, cb) {
	  this.push(null);
	  cb(err);
	};

	// Manually shove something into the read() buffer.
	// This returns true if the highWaterMark has not been hit yet,
	// similar to how Writable.write() returns true if you should
	// write() some more.
	Readable.prototype.push = function (chunk, encoding) {
	  var state = this._readableState;
	  var skipChunkCheck;

	  if (!state.objectMode) {
	    if (typeof chunk === 'string') {
	      encoding = encoding || state.defaultEncoding;
	      if (encoding !== state.encoding) {
	        chunk = Buffer.from(chunk, encoding);
	        encoding = '';
	      }
	      skipChunkCheck = true;
	    }
	  } else {
	    skipChunkCheck = true;
	  }

	  return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
	};

	// Unshift should *always* be something directly out of read()
	Readable.prototype.unshift = function (chunk) {
	  return readableAddChunk(this, chunk, null, true, false);
	};

	function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
	  var state = stream._readableState;
	  if (chunk === null) {
	    state.reading = false;
	    onEofChunk(stream, state);
	  } else {
	    var er;
	    if (!skipChunkCheck) er = chunkInvalid(state, chunk);
	    if (er) {
	      stream.emit('error', er);
	    } else if (state.objectMode || chunk && chunk.length > 0) {
	      if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
	        chunk = _uint8ArrayToBuffer(chunk);
	      }

	      if (addToFront) {
	        if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true);
	      } else if (state.ended) {
	        stream.emit('error', new Error('stream.push() after EOF'));
	      } else {
	        state.reading = false;
	        if (state.decoder && !encoding) {
	          chunk = state.decoder.write(chunk);
	          if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
	        } else {
	          addChunk(stream, state, chunk, false);
	        }
	      }
	    } else if (!addToFront) {
	      state.reading = false;
	    }
	  }

	  return needMoreData(state);
	}

	function addChunk(stream, state, chunk, addToFront) {
	  if (state.flowing && state.length === 0 && !state.sync) {
	    stream.emit('data', chunk);
	    stream.read(0);
	  } else {
	    // update the buffer info.
	    state.length += state.objectMode ? 1 : chunk.length;
	    if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);

	    if (state.needReadable) emitReadable(stream);
	  }
	  maybeReadMore(stream, state);
	}

	function chunkInvalid(state, chunk) {
	  var er;
	  if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
	    er = new TypeError('Invalid non-string/buffer chunk');
	  }
	  return er;
	}

	// if it's past the high water mark, we can push in some more.
	// Also, if we have no data yet, we can stand some
	// more bytes.  This is to work around cases where hwm=0,
	// such as the repl.  Also, if the push() triggered a
	// readable event, and the user called read(largeNumber) such that
	// needReadable was set, then we ought to push more, so that another
	// 'readable' event will be triggered.
	function needMoreData(state) {
	  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
	}

	Readable.prototype.isPaused = function () {
	  return this._readableState.flowing === false;
	};

	// backwards compatibility.
	Readable.prototype.setEncoding = function (enc) {
	  if (!StringDecoder) StringDecoder = requireString_decoder$1().StringDecoder;
	  this._readableState.decoder = new StringDecoder(enc);
	  this._readableState.encoding = enc;
	  return this;
	};

	// Don't raise the hwm > 8MB
	var MAX_HWM = 0x800000;
	function computeNewHighWaterMark(n) {
	  if (n >= MAX_HWM) {
	    n = MAX_HWM;
	  } else {
	    // Get the next highest power of 2 to prevent increasing hwm excessively in
	    // tiny amounts
	    n--;
	    n |= n >>> 1;
	    n |= n >>> 2;
	    n |= n >>> 4;
	    n |= n >>> 8;
	    n |= n >>> 16;
	    n++;
	  }
	  return n;
	}

	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function howMuchToRead(n, state) {
	  if (n <= 0 || state.length === 0 && state.ended) return 0;
	  if (state.objectMode) return 1;
	  if (n !== n) {
	    // Only flow one buffer at a time
	    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
	  }
	  // If we're asking for more than the current hwm, then raise the hwm.
	  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
	  if (n <= state.length) return n;
	  // Don't have enough
	  if (!state.ended) {
	    state.needReadable = true;
	    return 0;
	  }
	  return state.length;
	}

	// you can override either this method, or the async _read(n) below.
	Readable.prototype.read = function (n) {
	  debug('read', n);
	  n = parseInt(n, 10);
	  var state = this._readableState;
	  var nOrig = n;

	  if (n !== 0) state.emittedReadable = false;

	  // if we're doing read(0) to trigger a readable event, but we
	  // already have a bunch of data in the buffer, then just trigger
	  // the 'readable' event and move on.
	  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
	    debug('read: emitReadable', state.length, state.ended);
	    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
	    return null;
	  }

	  n = howMuchToRead(n, state);

	  // if we've ended, and we're now clear, then finish it up.
	  if (n === 0 && state.ended) {
	    if (state.length === 0) endReadable(this);
	    return null;
	  }

	  // All the actual chunk generation logic needs to be
	  // *below* the call to _read.  The reason is that in certain
	  // synthetic stream cases, such as passthrough streams, _read
	  // may be a completely synchronous operation which may change
	  // the state of the read buffer, providing enough data when
	  // before there was *not* enough.
	  //
	  // So, the steps are:
	  // 1. Figure out what the state of things will be after we do
	  // a read from the buffer.
	  //
	  // 2. If that resulting state will trigger a _read, then call _read.
	  // Note that this may be asynchronous, or synchronous.  Yes, it is
	  // deeply ugly to write APIs this way, but that still doesn't mean
	  // that the Readable class should behave improperly, as streams are
	  // designed to be sync/async agnostic.
	  // Take note if the _read call is sync or async (ie, if the read call
	  // has returned yet), so that we know whether or not it's safe to emit
	  // 'readable' etc.
	  //
	  // 3. Actually pull the requested chunks out of the buffer and return.

	  // if we need a readable event, then we need to do some reading.
	  var doRead = state.needReadable;
	  debug('need readable', doRead);

	  // if we currently have less than the highWaterMark, then also read some
	  if (state.length === 0 || state.length - n < state.highWaterMark) {
	    doRead = true;
	    debug('length less than watermark', doRead);
	  }

	  // however, if we've ended, then there's no point, and if we're already
	  // reading, then it's unnecessary.
	  if (state.ended || state.reading) {
	    doRead = false;
	    debug('reading or ended', doRead);
	  } else if (doRead) {
	    debug('do read');
	    state.reading = true;
	    state.sync = true;
	    // if the length is currently zero, then we *need* a readable event.
	    if (state.length === 0) state.needReadable = true;
	    // call internal read method
	    this._read(state.highWaterMark);
	    state.sync = false;
	    // If _read pushed data synchronously, then `reading` will be false,
	    // and we need to re-evaluate how much data we can return to the user.
	    if (!state.reading) n = howMuchToRead(nOrig, state);
	  }

	  var ret;
	  if (n > 0) ret = fromList(n, state);else ret = null;

	  if (ret === null) {
	    state.needReadable = true;
	    n = 0;
	  } else {
	    state.length -= n;
	  }

	  if (state.length === 0) {
	    // If we have nothing in the buffer, then we want to know
	    // as soon as we *do* get something into the buffer.
	    if (!state.ended) state.needReadable = true;

	    // If we tried to read() past the EOF, then emit end on the next tick.
	    if (nOrig !== n && state.ended) endReadable(this);
	  }

	  if (ret !== null) this.emit('data', ret);

	  return ret;
	};

	function onEofChunk(stream, state) {
	  if (state.ended) return;
	  if (state.decoder) {
	    var chunk = state.decoder.end();
	    if (chunk && chunk.length) {
	      state.buffer.push(chunk);
	      state.length += state.objectMode ? 1 : chunk.length;
	    }
	  }
	  state.ended = true;

	  // emit 'readable' now to make sure it gets picked up.
	  emitReadable(stream);
	}

	// Don't emit readable right away in sync mode, because this can trigger
	// another read() call => stack overflow.  This way, it might trigger
	// a nextTick recursion warning, but that's not so bad.
	function emitReadable(stream) {
	  var state = stream._readableState;
	  state.needReadable = false;
	  if (!state.emittedReadable) {
	    debug('emitReadable', state.flowing);
	    state.emittedReadable = true;
	    if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream);
	  }
	}

	function emitReadable_(stream) {
	  debug('emit readable');
	  stream.emit('readable');
	  flow(stream);
	}

	// at this point, the user has presumably seen the 'readable' event,
	// and called read() to consume some data.  that may have triggered
	// in turn another _read(n) call, in which case reading = true if
	// it's in progress.
	// However, if we're not ended, or reading, and the length < hwm,
	// then go ahead and try to read some more preemptively.
	function maybeReadMore(stream, state) {
	  if (!state.readingMore) {
	    state.readingMore = true;
	    pna.nextTick(maybeReadMore_, stream, state);
	  }
	}

	function maybeReadMore_(stream, state) {
	  var len = state.length;
	  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
	    debug('maybeReadMore read 0');
	    stream.read(0);
	    if (len === state.length)
	      // didn't get any data, stop spinning.
	      break;else len = state.length;
	  }
	  state.readingMore = false;
	}

	// abstract method.  to be overridden in specific implementation classes.
	// call cb(er, data) where data is <= n in length.
	// for virtual (non-string, non-buffer) streams, "length" is somewhat
	// arbitrary, and perhaps not very meaningful.
	Readable.prototype._read = function (n) {
	  this.emit('error', new Error('_read() is not implemented'));
	};

	Readable.prototype.pipe = function (dest, pipeOpts) {
	  var src = this;
	  var state = this._readableState;

	  switch (state.pipesCount) {
	    case 0:
	      state.pipes = dest;
	      break;
	    case 1:
	      state.pipes = [state.pipes, dest];
	      break;
	    default:
	      state.pipes.push(dest);
	      break;
	  }
	  state.pipesCount += 1;
	  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);

	  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;

	  var endFn = doEnd ? onend : unpipe;
	  if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn);

	  dest.on('unpipe', onunpipe);
	  function onunpipe(readable, unpipeInfo) {
	    debug('onunpipe');
	    if (readable === src) {
	      if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
	        unpipeInfo.hasUnpiped = true;
	        cleanup();
	      }
	    }
	  }

	  function onend() {
	    debug('onend');
	    dest.end();
	  }

	  // when the dest drains, it reduces the awaitDrain counter
	  // on the source.  This would be more elegant with a .once()
	  // handler in flow(), but adding and removing repeatedly is
	  // too slow.
	  var ondrain = pipeOnDrain(src);
	  dest.on('drain', ondrain);

	  var cleanedUp = false;
	  function cleanup() {
	    debug('cleanup');
	    // cleanup event handlers once the pipe is broken
	    dest.removeListener('close', onclose);
	    dest.removeListener('finish', onfinish);
	    dest.removeListener('drain', ondrain);
	    dest.removeListener('error', onerror);
	    dest.removeListener('unpipe', onunpipe);
	    src.removeListener('end', onend);
	    src.removeListener('end', unpipe);
	    src.removeListener('data', ondata);

	    cleanedUp = true;

	    // if the reader is waiting for a drain event from this
	    // specific writer, then it would cause it to never start
	    // flowing again.
	    // So, if this is awaiting a drain, then we just call it now.
	    // If we don't know, then assume that we are waiting for one.
	    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
	  }

	  // If the user pushes more data while we're writing to dest then we'll end up
	  // in ondata again. However, we only want to increase awaitDrain once because
	  // dest will only emit one 'drain' event for the multiple writes.
	  // => Introduce a guard on increasing awaitDrain.
	  var increasedAwaitDrain = false;
	  src.on('data', ondata);
	  function ondata(chunk) {
	    debug('ondata');
	    increasedAwaitDrain = false;
	    var ret = dest.write(chunk);
	    if (false === ret && !increasedAwaitDrain) {
	      // If the user unpiped during `dest.write()`, it is possible
	      // to get stuck in a permanently paused state if that write
	      // also returned false.
	      // => Check whether `dest` is still a piping destination.
	      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
	        debug('false write response, pause', state.awaitDrain);
	        state.awaitDrain++;
	        increasedAwaitDrain = true;
	      }
	      src.pause();
	    }
	  }

	  // if the dest has an error, then stop piping into it.
	  // however, don't suppress the throwing behavior for this.
	  function onerror(er) {
	    debug('onerror', er);
	    unpipe();
	    dest.removeListener('error', onerror);
	    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
	  }

	  // Make sure our error handler is attached before userland ones.
	  prependListener(dest, 'error', onerror);

	  // Both close and finish should trigger unpipe, but only once.
	  function onclose() {
	    dest.removeListener('finish', onfinish);
	    unpipe();
	  }
	  dest.once('close', onclose);
	  function onfinish() {
	    debug('onfinish');
	    dest.removeListener('close', onclose);
	    unpipe();
	  }
	  dest.once('finish', onfinish);

	  function unpipe() {
	    debug('unpipe');
	    src.unpipe(dest);
	  }

	  // tell the dest that it's being piped to
	  dest.emit('pipe', src);

	  // start the flow if it hasn't been started already.
	  if (!state.flowing) {
	    debug('pipe resume');
	    src.resume();
	  }

	  return dest;
	};

	function pipeOnDrain(src) {
	  return function () {
	    var state = src._readableState;
	    debug('pipeOnDrain', state.awaitDrain);
	    if (state.awaitDrain) state.awaitDrain--;
	    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
	      state.flowing = true;
	      flow(src);
	    }
	  };
	}

	Readable.prototype.unpipe = function (dest) {
	  var state = this._readableState;
	  var unpipeInfo = { hasUnpiped: false };

	  // if we're not piping anywhere, then do nothing.
	  if (state.pipesCount === 0) return this;

	  // just one destination.  most common case.
	  if (state.pipesCount === 1) {
	    // passed in one, but it's not the right one.
	    if (dest && dest !== state.pipes) return this;

	    if (!dest) dest = state.pipes;

	    // got a match.
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	    if (dest) dest.emit('unpipe', this, unpipeInfo);
	    return this;
	  }

	  // slow case. multiple pipe destinations.

	  if (!dest) {
	    // remove all.
	    var dests = state.pipes;
	    var len = state.pipesCount;
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;

	    for (var i = 0; i < len; i++) {
	      dests[i].emit('unpipe', this, { hasUnpiped: false });
	    }return this;
	  }

	  // try to find the right one.
	  var index = indexOf(state.pipes, dest);
	  if (index === -1) return this;

	  state.pipes.splice(index, 1);
	  state.pipesCount -= 1;
	  if (state.pipesCount === 1) state.pipes = state.pipes[0];

	  dest.emit('unpipe', this, unpipeInfo);

	  return this;
	};

	// set up data events if they are asked for
	// Ensure readable listeners eventually get something
	Readable.prototype.on = function (ev, fn) {
	  var res = Stream.prototype.on.call(this, ev, fn);

	  if (ev === 'data') {
	    // Start flowing on next tick if stream isn't explicitly paused
	    if (this._readableState.flowing !== false) this.resume();
	  } else if (ev === 'readable') {
	    var state = this._readableState;
	    if (!state.endEmitted && !state.readableListening) {
	      state.readableListening = state.needReadable = true;
	      state.emittedReadable = false;
	      if (!state.reading) {
	        pna.nextTick(nReadingNextTick, this);
	      } else if (state.length) {
	        emitReadable(this);
	      }
	    }
	  }

	  return res;
	};
	Readable.prototype.addListener = Readable.prototype.on;

	function nReadingNextTick(self) {
	  debug('readable nexttick read 0');
	  self.read(0);
	}

	// pause() and resume() are remnants of the legacy readable stream API
	// If the user uses them, then switch into old mode.
	Readable.prototype.resume = function () {
	  var state = this._readableState;
	  if (!state.flowing) {
	    debug('resume');
	    state.flowing = true;
	    resume(this, state);
	  }
	  return this;
	};

	function resume(stream, state) {
	  if (!state.resumeScheduled) {
	    state.resumeScheduled = true;
	    pna.nextTick(resume_, stream, state);
	  }
	}

	function resume_(stream, state) {
	  if (!state.reading) {
	    debug('resume read 0');
	    stream.read(0);
	  }

	  state.resumeScheduled = false;
	  state.awaitDrain = 0;
	  stream.emit('resume');
	  flow(stream);
	  if (state.flowing && !state.reading) stream.read(0);
	}

	Readable.prototype.pause = function () {
	  debug('call pause flowing=%j', this._readableState.flowing);
	  if (false !== this._readableState.flowing) {
	    debug('pause');
	    this._readableState.flowing = false;
	    this.emit('pause');
	  }
	  return this;
	};

	function flow(stream) {
	  var state = stream._readableState;
	  debug('flow', state.flowing);
	  while (state.flowing && stream.read() !== null) {}
	}

	// wrap an old-style stream as the async data source.
	// This is *not* part of the readable stream interface.
	// It is an ugly unfortunate mess of history.
	Readable.prototype.wrap = function (stream) {
	  var _this = this;

	  var state = this._readableState;
	  var paused = false;

	  stream.on('end', function () {
	    debug('wrapped end');
	    if (state.decoder && !state.ended) {
	      var chunk = state.decoder.end();
	      if (chunk && chunk.length) _this.push(chunk);
	    }

	    _this.push(null);
	  });

	  stream.on('data', function (chunk) {
	    debug('wrapped data');
	    if (state.decoder) chunk = state.decoder.write(chunk);

	    // don't skip over falsy values in objectMode
	    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;

	    var ret = _this.push(chunk);
	    if (!ret) {
	      paused = true;
	      stream.pause();
	    }
	  });

	  // proxy all the other methods.
	  // important when wrapping filters and duplexes.
	  for (var i in stream) {
	    if (this[i] === undefined && typeof stream[i] === 'function') {
	      this[i] = function (method) {
	        return function () {
	          return stream[method].apply(stream, arguments);
	        };
	      }(i);
	    }
	  }

	  // proxy certain important events.
	  for (var n = 0; n < kProxyEvents.length; n++) {
	    stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
	  }

	  // when we try to consume some more bytes, simply unpause the
	  // underlying stream.
	  this._read = function (n) {
	    debug('wrapped _read', n);
	    if (paused) {
	      paused = false;
	      stream.resume();
	    }
	  };

	  return this;
	};

	Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function () {
	    return this._readableState.highWaterMark;
	  }
	});

	// exposed for testing purposes only.
	Readable._fromList = fromList;

	// Pluck off n bytes from an array of buffers.
	// Length is the combined lengths of all the buffers in the list.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function fromList(n, state) {
	  // nothing buffered
	  if (state.length === 0) return null;

	  var ret;
	  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
	    // read it all, truncate the list
	    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);
	    state.buffer.clear();
	  } else {
	    // read part of list
	    ret = fromListPartial(n, state.buffer, state.decoder);
	  }

	  return ret;
	}

	// Extracts only enough buffered data to satisfy the amount requested.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function fromListPartial(n, list, hasStrings) {
	  var ret;
	  if (n < list.head.data.length) {
	    // slice is the same for buffers and strings
	    ret = list.head.data.slice(0, n);
	    list.head.data = list.head.data.slice(n);
	  } else if (n === list.head.data.length) {
	    // first chunk is a perfect match
	    ret = list.shift();
	  } else {
	    // result spans more than one buffer
	    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
	  }
	  return ret;
	}

	// Copies a specified amount of characters from the list of buffered data
	// chunks.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function copyFromBufferString(n, list) {
	  var p = list.head;
	  var c = 1;
	  var ret = p.data;
	  n -= ret.length;
	  while (p = p.next) {
	    var str = p.data;
	    var nb = n > str.length ? str.length : n;
	    if (nb === str.length) ret += str;else ret += str.slice(0, n);
	    n -= nb;
	    if (n === 0) {
	      if (nb === str.length) {
	        ++c;
	        if (p.next) list.head = p.next;else list.head = list.tail = null;
	      } else {
	        list.head = p;
	        p.data = str.slice(nb);
	      }
	      break;
	    }
	    ++c;
	  }
	  list.length -= c;
	  return ret;
	}

	// Copies a specified amount of bytes from the list of buffered data chunks.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function copyFromBuffer(n, list) {
	  var ret = Buffer.allocUnsafe(n);
	  var p = list.head;
	  var c = 1;
	  p.data.copy(ret);
	  n -= p.data.length;
	  while (p = p.next) {
	    var buf = p.data;
	    var nb = n > buf.length ? buf.length : n;
	    buf.copy(ret, ret.length - n, 0, nb);
	    n -= nb;
	    if (n === 0) {
	      if (nb === buf.length) {
	        ++c;
	        if (p.next) list.head = p.next;else list.head = list.tail = null;
	      } else {
	        list.head = p;
	        p.data = buf.slice(nb);
	      }
	      break;
	    }
	    ++c;
	  }
	  list.length -= c;
	  return ret;
	}

	function endReadable(stream) {
	  var state = stream._readableState;

	  // If we get here before consuming all the bytes, then that is a
	  // bug in node.  Should never happen.
	  if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream');

	  if (!state.endEmitted) {
	    state.ended = true;
	    pna.nextTick(endReadableNT, state, stream);
	  }
	}

	function endReadableNT(state, stream) {
	  // Check that we didn't get one last unshift.
	  if (!state.endEmitted && state.length === 0) {
	    state.endEmitted = true;
	    stream.readable = false;
	    stream.emit('end');
	  }
	}

	function indexOf(xs, x) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    if (xs[i] === x) return i;
	  }
	  return -1;
	}
	return _stream_readable$1;
}

var _stream_transform$1;
var hasRequired_stream_transform$1;

function require_stream_transform$1 () {
	if (hasRequired_stream_transform$1) return _stream_transform$1;
	hasRequired_stream_transform$1 = 1;

	_stream_transform$1 = Transform;

	var Duplex = require_stream_duplex$1();

	/*<replacement>*/
	var util = Object.create(requireUtil$2());
	util.inherits = requireInherits();
	/*</replacement>*/

	util.inherits(Transform, Duplex);

	function afterTransform(er, data) {
	  var ts = this._transformState;
	  ts.transforming = false;

	  var cb = ts.writecb;

	  if (!cb) {
	    return this.emit('error', new Error('write callback called multiple times'));
	  }

	  ts.writechunk = null;
	  ts.writecb = null;

	  if (data != null) // single equals check for both `null` and `undefined`
	    this.push(data);

	  cb(er);

	  var rs = this._readableState;
	  rs.reading = false;
	  if (rs.needReadable || rs.length < rs.highWaterMark) {
	    this._read(rs.highWaterMark);
	  }
	}

	function Transform(options) {
	  if (!(this instanceof Transform)) return new Transform(options);

	  Duplex.call(this, options);

	  this._transformState = {
	    afterTransform: afterTransform.bind(this),
	    needTransform: false,
	    transforming: false,
	    writecb: null,
	    writechunk: null,
	    writeencoding: null
	  };

	  // start out asking for a readable event once data is transformed.
	  this._readableState.needReadable = true;

	  // we have implemented the _read method, and done the other things
	  // that Readable wants before the first _read call, so unset the
	  // sync guard flag.
	  this._readableState.sync = false;

	  if (options) {
	    if (typeof options.transform === 'function') this._transform = options.transform;

	    if (typeof options.flush === 'function') this._flush = options.flush;
	  }

	  // When the writable side finishes, then flush out anything remaining.
	  this.on('prefinish', prefinish);
	}

	function prefinish() {
	  var _this = this;

	  if (typeof this._flush === 'function') {
	    this._flush(function (er, data) {
	      done(_this, er, data);
	    });
	  } else {
	    done(this, null, null);
	  }
	}

	Transform.prototype.push = function (chunk, encoding) {
	  this._transformState.needTransform = false;
	  return Duplex.prototype.push.call(this, chunk, encoding);
	};

	// This is the part where you do stuff!
	// override this function in implementation classes.
	// 'chunk' is an input chunk.
	//
	// Call `push(newChunk)` to pass along transformed output
	// to the readable side.  You may call 'push' zero or more times.
	//
	// Call `cb(err)` when you are done with this chunk.  If you pass
	// an error, then that'll put the hurt on the whole operation.  If you
	// never call cb(), then you'll never get another chunk.
	Transform.prototype._transform = function (chunk, encoding, cb) {
	  throw new Error('_transform() is not implemented');
	};

	Transform.prototype._write = function (chunk, encoding, cb) {
	  var ts = this._transformState;
	  ts.writecb = cb;
	  ts.writechunk = chunk;
	  ts.writeencoding = encoding;
	  if (!ts.transforming) {
	    var rs = this._readableState;
	    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
	  }
	};

	// Doesn't matter what the args are here.
	// _transform does all the work.
	// That we got here means that the readable side wants more data.
	Transform.prototype._read = function (n) {
	  var ts = this._transformState;

	  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
	    ts.transforming = true;
	    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
	  } else {
	    // mark that we need a transform, so that any data that comes in
	    // will get processed, now that we've asked for it.
	    ts.needTransform = true;
	  }
	};

	Transform.prototype._destroy = function (err, cb) {
	  var _this2 = this;

	  Duplex.prototype._destroy.call(this, err, function (err2) {
	    cb(err2);
	    _this2.emit('close');
	  });
	};

	function done(stream, er, data) {
	  if (er) return stream.emit('error', er);

	  if (data != null) // single equals check for both `null` and `undefined`
	    stream.push(data);

	  // if there's nothing in the write buffer, then that means
	  // that nothing more will ever be provided
	  if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0');

	  if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming');

	  return stream.push(null);
	}
	return _stream_transform$1;
}

var _stream_passthrough$1;
var hasRequired_stream_passthrough$1;

function require_stream_passthrough$1 () {
	if (hasRequired_stream_passthrough$1) return _stream_passthrough$1;
	hasRequired_stream_passthrough$1 = 1;

	_stream_passthrough$1 = PassThrough;

	var Transform = require_stream_transform$1();

	/*<replacement>*/
	var util = Object.create(requireUtil$2());
	util.inherits = requireInherits();
	/*</replacement>*/

	util.inherits(PassThrough, Transform);

	function PassThrough(options) {
	  if (!(this instanceof PassThrough)) return new PassThrough(options);

	  Transform.call(this, options);
	}

	PassThrough.prototype._transform = function (chunk, encoding, cb) {
	  cb(null, chunk);
	};
	return _stream_passthrough$1;
}

var hasRequiredReadable$1;

function requireReadable$1 () {
	if (hasRequiredReadable$1) return readable$1.exports;
	hasRequiredReadable$1 = 1;
	(function (module, exports) {
		var Stream = require$$0$4;
		if (process.env.READABLE_STREAM === 'disable' && Stream) {
		  module.exports = Stream;
		  exports = module.exports = Stream.Readable;
		  exports.Readable = Stream.Readable;
		  exports.Writable = Stream.Writable;
		  exports.Duplex = Stream.Duplex;
		  exports.Transform = Stream.Transform;
		  exports.PassThrough = Stream.PassThrough;
		  exports.Stream = Stream;
		} else {
		  exports = module.exports = require_stream_readable$1();
		  exports.Stream = Stream || exports;
		  exports.Readable = exports;
		  exports.Writable = require_stream_writable$1();
		  exports.Duplex = require_stream_duplex$1();
		  exports.Transform = require_stream_transform$1();
		  exports.PassThrough = require_stream_passthrough$1();
		} 
	} (readable$1, readable$1.exports));
	return readable$1.exports;
}

var passthrough;
var hasRequiredPassthrough;

function requirePassthrough () {
	if (hasRequiredPassthrough) return passthrough;
	hasRequiredPassthrough = 1;
	passthrough = requireReadable$1().PassThrough;
	return passthrough;
}

var lazystream;
var hasRequiredLazystream;

function requireLazystream () {
	if (hasRequiredLazystream) return lazystream;
	hasRequiredLazystream = 1;
	var util = require$$0$5;
	var PassThrough = requirePassthrough();

	lazystream = {
	  Readable: Readable,
	  Writable: Writable
	};

	util.inherits(Readable, PassThrough);
	util.inherits(Writable, PassThrough);

	// Patch the given method of instance so that the callback
	// is executed once, before the actual method is called the
	// first time.
	function beforeFirstCall(instance, method, callback) {
	  instance[method] = function() {
	    delete instance[method];
	    callback.apply(this, arguments);
	    return this[method].apply(this, arguments);
	  };
	}

	function Readable(fn, options) {
	  if (!(this instanceof Readable))
	    return new Readable(fn, options);

	  PassThrough.call(this, options);

	  beforeFirstCall(this, '_read', function() {
	    var source = fn.call(this, options);
	    var emit = this.emit.bind(this, 'error');
	    source.on('error', emit);
	    source.pipe(this);
	  });

	  this.emit('readable');
	}

	function Writable(fn, options) {
	  if (!(this instanceof Writable))
	    return new Writable(fn, options);

	  PassThrough.call(this, options);

	  beforeFirstCall(this, '_write', function() {
	    var destination = fn.call(this, options);
	    var emit = this.emit.bind(this, 'error');
	    destination.on('error', emit);
	    this.pipe(destination);
	  });

	  this.emit('writable');
	}
	return lazystream;
}

/*!
 * normalize-path <https://github.com/jonschlinkert/normalize-path>
 *
 * Copyright (c) 2014-2018, Jon Schlinkert.
 * Released under the MIT License.
 */

var normalizePath;
var hasRequiredNormalizePath;

function requireNormalizePath () {
	if (hasRequiredNormalizePath) return normalizePath;
	hasRequiredNormalizePath = 1;
	normalizePath = function(path, stripTrailing) {
	  if (typeof path !== 'string') {
	    throw new TypeError('expected path to be a string');
	  }

	  if (path === '\\' || path === '/') return '/';

	  var len = path.length;
	  if (len <= 1) return path;

	  // ensure that win32 namespaces has two leading slashes, so that the path is
	  // handled properly by the win32 version of path.parse() after being normalized
	  // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
	  var prefix = '';
	  if (len > 4 && path[3] === '\\') {
	    var ch = path[2];
	    if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
	      path = path.slice(2);
	      prefix = '//';
	    }
	  }

	  var segs = path.split(/[/\\]+/);
	  if (stripTrailing !== false && segs[segs.length - 1] === '') {
	    segs.pop();
	  }
	  return prefix + segs.join('/');
	};
	return normalizePath;
}

/**
 * This method returns the first argument it receives.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Util
 * @param {*} value Any value.
 * @returns {*} Returns `value`.
 * @example
 *
 * var object = { 'a': 1 };
 *
 * console.log(_.identity(object) === object);
 * // => true
 */

var identity_1;
var hasRequiredIdentity;

function requireIdentity () {
	if (hasRequiredIdentity) return identity_1;
	hasRequiredIdentity = 1;
	function identity(value) {
	  return value;
	}

	identity_1 = identity;
	return identity_1;
}

/**
 * A faster alternative to `Function#apply`, this function invokes `func`
 * with the `this` binding of `thisArg` and the arguments of `args`.
 *
 * @private
 * @param {Function} func The function to invoke.
 * @param {*} thisArg The `this` binding of `func`.
 * @param {Array} args The arguments to invoke `func` with.
 * @returns {*} Returns the result of `func`.
 */

var _apply;
var hasRequired_apply;

function require_apply () {
	if (hasRequired_apply) return _apply;
	hasRequired_apply = 1;
	function apply(func, thisArg, args) {
	  switch (args.length) {
	    case 0: return func.call(thisArg);
	    case 1: return func.call(thisArg, args[0]);
	    case 2: return func.call(thisArg, args[0], args[1]);
	    case 3: return func.call(thisArg, args[0], args[1], args[2]);
	  }
	  return func.apply(thisArg, args);
	}

	_apply = apply;
	return _apply;
}

var _overRest;
var hasRequired_overRest;

function require_overRest () {
	if (hasRequired_overRest) return _overRest;
	hasRequired_overRest = 1;
	var apply = require_apply();

	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeMax = Math.max;

	/**
	 * A specialized version of `baseRest` which transforms the rest array.
	 *
	 * @private
	 * @param {Function} func The function to apply a rest parameter to.
	 * @param {number} [start=func.length-1] The start position of the rest parameter.
	 * @param {Function} transform The rest array transform.
	 * @returns {Function} Returns the new function.
	 */
	function overRest(func, start, transform) {
	  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
	  return function() {
	    var args = arguments,
	        index = -1,
	        length = nativeMax(args.length - start, 0),
	        array = Array(length);

	    while (++index < length) {
	      array[index] = args[start + index];
	    }
	    index = -1;
	    var otherArgs = Array(start + 1);
	    while (++index < start) {
	      otherArgs[index] = args[index];
	    }
	    otherArgs[start] = transform(array);
	    return apply(func, this, otherArgs);
	  };
	}

	_overRest = overRest;
	return _overRest;
}

/**
 * Creates a function that returns `value`.
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Util
 * @param {*} value The value to return from the new function.
 * @returns {Function} Returns the new constant function.
 * @example
 *
 * var objects = _.times(2, _.constant({ 'a': 1 }));
 *
 * console.log(objects);
 * // => [{ 'a': 1 }, { 'a': 1 }]
 *
 * console.log(objects[0] === objects[1]);
 * // => true
 */

var constant_1;
var hasRequiredConstant;

function requireConstant () {
	if (hasRequiredConstant) return constant_1;
	hasRequiredConstant = 1;
	function constant(value) {
	  return function() {
	    return value;
	  };
	}

	constant_1 = constant;
	return constant_1;
}

/** Detect free variable `global` from Node.js. */

var _freeGlobal;
var hasRequired_freeGlobal;

function require_freeGlobal () {
	if (hasRequired_freeGlobal) return _freeGlobal;
	hasRequired_freeGlobal = 1;
	var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

	_freeGlobal = freeGlobal;
	return _freeGlobal;
}

var _root;
var hasRequired_root;

function require_root () {
	if (hasRequired_root) return _root;
	hasRequired_root = 1;
	var freeGlobal = require_freeGlobal();

	/** Detect free variable `self`. */
	var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

	/** Used as a reference to the global object. */
	var root = freeGlobal || freeSelf || Function('return this')();

	_root = root;
	return _root;
}

var _Symbol;
var hasRequired_Symbol;

function require_Symbol () {
	if (hasRequired_Symbol) return _Symbol;
	hasRequired_Symbol = 1;
	var root = require_root();

	/** Built-in value references. */
	var Symbol = root.Symbol;

	_Symbol = Symbol;
	return _Symbol;
}

var _getRawTag;
var hasRequired_getRawTag;

function require_getRawTag () {
	if (hasRequired_getRawTag) return _getRawTag;
	hasRequired_getRawTag = 1;
	var Symbol = require_Symbol();

	/** Used for built-in method references. */
	var objectProto = Object.prototype;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/**
	 * Used to resolve the
	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	 * of values.
	 */
	var nativeObjectToString = objectProto.toString;

	/** Built-in value references. */
	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;

	/**
	 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @returns {string} Returns the raw `toStringTag`.
	 */
	function getRawTag(value) {
	  var isOwn = hasOwnProperty.call(value, symToStringTag),
	      tag = value[symToStringTag];

	  try {
	    value[symToStringTag] = undefined;
	    var unmasked = true;
	  } catch (e) {}

	  var result = nativeObjectToString.call(value);
	  if (unmasked) {
	    if (isOwn) {
	      value[symToStringTag] = tag;
	    } else {
	      delete value[symToStringTag];
	    }
	  }
	  return result;
	}

	_getRawTag = getRawTag;
	return _getRawTag;
}

/** Used for built-in method references. */

var _objectToString;
var hasRequired_objectToString;

function require_objectToString () {
	if (hasRequired_objectToString) return _objectToString;
	hasRequired_objectToString = 1;
	var objectProto = Object.prototype;

	/**
	 * Used to resolve the
	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	 * of values.
	 */
	var nativeObjectToString = objectProto.toString;

	/**
	 * Converts `value` to a string using `Object.prototype.toString`.
	 *
	 * @private
	 * @param {*} value The value to convert.
	 * @returns {string} Returns the converted string.
	 */
	function objectToString(value) {
	  return nativeObjectToString.call(value);
	}

	_objectToString = objectToString;
	return _objectToString;
}

var _baseGetTag;
var hasRequired_baseGetTag;

function require_baseGetTag () {
	if (hasRequired_baseGetTag) return _baseGetTag;
	hasRequired_baseGetTag = 1;
	var Symbol = require_Symbol(),
	    getRawTag = require_getRawTag(),
	    objectToString = require_objectToString();

	/** `Object#toString` result references. */
	var nullTag = '[object Null]',
	    undefinedTag = '[object Undefined]';

	/** Built-in value references. */
	var symToStringTag = Symbol ? Symbol.toStringTag : undefined;

	/**
	 * The base implementation of `getTag` without fallbacks for buggy environments.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @returns {string} Returns the `toStringTag`.
	 */
	function baseGetTag(value) {
	  if (value == null) {
	    return value === undefined ? undefinedTag : nullTag;
	  }
	  return (symToStringTag && symToStringTag in Object(value))
	    ? getRawTag(value)
	    : objectToString(value);
	}

	_baseGetTag = baseGetTag;
	return _baseGetTag;
}

/**
 * Checks if `value` is the
 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject([1, 2, 3]);
 * // => true
 *
 * _.isObject(_.noop);
 * // => true
 *
 * _.isObject(null);
 * // => false
 */

var isObject_1;
var hasRequiredIsObject;

function requireIsObject () {
	if (hasRequiredIsObject) return isObject_1;
	hasRequiredIsObject = 1;
	function isObject(value) {
	  var type = typeof value;
	  return value != null && (type == 'object' || type == 'function');
	}

	isObject_1 = isObject;
	return isObject_1;
}

var isFunction_1;
var hasRequiredIsFunction;

function requireIsFunction () {
	if (hasRequiredIsFunction) return isFunction_1;
	hasRequiredIsFunction = 1;
	var baseGetTag = require_baseGetTag(),
	    isObject = requireIsObject();

	/** `Object#toString` result references. */
	var asyncTag = '[object AsyncFunction]',
	    funcTag = '[object Function]',
	    genTag = '[object GeneratorFunction]',
	    proxyTag = '[object Proxy]';

	/**
	 * Checks if `value` is classified as a `Function` object.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
	 * @example
	 *
	 * _.isFunction(_);
	 * // => true
	 *
	 * _.isFunction(/abc/);
	 * // => false
	 */
	function isFunction(value) {
	  if (!isObject(value)) {
	    return false;
	  }
	  // The use of `Object#toString` avoids issues with the `typeof` operator
	  // in Safari 9 which returns 'object' for typed arrays and other constructors.
	  var tag = baseGetTag(value);
	  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
	}

	isFunction_1 = isFunction;
	return isFunction_1;
}

var _coreJsData;
var hasRequired_coreJsData;

function require_coreJsData () {
	if (hasRequired_coreJsData) return _coreJsData;
	hasRequired_coreJsData = 1;
	var root = require_root();

	/** Used to detect overreaching core-js shims. */
	var coreJsData = root['__core-js_shared__'];

	_coreJsData = coreJsData;
	return _coreJsData;
}

var _isMasked;
var hasRequired_isMasked;

function require_isMasked () {
	if (hasRequired_isMasked) return _isMasked;
	hasRequired_isMasked = 1;
	var coreJsData = require_coreJsData();

	/** Used to detect methods masquerading as native. */
	var maskSrcKey = (function() {
	  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
	  return uid ? ('Symbol(src)_1.' + uid) : '';
	}());

	/**
	 * Checks if `func` has its source masked.
	 *
	 * @private
	 * @param {Function} func The function to check.
	 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
	 */
	function isMasked(func) {
	  return !!maskSrcKey && (maskSrcKey in func);
	}

	_isMasked = isMasked;
	return _isMasked;
}

/** Used for built-in method references. */

var _toSource;
var hasRequired_toSource;

function require_toSource () {
	if (hasRequired_toSource) return _toSource;
	hasRequired_toSource = 1;
	var funcProto = Function.prototype;

	/** Used to resolve the decompiled source of functions. */
	var funcToString = funcProto.toString;

	/**
	 * Converts `func` to its source code.
	 *
	 * @private
	 * @param {Function} func The function to convert.
	 * @returns {string} Returns the source code.
	 */
	function toSource(func) {
	  if (func != null) {
	    try {
	      return funcToString.call(func);
	    } catch (e) {}
	    try {
	      return (func + '');
	    } catch (e) {}
	  }
	  return '';
	}

	_toSource = toSource;
	return _toSource;
}

var _baseIsNative;
var hasRequired_baseIsNative;

function require_baseIsNative () {
	if (hasRequired_baseIsNative) return _baseIsNative;
	hasRequired_baseIsNative = 1;
	var isFunction = requireIsFunction(),
	    isMasked = require_isMasked(),
	    isObject = requireIsObject(),
	    toSource = require_toSource();

	/**
	 * Used to match `RegExp`
	 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
	 */
	var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

	/** Used to detect host constructors (Safari). */
	var reIsHostCtor = /^\[object .+?Constructor\]$/;

	/** Used for built-in method references. */
	var funcProto = Function.prototype,
	    objectProto = Object.prototype;

	/** Used to resolve the decompiled source of functions. */
	var funcToString = funcProto.toString;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/** Used to detect if a method is native. */
	var reIsNative = RegExp('^' +
	  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
	  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
	);

	/**
	 * The base implementation of `_.isNative` without bad shim checks.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a native function,
	 *  else `false`.
	 */
	function baseIsNative(value) {
	  if (!isObject(value) || isMasked(value)) {
	    return false;
	  }
	  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
	  return pattern.test(toSource(value));
	}

	_baseIsNative = baseIsNative;
	return _baseIsNative;
}

/**
 * Gets the value at `key` of `object`.
 *
 * @private
 * @param {Object} [object] The object to query.
 * @param {string} key The key of the property to get.
 * @returns {*} Returns the property value.
 */

var _getValue;
var hasRequired_getValue;

function require_getValue () {
	if (hasRequired_getValue) return _getValue;
	hasRequired_getValue = 1;
	function getValue(object, key) {
	  return object == null ? undefined : object[key];
	}

	_getValue = getValue;
	return _getValue;
}

var _getNative;
var hasRequired_getNative;

function require_getNative () {
	if (hasRequired_getNative) return _getNative;
	hasRequired_getNative = 1;
	var baseIsNative = require_baseIsNative(),
	    getValue = require_getValue();

	/**
	 * Gets the native function at `key` of `object`.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @param {string} key The key of the method to get.
	 * @returns {*} Returns the function if it's native, else `undefined`.
	 */
	function getNative(object, key) {
	  var value = getValue(object, key);
	  return baseIsNative(value) ? value : undefined;
	}

	_getNative = getNative;
	return _getNative;
}

var _defineProperty;
var hasRequired_defineProperty;

function require_defineProperty () {
	if (hasRequired_defineProperty) return _defineProperty;
	hasRequired_defineProperty = 1;
	var getNative = require_getNative();

	var defineProperty = (function() {
	  try {
	    var func = getNative(Object, 'defineProperty');
	    func({}, '', {});
	    return func;
	  } catch (e) {}
	}());

	_defineProperty = defineProperty;
	return _defineProperty;
}

var _baseSetToString;
var hasRequired_baseSetToString;

function require_baseSetToString () {
	if (hasRequired_baseSetToString) return _baseSetToString;
	hasRequired_baseSetToString = 1;
	var constant = requireConstant(),
	    defineProperty = require_defineProperty(),
	    identity = requireIdentity();

	/**
	 * The base implementation of `setToString` without support for hot loop shorting.
	 *
	 * @private
	 * @param {Function} func The function to modify.
	 * @param {Function} string The `toString` result.
	 * @returns {Function} Returns `func`.
	 */
	var baseSetToString = !defineProperty ? identity : function(func, string) {
	  return defineProperty(func, 'toString', {
	    'configurable': true,
	    'enumerable': false,
	    'value': constant(string),
	    'writable': true
	  });
	};

	_baseSetToString = baseSetToString;
	return _baseSetToString;
}

/** Used to detect hot functions by number of calls within a span of milliseconds. */

var _shortOut;
var hasRequired_shortOut;

function require_shortOut () {
	if (hasRequired_shortOut) return _shortOut;
	hasRequired_shortOut = 1;
	var HOT_COUNT = 800,
	    HOT_SPAN = 16;

	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeNow = Date.now;

	/**
	 * Creates a function that'll short out and invoke `identity` instead
	 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
	 * milliseconds.
	 *
	 * @private
	 * @param {Function} func The function to restrict.
	 * @returns {Function} Returns the new shortable function.
	 */
	function shortOut(func) {
	  var count = 0,
	      lastCalled = 0;

	  return function() {
	    var stamp = nativeNow(),
	        remaining = HOT_SPAN - (stamp - lastCalled);

	    lastCalled = stamp;
	    if (remaining > 0) {
	      if (++count >= HOT_COUNT) {
	        return arguments[0];
	      }
	    } else {
	      count = 0;
	    }
	    return func.apply(undefined, arguments);
	  };
	}

	_shortOut = shortOut;
	return _shortOut;
}

var _setToString;
var hasRequired_setToString;

function require_setToString () {
	if (hasRequired_setToString) return _setToString;
	hasRequired_setToString = 1;
	var baseSetToString = require_baseSetToString(),
	    shortOut = require_shortOut();

	/**
	 * Sets the `toString` method of `func` to return `string`.
	 *
	 * @private
	 * @param {Function} func The function to modify.
	 * @param {Function} string The `toString` result.
	 * @returns {Function} Returns `func`.
	 */
	var setToString = shortOut(baseSetToString);

	_setToString = setToString;
	return _setToString;
}

var _baseRest;
var hasRequired_baseRest;

function require_baseRest () {
	if (hasRequired_baseRest) return _baseRest;
	hasRequired_baseRest = 1;
	var identity = requireIdentity(),
	    overRest = require_overRest(),
	    setToString = require_setToString();

	/**
	 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
	 *
	 * @private
	 * @param {Function} func The function to apply a rest parameter to.
	 * @param {number} [start=func.length-1] The start position of the rest parameter.
	 * @returns {Function} Returns the new function.
	 */
	function baseRest(func, start) {
	  return setToString(overRest(func, start, identity), func + '');
	}

	_baseRest = baseRest;
	return _baseRest;
}

/**
 * Performs a
 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * comparison between two values to determine if they are equivalent.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
 * @example
 *
 * var object = { 'a': 1 };
 * var other = { 'a': 1 };
 *
 * _.eq(object, object);
 * // => true
 *
 * _.eq(object, other);
 * // => false
 *
 * _.eq('a', 'a');
 * // => true
 *
 * _.eq('a', Object('a'));
 * // => false
 *
 * _.eq(NaN, NaN);
 * // => true
 */

var eq_1;
var hasRequiredEq;

function requireEq () {
	if (hasRequiredEq) return eq_1;
	hasRequiredEq = 1;
	function eq(value, other) {
	  return value === other || (value !== value && other !== other);
	}

	eq_1 = eq;
	return eq_1;
}

/** Used as references for various `Number` constants. */

var isLength_1;
var hasRequiredIsLength;

function requireIsLength () {
	if (hasRequiredIsLength) return isLength_1;
	hasRequiredIsLength = 1;
	var MAX_SAFE_INTEGER = 9007199254740991;

	/**
	 * Checks if `value` is a valid array-like length.
	 *
	 * **Note:** This method is loosely based on
	 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
	 * @example
	 *
	 * _.isLength(3);
	 * // => true
	 *
	 * _.isLength(Number.MIN_VALUE);
	 * // => false
	 *
	 * _.isLength(Infinity);
	 * // => false
	 *
	 * _.isLength('3');
	 * // => false
	 */
	function isLength(value) {
	  return typeof value == 'number' &&
	    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
	}

	isLength_1 = isLength;
	return isLength_1;
}

var isArrayLike_1;
var hasRequiredIsArrayLike;

function requireIsArrayLike () {
	if (hasRequiredIsArrayLike) return isArrayLike_1;
	hasRequiredIsArrayLike = 1;
	var isFunction = requireIsFunction(),
	    isLength = requireIsLength();

	/**
	 * Checks if `value` is array-like. A value is considered array-like if it's
	 * not a function and has a `value.length` that's an integer greater than or
	 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
	 * @example
	 *
	 * _.isArrayLike([1, 2, 3]);
	 * // => true
	 *
	 * _.isArrayLike(document.body.children);
	 * // => true
	 *
	 * _.isArrayLike('abc');
	 * // => true
	 *
	 * _.isArrayLike(_.noop);
	 * // => false
	 */
	function isArrayLike(value) {
	  return value != null && isLength(value.length) && !isFunction(value);
	}

	isArrayLike_1 = isArrayLike;
	return isArrayLike_1;
}

/** Used as references for various `Number` constants. */

var _isIndex;
var hasRequired_isIndex;

function require_isIndex () {
	if (hasRequired_isIndex) return _isIndex;
	hasRequired_isIndex = 1;
	var MAX_SAFE_INTEGER = 9007199254740991;

	/** Used to detect unsigned integer values. */
	var reIsUint = /^(?:0|[1-9]\d*)$/;

	/**
	 * Checks if `value` is a valid array-like index.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
	 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
	 */
	function isIndex(value, length) {
	  var type = typeof value;
	  length = length == null ? MAX_SAFE_INTEGER : length;

	  return !!length &&
	    (type == 'number' ||
	      (type != 'symbol' && reIsUint.test(value))) &&
	        (value > -1 && value % 1 == 0 && value < length);
	}

	_isIndex = isIndex;
	return _isIndex;
}

var _isIterateeCall;
var hasRequired_isIterateeCall;

function require_isIterateeCall () {
	if (hasRequired_isIterateeCall) return _isIterateeCall;
	hasRequired_isIterateeCall = 1;
	var eq = requireEq(),
	    isArrayLike = requireIsArrayLike(),
	    isIndex = require_isIndex(),
	    isObject = requireIsObject();

	/**
	 * Checks if the given arguments are from an iteratee call.
	 *
	 * @private
	 * @param {*} value The potential iteratee value argument.
	 * @param {*} index The potential iteratee index or key argument.
	 * @param {*} object The potential iteratee object argument.
	 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
	 *  else `false`.
	 */
	function isIterateeCall(value, index, object) {
	  if (!isObject(object)) {
	    return false;
	  }
	  var type = typeof index;
	  if (type == 'number'
	        ? (isArrayLike(object) && isIndex(index, object.length))
	        : (type == 'string' && index in object)
	      ) {
	    return eq(object[index], value);
	  }
	  return false;
	}

	_isIterateeCall = isIterateeCall;
	return _isIterateeCall;
}

/**
 * The base implementation of `_.times` without support for iteratee shorthands
 * or max array length checks.
 *
 * @private
 * @param {number} n The number of times to invoke `iteratee`.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the array of results.
 */

var _baseTimes;
var hasRequired_baseTimes;

function require_baseTimes () {
	if (hasRequired_baseTimes) return _baseTimes;
	hasRequired_baseTimes = 1;
	function baseTimes(n, iteratee) {
	  var index = -1,
	      result = Array(n);

	  while (++index < n) {
	    result[index] = iteratee(index);
	  }
	  return result;
	}

	_baseTimes = baseTimes;
	return _baseTimes;
}

/**
 * Checks if `value` is object-like. A value is object-like if it's not `null`
 * and has a `typeof` result of "object".
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 * @example
 *
 * _.isObjectLike({});
 * // => true
 *
 * _.isObjectLike([1, 2, 3]);
 * // => true
 *
 * _.isObjectLike(_.noop);
 * // => false
 *
 * _.isObjectLike(null);
 * // => false
 */

var isObjectLike_1;
var hasRequiredIsObjectLike;

function requireIsObjectLike () {
	if (hasRequiredIsObjectLike) return isObjectLike_1;
	hasRequiredIsObjectLike = 1;
	function isObjectLike(value) {
	  return value != null && typeof value == 'object';
	}

	isObjectLike_1 = isObjectLike;
	return isObjectLike_1;
}

var _baseIsArguments;
var hasRequired_baseIsArguments;

function require_baseIsArguments () {
	if (hasRequired_baseIsArguments) return _baseIsArguments;
	hasRequired_baseIsArguments = 1;
	var baseGetTag = require_baseGetTag(),
	    isObjectLike = requireIsObjectLike();

	/** `Object#toString` result references. */
	var argsTag = '[object Arguments]';

	/**
	 * The base implementation of `_.isArguments`.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	 */
	function baseIsArguments(value) {
	  return isObjectLike(value) && baseGetTag(value) == argsTag;
	}

	_baseIsArguments = baseIsArguments;
	return _baseIsArguments;
}

var isArguments_1;
var hasRequiredIsArguments;

function requireIsArguments () {
	if (hasRequiredIsArguments) return isArguments_1;
	hasRequiredIsArguments = 1;
	var baseIsArguments = require_baseIsArguments(),
	    isObjectLike = requireIsObjectLike();

	/** Used for built-in method references. */
	var objectProto = Object.prototype;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/** Built-in value references. */
	var propertyIsEnumerable = objectProto.propertyIsEnumerable;

	/**
	 * Checks if `value` is likely an `arguments` object.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	 *  else `false`.
	 * @example
	 *
	 * _.isArguments(function() { return arguments; }());
	 * // => true
	 *
	 * _.isArguments([1, 2, 3]);
	 * // => false
	 */
	var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
	  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
	    !propertyIsEnumerable.call(value, 'callee');
	};

	isArguments_1 = isArguments;
	return isArguments_1;
}

/**
 * Checks if `value` is classified as an `Array` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
 * @example
 *
 * _.isArray([1, 2, 3]);
 * // => true
 *
 * _.isArray(document.body.children);
 * // => false
 *
 * _.isArray('abc');
 * // => false
 *
 * _.isArray(_.noop);
 * // => false
 */

var isArray_1;
var hasRequiredIsArray;

function requireIsArray () {
	if (hasRequiredIsArray) return isArray_1;
	hasRequiredIsArray = 1;
	var isArray = Array.isArray;

	isArray_1 = isArray;
	return isArray_1;
}

var isBuffer = {exports: {}};

/**
 * This method returns `false`.
 *
 * @static
 * @memberOf _
 * @since 4.13.0
 * @category Util
 * @returns {boolean} Returns `false`.
 * @example
 *
 * _.times(2, _.stubFalse);
 * // => [false, false]
 */

var stubFalse_1;
var hasRequiredStubFalse;

function requireStubFalse () {
	if (hasRequiredStubFalse) return stubFalse_1;
	hasRequiredStubFalse = 1;
	function stubFalse() {
	  return false;
	}

	stubFalse_1 = stubFalse;
	return stubFalse_1;
}

isBuffer.exports;

var hasRequiredIsBuffer;

function requireIsBuffer () {
	if (hasRequiredIsBuffer) return isBuffer.exports;
	hasRequiredIsBuffer = 1;
	(function (module, exports) {
		var root = require_root(),
		    stubFalse = requireStubFalse();

		/** Detect free variable `exports`. */
		var freeExports = exports && !exports.nodeType && exports;

		/** Detect free variable `module`. */
		var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;

		/** Detect the popular CommonJS extension `module.exports`. */
		var moduleExports = freeModule && freeModule.exports === freeExports;

		/** Built-in value references. */
		var Buffer = moduleExports ? root.Buffer : undefined;

		/* Built-in method references for those with the same name as other `lodash` methods. */
		var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;

		/**
		 * Checks if `value` is a buffer.
		 *
		 * @static
		 * @memberOf _
		 * @since 4.3.0
		 * @category Lang
		 * @param {*} value The value to check.
		 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
		 * @example
		 *
		 * _.isBuffer(new Buffer(2));
		 * // => true
		 *
		 * _.isBuffer(new Uint8Array(2));
		 * // => false
		 */
		var isBuffer = nativeIsBuffer || stubFalse;

		module.exports = isBuffer; 
	} (isBuffer, isBuffer.exports));
	return isBuffer.exports;
}

var _baseIsTypedArray;
var hasRequired_baseIsTypedArray;

function require_baseIsTypedArray () {
	if (hasRequired_baseIsTypedArray) return _baseIsTypedArray;
	hasRequired_baseIsTypedArray = 1;
	var baseGetTag = require_baseGetTag(),
	    isLength = requireIsLength(),
	    isObjectLike = requireIsObjectLike();

	/** `Object#toString` result references. */
	var argsTag = '[object Arguments]',
	    arrayTag = '[object Array]',
	    boolTag = '[object Boolean]',
	    dateTag = '[object Date]',
	    errorTag = '[object Error]',
	    funcTag = '[object Function]',
	    mapTag = '[object Map]',
	    numberTag = '[object Number]',
	    objectTag = '[object Object]',
	    regexpTag = '[object RegExp]',
	    setTag = '[object Set]',
	    stringTag = '[object String]',
	    weakMapTag = '[object WeakMap]';

	var arrayBufferTag = '[object ArrayBuffer]',
	    dataViewTag = '[object DataView]',
	    float32Tag = '[object Float32Array]',
	    float64Tag = '[object Float64Array]',
	    int8Tag = '[object Int8Array]',
	    int16Tag = '[object Int16Array]',
	    int32Tag = '[object Int32Array]',
	    uint8Tag = '[object Uint8Array]',
	    uint8ClampedTag = '[object Uint8ClampedArray]',
	    uint16Tag = '[object Uint16Array]',
	    uint32Tag = '[object Uint32Array]';

	/** Used to identify `toStringTag` values of typed arrays. */
	var typedArrayTags = {};
	typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
	typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
	typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
	typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
	typedArrayTags[uint32Tag] = true;
	typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
	typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
	typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
	typedArrayTags[errorTag] = typedArrayTags[funcTag] =
	typedArrayTags[mapTag] = typedArrayTags[numberTag] =
	typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
	typedArrayTags[setTag] = typedArrayTags[stringTag] =
	typedArrayTags[weakMapTag] = false;

	/**
	 * The base implementation of `_.isTypedArray` without Node.js optimizations.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	 */
	function baseIsTypedArray(value) {
	  return isObjectLike(value) &&
	    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
	}

	_baseIsTypedArray = baseIsTypedArray;
	return _baseIsTypedArray;
}

/**
 * The base implementation of `_.unary` without support for storing metadata.
 *
 * @private
 * @param {Function} func The function to cap arguments for.
 * @returns {Function} Returns the new capped function.
 */

var _baseUnary;
var hasRequired_baseUnary;

function require_baseUnary () {
	if (hasRequired_baseUnary) return _baseUnary;
	hasRequired_baseUnary = 1;
	function baseUnary(func) {
	  return function(value) {
	    return func(value);
	  };
	}

	_baseUnary = baseUnary;
	return _baseUnary;
}

var _nodeUtil = {exports: {}};

_nodeUtil.exports;

var hasRequired_nodeUtil;

function require_nodeUtil () {
	if (hasRequired_nodeUtil) return _nodeUtil.exports;
	hasRequired_nodeUtil = 1;
	(function (module, exports) {
		var freeGlobal = require_freeGlobal();

		/** Detect free variable `exports`. */
		var freeExports = exports && !exports.nodeType && exports;

		/** Detect free variable `module`. */
		var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;

		/** Detect the popular CommonJS extension `module.exports`. */
		var moduleExports = freeModule && freeModule.exports === freeExports;

		/** Detect free variable `process` from Node.js. */
		var freeProcess = moduleExports && freeGlobal.process;

		/** Used to access faster Node.js helpers. */
		var nodeUtil = (function() {
		  try {
		    // Use `util.types` for Node.js 10+.
		    var types = freeModule && freeModule.require && freeModule.require('util').types;

		    if (types) {
		      return types;
		    }

		    // Legacy `process.binding('util')` for Node.js < 10.
		    return freeProcess && freeProcess.binding && freeProcess.binding('util');
		  } catch (e) {}
		}());

		module.exports = nodeUtil; 
	} (_nodeUtil, _nodeUtil.exports));
	return _nodeUtil.exports;
}

var isTypedArray_1;
var hasRequiredIsTypedArray;

function requireIsTypedArray () {
	if (hasRequiredIsTypedArray) return isTypedArray_1;
	hasRequiredIsTypedArray = 1;
	var baseIsTypedArray = require_baseIsTypedArray(),
	    baseUnary = require_baseUnary(),
	    nodeUtil = require_nodeUtil();

	/* Node.js helper references. */
	var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;

	/**
	 * Checks if `value` is classified as a typed array.
	 *
	 * @static
	 * @memberOf _
	 * @since 3.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	 * @example
	 *
	 * _.isTypedArray(new Uint8Array);
	 * // => true
	 *
	 * _.isTypedArray([]);
	 * // => false
	 */
	var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;

	isTypedArray_1 = isTypedArray;
	return isTypedArray_1;
}

var _arrayLikeKeys;
var hasRequired_arrayLikeKeys;

function require_arrayLikeKeys () {
	if (hasRequired_arrayLikeKeys) return _arrayLikeKeys;
	hasRequired_arrayLikeKeys = 1;
	var baseTimes = require_baseTimes(),
	    isArguments = requireIsArguments(),
	    isArray = requireIsArray(),
	    isBuffer = requireIsBuffer(),
	    isIndex = require_isIndex(),
	    isTypedArray = requireIsTypedArray();

	/** Used for built-in method references. */
	var objectProto = Object.prototype;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/**
	 * Creates an array of the enumerable property names of the array-like `value`.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @param {boolean} inherited Specify returning inherited property names.
	 * @returns {Array} Returns the array of property names.
	 */
	function arrayLikeKeys(value, inherited) {
	  var isArr = isArray(value),
	      isArg = !isArr && isArguments(value),
	      isBuff = !isArr && !isArg && isBuffer(value),
	      isType = !isArr && !isArg && !isBuff && isTypedArray(value),
	      skipIndexes = isArr || isArg || isBuff || isType,
	      result = skipIndexes ? baseTimes(value.length, String) : [],
	      length = result.length;

	  for (var key in value) {
	    if ((inherited || hasOwnProperty.call(value, key)) &&
	        !(skipIndexes && (
	           // Safari 9 has enumerable `arguments.length` in strict mode.
	           key == 'length' ||
	           // Node.js 0.10 has enumerable non-index properties on buffers.
	           (isBuff && (key == 'offset' || key == 'parent')) ||
	           // PhantomJS 2 has enumerable non-index properties on typed arrays.
	           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
	           // Skip index properties.
	           isIndex(key, length)
	        ))) {
	      result.push(key);
	    }
	  }
	  return result;
	}

	_arrayLikeKeys = arrayLikeKeys;
	return _arrayLikeKeys;
}

/** Used for built-in method references. */

var _isPrototype;
var hasRequired_isPrototype;

function require_isPrototype () {
	if (hasRequired_isPrototype) return _isPrototype;
	hasRequired_isPrototype = 1;
	var objectProto = Object.prototype;

	/**
	 * Checks if `value` is likely a prototype object.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
	 */
	function isPrototype(value) {
	  var Ctor = value && value.constructor,
	      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;

	  return value === proto;
	}

	_isPrototype = isPrototype;
	return _isPrototype;
}

/**
 * This function is like
 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
 * except that it includes inherited enumerable properties.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */

var _nativeKeysIn;
var hasRequired_nativeKeysIn;

function require_nativeKeysIn () {
	if (hasRequired_nativeKeysIn) return _nativeKeysIn;
	hasRequired_nativeKeysIn = 1;
	function nativeKeysIn(object) {
	  var result = [];
	  if (object != null) {
	    for (var key in Object(object)) {
	      result.push(key);
	    }
	  }
	  return result;
	}

	_nativeKeysIn = nativeKeysIn;
	return _nativeKeysIn;
}

var _baseKeysIn;
var hasRequired_baseKeysIn;

function require_baseKeysIn () {
	if (hasRequired_baseKeysIn) return _baseKeysIn;
	hasRequired_baseKeysIn = 1;
	var isObject = requireIsObject(),
	    isPrototype = require_isPrototype(),
	    nativeKeysIn = require_nativeKeysIn();

	/** Used for built-in method references. */
	var objectProto = Object.prototype;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/**
	 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 */
	function baseKeysIn(object) {
	  if (!isObject(object)) {
	    return nativeKeysIn(object);
	  }
	  var isProto = isPrototype(object),
	      result = [];

	  for (var key in object) {
	    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
	      result.push(key);
	    }
	  }
	  return result;
	}

	_baseKeysIn = baseKeysIn;
	return _baseKeysIn;
}

var keysIn_1;
var hasRequiredKeysIn;

function requireKeysIn () {
	if (hasRequiredKeysIn) return keysIn_1;
	hasRequiredKeysIn = 1;
	var arrayLikeKeys = require_arrayLikeKeys(),
	    baseKeysIn = require_baseKeysIn(),
	    isArrayLike = requireIsArrayLike();

	/**
	 * Creates an array of the own and inherited enumerable property names of `object`.
	 *
	 * **Note:** Non-object values are coerced to objects.
	 *
	 * @static
	 * @memberOf _
	 * @since 3.0.0
	 * @category Object
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 * @example
	 *
	 * function Foo() {
	 *   this.a = 1;
	 *   this.b = 2;
	 * }
	 *
	 * Foo.prototype.c = 3;
	 *
	 * _.keysIn(new Foo);
	 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
	 */
	function keysIn(object) {
	  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
	}

	keysIn_1 = keysIn;
	return keysIn_1;
}

var defaults_1;
var hasRequiredDefaults;

function requireDefaults () {
	if (hasRequiredDefaults) return defaults_1;
	hasRequiredDefaults = 1;
	var baseRest = require_baseRest(),
	    eq = requireEq(),
	    isIterateeCall = require_isIterateeCall(),
	    keysIn = requireKeysIn();

	/** Used for built-in method references. */
	var objectProto = Object.prototype;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/**
	 * Assigns own and inherited enumerable string keyed properties of source
	 * objects to the destination object for all destination properties that
	 * resolve to `undefined`. Source objects are applied from left to right.
	 * Once a property is set, additional values of the same property are ignored.
	 *
	 * **Note:** This method mutates `object`.
	 *
	 * @static
	 * @since 0.1.0
	 * @memberOf _
	 * @category Object
	 * @param {Object} object The destination object.
	 * @param {...Object} [sources] The source objects.
	 * @returns {Object} Returns `object`.
	 * @see _.defaultsDeep
	 * @example
	 *
	 * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
	 * // => { 'a': 1, 'b': 2 }
	 */
	var defaults = baseRest(function(object, sources) {
	  object = Object(object);

	  var index = -1;
	  var length = sources.length;
	  var guard = length > 2 ? sources[2] : undefined;

	  if (guard && isIterateeCall(sources[0], sources[1], guard)) {
	    length = 1;
	  }

	  while (++index < length) {
	    var source = sources[index];
	    var props = keysIn(source);
	    var propsIndex = -1;
	    var propsLength = props.length;

	    while (++propsIndex < propsLength) {
	      var key = props[propsIndex];
	      var value = object[key];

	      if (value === undefined ||
	          (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
	        object[key] = source[key];
	      }
	    }
	  }

	  return object;
	});

	defaults_1 = defaults;
	return defaults_1;
}

var readable = {exports: {}};

var stream;
var hasRequiredStream;

function requireStream () {
	if (hasRequiredStream) return stream;
	hasRequiredStream = 1;
	stream = require$$0$4;
	return stream;
}

var buffer_list;
var hasRequiredBuffer_list;

function requireBuffer_list () {
	if (hasRequiredBuffer_list) return buffer_list;
	hasRequiredBuffer_list = 1;

	function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
	function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
	function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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, _toPropertyKey(descriptor.key), descriptor); } }
	function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
	function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
	function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (String )(input); }
	var _require = require$$0$6,
	  Buffer = _require.Buffer;
	var _require2 = require$$0$5,
	  inspect = _require2.inspect;
	var custom = inspect && inspect.custom || 'inspect';
	function copyBuffer(src, target, offset) {
	  Buffer.prototype.copy.call(src, target, offset);
	}
	buffer_list = /*#__PURE__*/function () {
	  function BufferList() {
	    _classCallCheck(this, BufferList);
	    this.head = null;
	    this.tail = null;
	    this.length = 0;
	  }
	  _createClass(BufferList, [{
	    key: "push",
	    value: function push(v) {
	      var entry = {
	        data: v,
	        next: null
	      };
	      if (this.length > 0) this.tail.next = entry;else this.head = entry;
	      this.tail = entry;
	      ++this.length;
	    }
	  }, {
	    key: "unshift",
	    value: function unshift(v) {
	      var entry = {
	        data: v,
	        next: this.head
	      };
	      if (this.length === 0) this.tail = entry;
	      this.head = entry;
	      ++this.length;
	    }
	  }, {
	    key: "shift",
	    value: function shift() {
	      if (this.length === 0) return;
	      var ret = this.head.data;
	      if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
	      --this.length;
	      return ret;
	    }
	  }, {
	    key: "clear",
	    value: function clear() {
	      this.head = this.tail = null;
	      this.length = 0;
	    }
	  }, {
	    key: "join",
	    value: function join(s) {
	      if (this.length === 0) return '';
	      var p = this.head;
	      var ret = '' + p.data;
	      while (p = p.next) ret += s + p.data;
	      return ret;
	    }
	  }, {
	    key: "concat",
	    value: function concat(n) {
	      if (this.length === 0) return Buffer.alloc(0);
	      var ret = Buffer.allocUnsafe(n >>> 0);
	      var p = this.head;
	      var i = 0;
	      while (p) {
	        copyBuffer(p.data, ret, i);
	        i += p.data.length;
	        p = p.next;
	      }
	      return ret;
	    }

	    // Consumes a specified amount of bytes or characters from the buffered data.
	  }, {
	    key: "consume",
	    value: function consume(n, hasStrings) {
	      var ret;
	      if (n < this.head.data.length) {
	        // `slice` is the same for buffers and strings.
	        ret = this.head.data.slice(0, n);
	        this.head.data = this.head.data.slice(n);
	      } else if (n === this.head.data.length) {
	        // First chunk is a perfect match.
	        ret = this.shift();
	      } else {
	        // Result spans more than one buffer.
	        ret = hasStrings ? this._getString(n) : this._getBuffer(n);
	      }
	      return ret;
	    }
	  }, {
	    key: "first",
	    value: function first() {
	      return this.head.data;
	    }

	    // Consumes a specified amount of characters from the buffered data.
	  }, {
	    key: "_getString",
	    value: function _getString(n) {
	      var p = this.head;
	      var c = 1;
	      var ret = p.data;
	      n -= ret.length;
	      while (p = p.next) {
	        var str = p.data;
	        var nb = n > str.length ? str.length : n;
	        if (nb === str.length) ret += str;else ret += str.slice(0, n);
	        n -= nb;
	        if (n === 0) {
	          if (nb === str.length) {
	            ++c;
	            if (p.next) this.head = p.next;else this.head = this.tail = null;
	          } else {
	            this.head = p;
	            p.data = str.slice(nb);
	          }
	          break;
	        }
	        ++c;
	      }
	      this.length -= c;
	      return ret;
	    }

	    // Consumes a specified amount of bytes from the buffered data.
	  }, {
	    key: "_getBuffer",
	    value: function _getBuffer(n) {
	      var ret = Buffer.allocUnsafe(n);
	      var p = this.head;
	      var c = 1;
	      p.data.copy(ret);
	      n -= p.data.length;
	      while (p = p.next) {
	        var buf = p.data;
	        var nb = n > buf.length ? buf.length : n;
	        buf.copy(ret, ret.length - n, 0, nb);
	        n -= nb;
	        if (n === 0) {
	          if (nb === buf.length) {
	            ++c;
	            if (p.next) this.head = p.next;else this.head = this.tail = null;
	          } else {
	            this.head = p;
	            p.data = buf.slice(nb);
	          }
	          break;
	        }
	        ++c;
	      }
	      this.length -= c;
	      return ret;
	    }

	    // Make sure the linked list only shows the minimal necessary information.
	  }, {
	    key: custom,
	    value: function value(_, options) {
	      return inspect(this, _objectSpread(_objectSpread({}, options), {}, {
	        // Only inspect one level.
	        depth: 0,
	        // It should not recurse.
	        customInspect: false
	      }));
	    }
	  }]);
	  return BufferList;
	}();
	return buffer_list;
}

var destroy_1;
var hasRequiredDestroy;

function requireDestroy () {
	if (hasRequiredDestroy) return destroy_1;
	hasRequiredDestroy = 1;

	// undocumented cb() API, needed for core, not for public API
	function destroy(err, cb) {
	  var _this = this;
	  var readableDestroyed = this._readableState && this._readableState.destroyed;
	  var writableDestroyed = this._writableState && this._writableState.destroyed;
	  if (readableDestroyed || writableDestroyed) {
	    if (cb) {
	      cb(err);
	    } else if (err) {
	      if (!this._writableState) {
	        process.nextTick(emitErrorNT, this, err);
	      } else if (!this._writableState.errorEmitted) {
	        this._writableState.errorEmitted = true;
	        process.nextTick(emitErrorNT, this, err);
	      }
	    }
	    return this;
	  }

	  // we set destroyed to true before firing error callbacks in order
	  // to make it re-entrance safe in case destroy() is called within callbacks

	  if (this._readableState) {
	    this._readableState.destroyed = true;
	  }

	  // if this is a duplex stream mark the writable part as destroyed as well
	  if (this._writableState) {
	    this._writableState.destroyed = true;
	  }
	  this._destroy(err || null, function (err) {
	    if (!cb && err) {
	      if (!_this._writableState) {
	        process.nextTick(emitErrorAndCloseNT, _this, err);
	      } else if (!_this._writableState.errorEmitted) {
	        _this._writableState.errorEmitted = true;
	        process.nextTick(emitErrorAndCloseNT, _this, err);
	      } else {
	        process.nextTick(emitCloseNT, _this);
	      }
	    } else if (cb) {
	      process.nextTick(emitCloseNT, _this);
	      cb(err);
	    } else {
	      process.nextTick(emitCloseNT, _this);
	    }
	  });
	  return this;
	}
	function emitErrorAndCloseNT(self, err) {
	  emitErrorNT(self, err);
	  emitCloseNT(self);
	}
	function emitCloseNT(self) {
	  if (self._writableState && !self._writableState.emitClose) return;
	  if (self._readableState && !self._readableState.emitClose) return;
	  self.emit('close');
	}
	function undestroy() {
	  if (this._readableState) {
	    this._readableState.destroyed = false;
	    this._readableState.reading = false;
	    this._readableState.ended = false;
	    this._readableState.endEmitted = false;
	  }
	  if (this._writableState) {
	    this._writableState.destroyed = false;
	    this._writableState.ended = false;
	    this._writableState.ending = false;
	    this._writableState.finalCalled = false;
	    this._writableState.prefinished = false;
	    this._writableState.finished = false;
	    this._writableState.errorEmitted = false;
	  }
	}
	function emitErrorNT(self, err) {
	  self.emit('error', err);
	}
	function errorOrDestroy(stream, err) {
	  // We have tests that rely on errors being emitted
	  // in the same tick, so changing this is semver major.
	  // For now when you opt-in to autoDestroy we allow
	  // the error to be emitted nextTick. In a future
	  // semver major update we should change the default to this.

	  var rState = stream._readableState;
	  var wState = stream._writableState;
	  if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
	}
	destroy_1 = {
	  destroy: destroy,
	  undestroy: undestroy,
	  errorOrDestroy: errorOrDestroy
	};
	return destroy_1;
}

var errors = {};

var hasRequiredErrors;

function requireErrors () {
	if (hasRequiredErrors) return errors;
	hasRequiredErrors = 1;

	const codes = {};

	function createErrorType(code, message, Base) {
	  if (!Base) {
	    Base = Error;
	  }

	  function getMessage (arg1, arg2, arg3) {
	    if (typeof message === 'string') {
	      return message
	    } else {
	      return message(arg1, arg2, arg3)
	    }
	  }

	  class NodeError extends Base {
	    constructor (arg1, arg2, arg3) {
	      super(getMessage(arg1, arg2, arg3));
	    }
	  }

	  NodeError.prototype.name = Base.name;
	  NodeError.prototype.code = code;

	  codes[code] = NodeError;
	}

	// https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js
	function oneOf(expected, thing) {
	  if (Array.isArray(expected)) {
	    const len = expected.length;
	    expected = expected.map((i) => String(i));
	    if (len > 2) {
	      return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` +
	             expected[len - 1];
	    } else if (len === 2) {
	      return `one of ${thing} ${expected[0]} or ${expected[1]}`;
	    } else {
	      return `of ${thing} ${expected[0]}`;
	    }
	  } else {
	    return `of ${thing} ${String(expected)}`;
	  }
	}

	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
	function startsWith(str, search, pos) {
		return str.substr(0 , search.length) === search;
	}

	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
	function endsWith(str, search, this_len) {
		if (this_len === undefined || this_len > str.length) {
			this_len = str.length;
		}
		return str.substring(this_len - search.length, this_len) === search;
	}

	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
	function includes(str, search, start) {
	  if (typeof start !== 'number') {
	    start = 0;
	  }

	  if (start + search.length > str.length) {
	    return false;
	  } else {
	    return str.indexOf(search, start) !== -1;
	  }
	}

	createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) {
	  return 'The value "' + value + '" is invalid for option "' + name + '"'
	}, TypeError);
	createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) {
	  // determiner: 'must be' or 'must not be'
	  let determiner;
	  if (typeof expected === 'string' && startsWith(expected, 'not ')) {
	    determiner = 'must not be';
	    expected = expected.replace(/^not /, '');
	  } else {
	    determiner = 'must be';
	  }

	  let msg;
	  if (endsWith(name, ' argument')) {
	    // For cases like 'first argument'
	    msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`;
	  } else {
	    const type = includes(name, '.') ? 'property' : 'argument';
	    msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`;
	  }

	  msg += `. Received type ${typeof actual}`;
	  return msg;
	}, TypeError);
	createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF');
	createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) {
	  return 'The ' + name + ' method is not implemented'
	});
	createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close');
	createErrorType('ERR_STREAM_DESTROYED', function (name) {
	  return 'Cannot call ' + name + ' after a stream was destroyed';
	});
	createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times');
	createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable');
	createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end');
	createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError);
	createErrorType('ERR_UNKNOWN_ENCODING', function (arg) {
	  return 'Unknown encoding: ' + arg
	}, TypeError);
	createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event');

	errors.codes = codes;
	return errors;
}

var state;
var hasRequiredState;

function requireState () {
	if (hasRequiredState) return state;
	hasRequiredState = 1;

	var ERR_INVALID_OPT_VALUE = requireErrors().codes.ERR_INVALID_OPT_VALUE;
	function highWaterMarkFrom(options, isDuplex, duplexKey) {
	  return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null;
	}
	function getHighWaterMark(state, options, duplexKey, isDuplex) {
	  var hwm = highWaterMarkFrom(options, isDuplex, duplexKey);
	  if (hwm != null) {
	    if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) {
	      var name = isDuplex ? duplexKey : 'highWaterMark';
	      throw new ERR_INVALID_OPT_VALUE(name, hwm);
	    }
	    return Math.floor(hwm);
	  }

	  // Default value
	  return state.objectMode ? 16 : 16 * 1024;
	}
	state = {
	  getHighWaterMark: getHighWaterMark
	};
	return state;
}

var _stream_writable;
var hasRequired_stream_writable;

function require_stream_writable () {
	if (hasRequired_stream_writable) return _stream_writable;
	hasRequired_stream_writable = 1;

	_stream_writable = Writable;

	// It seems a linked list but it is not
	// there will be only 2 of these for each stream
	function CorkedRequest(state) {
	  var _this = this;
	  this.next = null;
	  this.entry = null;
	  this.finish = function () {
	    onCorkedFinish(_this, state);
	  };
	}
	/* </replacement> */

	/*<replacement>*/
	var Duplex;
	/*</replacement>*/

	Writable.WritableState = WritableState;

	/*<replacement>*/
	var internalUtil = {
	  deprecate: requireNode()
	};
	/*</replacement>*/

	/*<replacement>*/
	var Stream = requireStream();
	/*</replacement>*/

	var Buffer = require$$0$6.Buffer;
	var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
	function _uint8ArrayToBuffer(chunk) {
	  return Buffer.from(chunk);
	}
	function _isUint8Array(obj) {
	  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
	}
	var destroyImpl = requireDestroy();
	var _require = requireState(),
	  getHighWaterMark = _require.getHighWaterMark;
	var _require$codes = requireErrors().codes,
	  ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
	  ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
	  ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
	  ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE,
	  ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED,
	  ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES,
	  ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END,
	  ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING;
	var errorOrDestroy = destroyImpl.errorOrDestroy;
	requireInherits()(Writable, Stream);
	function nop() {}
	function WritableState(options, stream, isDuplex) {
	  Duplex = Duplex || require_stream_duplex();
	  options = options || {};

	  // Duplex streams are both readable and writable, but share
	  // the same options object.
	  // However, some cases require setting options to different
	  // values for the readable and the writable sides of the duplex stream,
	  // e.g. options.readableObjectMode vs. options.writableObjectMode, etc.
	  if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;

	  // object stream flag to indicate whether or not this stream
	  // contains buffers or objects.
	  this.objectMode = !!options.objectMode;
	  if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;

	  // the point at which write() starts returning false
	  // Note: 0 is a valid value, means that we always return false if
	  // the entire buffer is not flushed immediately on write()
	  this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex);

	  // if _final has been called
	  this.finalCalled = false;

	  // drain event flag.
	  this.needDrain = false;
	  // at the start of calling end()
	  this.ending = false;
	  // when end() has been called, and returned
	  this.ended = false;
	  // when 'finish' is emitted
	  this.finished = false;

	  // has it been destroyed
	  this.destroyed = false;

	  // should we decode strings into buffers before passing to _write?
	  // this is here so that some node-core streams can optimize string
	  // handling at a lower level.
	  var noDecode = options.decodeStrings === false;
	  this.decodeStrings = !noDecode;

	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';

	  // not an actual buffer we keep track of, but a measurement
	  // of how much we're waiting to get pushed to some underlying
	  // socket or file.
	  this.length = 0;

	  // a flag to see when we're in the middle of a write.
	  this.writing = false;

	  // when true all writes will be buffered until .uncork() call
	  this.corked = 0;

	  // a flag to be able to tell if the onwrite cb is called immediately,
	  // or on a later tick.  We set this to true at first, because any
	  // actions that shouldn't happen until "later" should generally also
	  // not happen before the first write call.
	  this.sync = true;

	  // a flag to know if we're processing previously buffered items, which
	  // may call the _write() callback in the same tick, so that we don't
	  // end up in an overlapped onwrite situation.
	  this.bufferProcessing = false;

	  // the callback that's passed to _write(chunk,cb)
	  this.onwrite = function (er) {
	    onwrite(stream, er);
	  };

	  // the callback that the user supplies to write(chunk,encoding,cb)
	  this.writecb = null;

	  // the amount that is being written when _write is called.
	  this.writelen = 0;
	  this.bufferedRequest = null;
	  this.lastBufferedRequest = null;

	  // number of pending user-supplied write callbacks
	  // this must be 0 before 'finish' can be emitted
	  this.pendingcb = 0;

	  // emit prefinish if the only thing we're waiting for is _write cbs
	  // This is relevant for synchronous Transform streams
	  this.prefinished = false;

	  // True if the error was already emitted and should not be thrown again
	  this.errorEmitted = false;

	  // Should close be emitted on destroy. Defaults to true.
	  this.emitClose = options.emitClose !== false;

	  // Should .destroy() be called after 'finish' (and potentially 'end')
	  this.autoDestroy = !!options.autoDestroy;

	  // count buffered requests
	  this.bufferedRequestCount = 0;

	  // allocate the first CorkedRequest, there is always
	  // one allocated and free to use, and we maintain at most two
	  this.corkedRequestsFree = new CorkedRequest(this);
	}
	WritableState.prototype.getBuffer = function getBuffer() {
	  var current = this.bufferedRequest;
	  var out = [];
	  while (current) {
	    out.push(current);
	    current = current.next;
	  }
	  return out;
	};
	(function () {
	  try {
	    Object.defineProperty(WritableState.prototype, 'buffer', {
	      get: internalUtil.deprecate(function writableStateBufferGetter() {
	        return this.getBuffer();
	      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
	    });
	  } catch (_) {}
	})();

	// Test _writableState for inheritance to account for Duplex streams,
	// whose prototype chain only points to Readable.
	var realHasInstance;
	if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
	  realHasInstance = Function.prototype[Symbol.hasInstance];
	  Object.defineProperty(Writable, Symbol.hasInstance, {
	    value: function value(object) {
	      if (realHasInstance.call(this, object)) return true;
	      if (this !== Writable) return false;
	      return object && object._writableState instanceof WritableState;
	    }
	  });
	} else {
	  realHasInstance = function realHasInstance(object) {
	    return object instanceof this;
	  };
	}
	function Writable(options) {
	  Duplex = Duplex || require_stream_duplex();

	  // Writable ctor is applied to Duplexes, too.
	  // `realHasInstance` is necessary because using plain `instanceof`
	  // would return false, as no `_writableState` property is attached.

	  // Trying to use the custom `instanceof` for Writable here will also break the
	  // Node.js LazyTransform implementation, which has a non-trivial getter for
	  // `_writableState` that would lead to infinite recursion.

	  // Checking for a Stream.Duplex instance is faster here instead of inside
	  // the WritableState constructor, at least with V8 6.5
	  var isDuplex = this instanceof Duplex;
	  if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options);
	  this._writableState = new WritableState(options, this, isDuplex);

	  // legacy.
	  this.writable = true;
	  if (options) {
	    if (typeof options.write === 'function') this._write = options.write;
	    if (typeof options.writev === 'function') this._writev = options.writev;
	    if (typeof options.destroy === 'function') this._destroy = options.destroy;
	    if (typeof options.final === 'function') this._final = options.final;
	  }
	  Stream.call(this);
	}

	// Otherwise people can pipe Writable streams, which is just wrong.
	Writable.prototype.pipe = function () {
	  errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE());
	};
	function writeAfterEnd(stream, cb) {
	  var er = new ERR_STREAM_WRITE_AFTER_END();
	  // TODO: defer error events consistently everywhere, not just the cb
	  errorOrDestroy(stream, er);
	  process.nextTick(cb, er);
	}

	// Checks that a user-supplied chunk is valid, especially for the particular
	// mode the stream is in. Currently this means that `null` is never accepted
	// and undefined/non-string values are only allowed in object mode.
	function validChunk(stream, state, chunk, cb) {
	  var er;
	  if (chunk === null) {
	    er = new ERR_STREAM_NULL_VALUES();
	  } else if (typeof chunk !== 'string' && !state.objectMode) {
	    er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
	  }
	  if (er) {
	    errorOrDestroy(stream, er);
	    process.nextTick(cb, er);
	    return false;
	  }
	  return true;
	}
	Writable.prototype.write = function (chunk, encoding, cb) {
	  var state = this._writableState;
	  var ret = false;
	  var isBuf = !state.objectMode && _isUint8Array(chunk);
	  if (isBuf && !Buffer.isBuffer(chunk)) {
	    chunk = _uint8ArrayToBuffer(chunk);
	  }
	  if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }
	  if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
	  if (typeof cb !== 'function') cb = nop;
	  if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
	    state.pendingcb++;
	    ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
	  }
	  return ret;
	};
	Writable.prototype.cork = function () {
	  this._writableState.corked++;
	};
	Writable.prototype.uncork = function () {
	  var state = this._writableState;
	  if (state.corked) {
	    state.corked--;
	    if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
	  }
	};
	Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
	  // node::ParseEncoding() requires lower case.
	  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
	  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding);
	  this._writableState.defaultEncoding = encoding;
	  return this;
	};
	Object.defineProperty(Writable.prototype, 'writableBuffer', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._writableState && this._writableState.getBuffer();
	  }
	});
	function decodeChunk(state, chunk, encoding) {
	  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
	    chunk = Buffer.from(chunk, encoding);
	  }
	  return chunk;
	}
	Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._writableState.highWaterMark;
	  }
	});

	// if we're already writing something, then just put this
	// in the queue, and wait our turn.  Otherwise, call _write
	// If we return false, then we need a drain event, so set that flag.
	function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
	  if (!isBuf) {
	    var newChunk = decodeChunk(state, chunk, encoding);
	    if (chunk !== newChunk) {
	      isBuf = true;
	      encoding = 'buffer';
	      chunk = newChunk;
	    }
	  }
	  var len = state.objectMode ? 1 : chunk.length;
	  state.length += len;
	  var ret = state.length < state.highWaterMark;
	  // we must ensure that previous needDrain will not be reset to false.
	  if (!ret) state.needDrain = true;
	  if (state.writing || state.corked) {
	    var last = state.lastBufferedRequest;
	    state.lastBufferedRequest = {
	      chunk: chunk,
	      encoding: encoding,
	      isBuf: isBuf,
	      callback: cb,
	      next: null
	    };
	    if (last) {
	      last.next = state.lastBufferedRequest;
	    } else {
	      state.bufferedRequest = state.lastBufferedRequest;
	    }
	    state.bufferedRequestCount += 1;
	  } else {
	    doWrite(stream, state, false, len, chunk, encoding, cb);
	  }
	  return ret;
	}
	function doWrite(stream, state, writev, len, chunk, encoding, cb) {
	  state.writelen = len;
	  state.writecb = cb;
	  state.writing = true;
	  state.sync = true;
	  if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
	  state.sync = false;
	}
	function onwriteError(stream, state, sync, er, cb) {
	  --state.pendingcb;
	  if (sync) {
	    // defer the callback if we are being called synchronously
	    // to avoid piling up things on the stack
	    process.nextTick(cb, er);
	    // this can emit finish, and it will always happen
	    // after error
	    process.nextTick(finishMaybe, stream, state);
	    stream._writableState.errorEmitted = true;
	    errorOrDestroy(stream, er);
	  } else {
	    // the caller expect this to happen before if
	    // it is async
	    cb(er);
	    stream._writableState.errorEmitted = true;
	    errorOrDestroy(stream, er);
	    // this can emit finish, but finish must
	    // always follow error
	    finishMaybe(stream, state);
	  }
	}
	function onwriteStateUpdate(state) {
	  state.writing = false;
	  state.writecb = null;
	  state.length -= state.writelen;
	  state.writelen = 0;
	}
	function onwrite(stream, er) {
	  var state = stream._writableState;
	  var sync = state.sync;
	  var cb = state.writecb;
	  if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK();
	  onwriteStateUpdate(state);
	  if (er) onwriteError(stream, state, sync, er, cb);else {
	    // Check if we're actually ready to finish, but don't emit yet
	    var finished = needFinish(state) || stream.destroyed;
	    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
	      clearBuffer(stream, state);
	    }
	    if (sync) {
	      process.nextTick(afterWrite, stream, state, finished, cb);
	    } else {
	      afterWrite(stream, state, finished, cb);
	    }
	  }
	}
	function afterWrite(stream, state, finished, cb) {
	  if (!finished) onwriteDrain(stream, state);
	  state.pendingcb--;
	  cb();
	  finishMaybe(stream, state);
	}

	// Must force callback to be called on nextTick, so that we don't
	// emit 'drain' before the write() consumer gets the 'false' return
	// value, and has a chance to attach a 'drain' listener.
	function onwriteDrain(stream, state) {
	  if (state.length === 0 && state.needDrain) {
	    state.needDrain = false;
	    stream.emit('drain');
	  }
	}

	// if there's something in the buffer waiting, then process it
	function clearBuffer(stream, state) {
	  state.bufferProcessing = true;
	  var entry = state.bufferedRequest;
	  if (stream._writev && entry && entry.next) {
	    // Fast case, write everything using _writev()
	    var l = state.bufferedRequestCount;
	    var buffer = new Array(l);
	    var holder = state.corkedRequestsFree;
	    holder.entry = entry;
	    var count = 0;
	    var allBuffers = true;
	    while (entry) {
	      buffer[count] = entry;
	      if (!entry.isBuf) allBuffers = false;
	      entry = entry.next;
	      count += 1;
	    }
	    buffer.allBuffers = allBuffers;
	    doWrite(stream, state, true, state.length, buffer, '', holder.finish);

	    // doWrite is almost always async, defer these to save a bit of time
	    // as the hot path ends with doWrite
	    state.pendingcb++;
	    state.lastBufferedRequest = null;
	    if (holder.next) {
	      state.corkedRequestsFree = holder.next;
	      holder.next = null;
	    } else {
	      state.corkedRequestsFree = new CorkedRequest(state);
	    }
	    state.bufferedRequestCount = 0;
	  } else {
	    // Slow case, write chunks one-by-one
	    while (entry) {
	      var chunk = entry.chunk;
	      var encoding = entry.encoding;
	      var cb = entry.callback;
	      var len = state.objectMode ? 1 : chunk.length;
	      doWrite(stream, state, false, len, chunk, encoding, cb);
	      entry = entry.next;
	      state.bufferedRequestCount--;
	      // if we didn't call the onwrite immediately, then
	      // it means that we need to wait until it does.
	      // also, that means that the chunk and cb are currently
	      // being processed, so move the buffer counter past them.
	      if (state.writing) {
	        break;
	      }
	    }
	    if (entry === null) state.lastBufferedRequest = null;
	  }
	  state.bufferedRequest = entry;
	  state.bufferProcessing = false;
	}
	Writable.prototype._write = function (chunk, encoding, cb) {
	  cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()'));
	};
	Writable.prototype._writev = null;
	Writable.prototype.end = function (chunk, encoding, cb) {
	  var state = this._writableState;
	  if (typeof chunk === 'function') {
	    cb = chunk;
	    chunk = null;
	    encoding = null;
	  } else if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }
	  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);

	  // .end() fully uncorks
	  if (state.corked) {
	    state.corked = 1;
	    this.uncork();
	  }

	  // ignore unnecessary end() calls.
	  if (!state.ending) endWritable(this, state, cb);
	  return this;
	};
	Object.defineProperty(Writable.prototype, 'writableLength', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._writableState.length;
	  }
	});
	function needFinish(state) {
	  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
	}
	function callFinal(stream, state) {
	  stream._final(function (err) {
	    state.pendingcb--;
	    if (err) {
	      errorOrDestroy(stream, err);
	    }
	    state.prefinished = true;
	    stream.emit('prefinish');
	    finishMaybe(stream, state);
	  });
	}
	function prefinish(stream, state) {
	  if (!state.prefinished && !state.finalCalled) {
	    if (typeof stream._final === 'function' && !state.destroyed) {
	      state.pendingcb++;
	      state.finalCalled = true;
	      process.nextTick(callFinal, stream, state);
	    } else {
	      state.prefinished = true;
	      stream.emit('prefinish');
	    }
	  }
	}
	function finishMaybe(stream, state) {
	  var need = needFinish(state);
	  if (need) {
	    prefinish(stream, state);
	    if (state.pendingcb === 0) {
	      state.finished = true;
	      stream.emit('finish');
	      if (state.autoDestroy) {
	        // In case of duplex streams we need a way to detect
	        // if the readable side is ready for autoDestroy as well
	        var rState = stream._readableState;
	        if (!rState || rState.autoDestroy && rState.endEmitted) {
	          stream.destroy();
	        }
	      }
	    }
	  }
	  return need;
	}
	function endWritable(stream, state, cb) {
	  state.ending = true;
	  finishMaybe(stream, state);
	  if (cb) {
	    if (state.finished) process.nextTick(cb);else stream.once('finish', cb);
	  }
	  state.ended = true;
	  stream.writable = false;
	}
	function onCorkedFinish(corkReq, state, err) {
	  var entry = corkReq.entry;
	  corkReq.entry = null;
	  while (entry) {
	    var cb = entry.callback;
	    state.pendingcb--;
	    cb(err);
	    entry = entry.next;
	  }

	  // reuse the free corkReq.
	  state.corkedRequestsFree.next = corkReq;
	}
	Object.defineProperty(Writable.prototype, 'destroyed', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    if (this._writableState === undefined) {
	      return false;
	    }
	    return this._writableState.destroyed;
	  },
	  set: function set(value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (!this._writableState) {
	      return;
	    }

	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._writableState.destroyed = value;
	  }
	});
	Writable.prototype.destroy = destroyImpl.destroy;
	Writable.prototype._undestroy = destroyImpl.undestroy;
	Writable.prototype._destroy = function (err, cb) {
	  cb(err);
	};
	return _stream_writable;
}

var _stream_duplex;
var hasRequired_stream_duplex;

function require_stream_duplex () {
	if (hasRequired_stream_duplex) return _stream_duplex;
	hasRequired_stream_duplex = 1;

	/*<replacement>*/
	var objectKeys = Object.keys || function (obj) {
	  var keys = [];
	  for (var key in obj) keys.push(key);
	  return keys;
	};
	/*</replacement>*/

	_stream_duplex = Duplex;
	var Readable = require_stream_readable();
	var Writable = require_stream_writable();
	requireInherits()(Duplex, Readable);
	{
	  // Allow the keys array to be GC'ed.
	  var keys = objectKeys(Writable.prototype);
	  for (var v = 0; v < keys.length; v++) {
	    var method = keys[v];
	    if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
	  }
	}
	function Duplex(options) {
	  if (!(this instanceof Duplex)) return new Duplex(options);
	  Readable.call(this, options);
	  Writable.call(this, options);
	  this.allowHalfOpen = true;
	  if (options) {
	    if (options.readable === false) this.readable = false;
	    if (options.writable === false) this.writable = false;
	    if (options.allowHalfOpen === false) {
	      this.allowHalfOpen = false;
	      this.once('end', onend);
	    }
	  }
	}
	Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._writableState.highWaterMark;
	  }
	});
	Object.defineProperty(Duplex.prototype, 'writableBuffer', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._writableState && this._writableState.getBuffer();
	  }
	});
	Object.defineProperty(Duplex.prototype, 'writableLength', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._writableState.length;
	  }
	});

	// the no-half-open enforcer
	function onend() {
	  // If the writable side ended, then we're ok.
	  if (this._writableState.ended) return;

	  // no more data can be written.
	  // But allow more writes to happen in this tick.
	  process.nextTick(onEndNT, this);
	}
	function onEndNT(self) {
	  self.end();
	}
	Object.defineProperty(Duplex.prototype, 'destroyed', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    if (this._readableState === undefined || this._writableState === undefined) {
	      return false;
	    }
	    return this._readableState.destroyed && this._writableState.destroyed;
	  },
	  set: function set(value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (this._readableState === undefined || this._writableState === undefined) {
	      return;
	    }

	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._readableState.destroyed = value;
	    this._writableState.destroyed = value;
	  }
	});
	return _stream_duplex;
}

var string_decoder = {};

var safeBuffer = {exports: {}};

/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */

var hasRequiredSafeBuffer;

function requireSafeBuffer () {
	if (hasRequiredSafeBuffer) return safeBuffer.exports;
	hasRequiredSafeBuffer = 1;
	(function (module, exports) {
		/* eslint-disable node/no-deprecated-api */
		var buffer = require$$0$6;
		var Buffer = buffer.Buffer;

		// alternative to using Object.keys for old browsers
		function copyProps (src, dst) {
		  for (var key in src) {
		    dst[key] = src[key];
		  }
		}
		if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
		  module.exports = buffer;
		} else {
		  // Copy properties from require('buffer')
		  copyProps(buffer, exports);
		  exports.Buffer = SafeBuffer;
		}

		function SafeBuffer (arg, encodingOrOffset, length) {
		  return Buffer(arg, encodingOrOffset, length)
		}

		SafeBuffer.prototype = Object.create(Buffer.prototype);

		// Copy static methods from Buffer
		copyProps(Buffer, SafeBuffer);

		SafeBuffer.from = function (arg, encodingOrOffset, length) {
		  if (typeof arg === 'number') {
		    throw new TypeError('Argument must not be a number')
		  }
		  return Buffer(arg, encodingOrOffset, length)
		};

		SafeBuffer.alloc = function (size, fill, encoding) {
		  if (typeof size !== 'number') {
		    throw new TypeError('Argument must be a number')
		  }
		  var buf = Buffer(size);
		  if (fill !== undefined) {
		    if (typeof encoding === 'string') {
		      buf.fill(fill, encoding);
		    } else {
		      buf.fill(fill);
		    }
		  } else {
		    buf.fill(0);
		  }
		  return buf
		};

		SafeBuffer.allocUnsafe = function (size) {
		  if (typeof size !== 'number') {
		    throw new TypeError('Argument must be a number')
		  }
		  return Buffer(size)
		};

		SafeBuffer.allocUnsafeSlow = function (size) {
		  if (typeof size !== 'number') {
		    throw new TypeError('Argument must be a number')
		  }
		  return buffer.SlowBuffer(size)
		}; 
	} (safeBuffer, safeBuffer.exports));
	return safeBuffer.exports;
}

var hasRequiredString_decoder;

function requireString_decoder () {
	if (hasRequiredString_decoder) return string_decoder;
	hasRequiredString_decoder = 1;

	/*<replacement>*/

	var Buffer = requireSafeBuffer().Buffer;
	/*</replacement>*/

	var isEncoding = Buffer.isEncoding || function (encoding) {
	  encoding = '' + encoding;
	  switch (encoding && encoding.toLowerCase()) {
	    case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
	      return true;
	    default:
	      return false;
	  }
	};

	function _normalizeEncoding(enc) {
	  if (!enc) return 'utf8';
	  var retried;
	  while (true) {
	    switch (enc) {
	      case 'utf8':
	      case 'utf-8':
	        return 'utf8';
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return 'utf16le';
	      case 'latin1':
	      case 'binary':
	        return 'latin1';
	      case 'base64':
	      case 'ascii':
	      case 'hex':
	        return enc;
	      default:
	        if (retried) return; // undefined
	        enc = ('' + enc).toLowerCase();
	        retried = true;
	    }
	  }
	}
	// Do not cache `Buffer.isEncoding` when checking encoding names as some
	// modules monkey-patch it to support additional encodings
	function normalizeEncoding(enc) {
	  var nenc = _normalizeEncoding(enc);
	  if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
	  return nenc || enc;
	}

	// StringDecoder provides an interface for efficiently splitting a series of
	// buffers into a series of JS strings without breaking apart multi-byte
	// characters.
	string_decoder.StringDecoder = StringDecoder;
	function StringDecoder(encoding) {
	  this.encoding = normalizeEncoding(encoding);
	  var nb;
	  switch (this.encoding) {
	    case 'utf16le':
	      this.text = utf16Text;
	      this.end = utf16End;
	      nb = 4;
	      break;
	    case 'utf8':
	      this.fillLast = utf8FillLast;
	      nb = 4;
	      break;
	    case 'base64':
	      this.text = base64Text;
	      this.end = base64End;
	      nb = 3;
	      break;
	    default:
	      this.write = simpleWrite;
	      this.end = simpleEnd;
	      return;
	  }
	  this.lastNeed = 0;
	  this.lastTotal = 0;
	  this.lastChar = Buffer.allocUnsafe(nb);
	}

	StringDecoder.prototype.write = function (buf) {
	  if (buf.length === 0) return '';
	  var r;
	  var i;
	  if (this.lastNeed) {
	    r = this.fillLast(buf);
	    if (r === undefined) return '';
	    i = this.lastNeed;
	    this.lastNeed = 0;
	  } else {
	    i = 0;
	  }
	  if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
	  return r || '';
	};

	StringDecoder.prototype.end = utf8End;

	// Returns only complete characters in a Buffer
	StringDecoder.prototype.text = utf8Text;

	// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
	StringDecoder.prototype.fillLast = function (buf) {
	  if (this.lastNeed <= buf.length) {
	    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
	    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
	  }
	  buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
	  this.lastNeed -= buf.length;
	};

	// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
	// continuation byte. If an invalid byte is detected, -2 is returned.
	function utf8CheckByte(byte) {
	  if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
	  return byte >> 6 === 0x02 ? -1 : -2;
	}

	// Checks at most 3 bytes at the end of a Buffer in order to detect an
	// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
	// needed to complete the UTF-8 character (if applicable) are returned.
	function utf8CheckIncomplete(self, buf, i) {
	  var j = buf.length - 1;
	  if (j < i) return 0;
	  var nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) self.lastNeed = nb - 1;
	    return nb;
	  }
	  if (--j < i || nb === -2) return 0;
	  nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) self.lastNeed = nb - 2;
	    return nb;
	  }
	  if (--j < i || nb === -2) return 0;
	  nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) {
	      if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
	    }
	    return nb;
	  }
	  return 0;
	}

	// Validates as many continuation bytes for a multi-byte UTF-8 character as
	// needed or are available. If we see a non-continuation byte where we expect
	// one, we "replace" the validated continuation bytes we've seen so far with
	// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
	// behavior. The continuation byte check is included three times in the case
	// where all of the continuation bytes for a character exist in the same buffer.
	// It is also done this way as a slight performance increase instead of using a
	// loop.
	function utf8CheckExtraBytes(self, buf, p) {
	  if ((buf[0] & 0xC0) !== 0x80) {
	    self.lastNeed = 0;
	    return '\ufffd';
	  }
	  if (self.lastNeed > 1 && buf.length > 1) {
	    if ((buf[1] & 0xC0) !== 0x80) {
	      self.lastNeed = 1;
	      return '\ufffd';
	    }
	    if (self.lastNeed > 2 && buf.length > 2) {
	      if ((buf[2] & 0xC0) !== 0x80) {
	        self.lastNeed = 2;
	        return '\ufffd';
	      }
	    }
	  }
	}

	// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
	function utf8FillLast(buf) {
	  var p = this.lastTotal - this.lastNeed;
	  var r = utf8CheckExtraBytes(this, buf);
	  if (r !== undefined) return r;
	  if (this.lastNeed <= buf.length) {
	    buf.copy(this.lastChar, p, 0, this.lastNeed);
	    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
	  }
	  buf.copy(this.lastChar, p, 0, buf.length);
	  this.lastNeed -= buf.length;
	}

	// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
	// partial character, the character's bytes are buffered until the required
	// number of bytes are available.
	function utf8Text(buf, i) {
	  var total = utf8CheckIncomplete(this, buf, i);
	  if (!this.lastNeed) return buf.toString('utf8', i);
	  this.lastTotal = total;
	  var end = buf.length - (total - this.lastNeed);
	  buf.copy(this.lastChar, 0, end);
	  return buf.toString('utf8', i, end);
	}

	// For UTF-8, a replacement character is added when ending on a partial
	// character.
	function utf8End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) return r + '\ufffd';
	  return r;
	}

	// UTF-16LE typically needs two bytes per character, but even if we have an even
	// number of bytes available, we need to check if we end on a leading/high
	// surrogate. In that case, we need to wait for the next two bytes in order to
	// decode the last character properly.
	function utf16Text(buf, i) {
	  if ((buf.length - i) % 2 === 0) {
	    var r = buf.toString('utf16le', i);
	    if (r) {
	      var c = r.charCodeAt(r.length - 1);
	      if (c >= 0xD800 && c <= 0xDBFF) {
	        this.lastNeed = 2;
	        this.lastTotal = 4;
	        this.lastChar[0] = buf[buf.length - 2];
	        this.lastChar[1] = buf[buf.length - 1];
	        return r.slice(0, -1);
	      }
	    }
	    return r;
	  }
	  this.lastNeed = 1;
	  this.lastTotal = 2;
	  this.lastChar[0] = buf[buf.length - 1];
	  return buf.toString('utf16le', i, buf.length - 1);
	}

	// For UTF-16LE we do not explicitly append special replacement characters if we
	// end on a partial character, we simply let v8 handle that.
	function utf16End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) {
	    var end = this.lastTotal - this.lastNeed;
	    return r + this.lastChar.toString('utf16le', 0, end);
	  }
	  return r;
	}

	function base64Text(buf, i) {
	  var n = (buf.length - i) % 3;
	  if (n === 0) return buf.toString('base64', i);
	  this.lastNeed = 3 - n;
	  this.lastTotal = 3;
	  if (n === 1) {
	    this.lastChar[0] = buf[buf.length - 1];
	  } else {
	    this.lastChar[0] = buf[buf.length - 2];
	    this.lastChar[1] = buf[buf.length - 1];
	  }
	  return buf.toString('base64', i, buf.length - n);
	}

	function base64End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
	  return r;
	}

	// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
	function simpleWrite(buf) {
	  return buf.toString(this.encoding);
	}

	function simpleEnd(buf) {
	  return buf && buf.length ? this.write(buf) : '';
	}
	return string_decoder;
}

var endOfStream;
var hasRequiredEndOfStream;

function requireEndOfStream () {
	if (hasRequiredEndOfStream) return endOfStream;
	hasRequiredEndOfStream = 1;

	var ERR_STREAM_PREMATURE_CLOSE = requireErrors().codes.ERR_STREAM_PREMATURE_CLOSE;
	function once(callback) {
	  var called = false;
	  return function () {
	    if (called) return;
	    called = true;
	    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
	      args[_key] = arguments[_key];
	    }
	    callback.apply(this, args);
	  };
	}
	function noop() {}
	function isRequest(stream) {
	  return stream.setHeader && typeof stream.abort === 'function';
	}
	function eos(stream, opts, callback) {
	  if (typeof opts === 'function') return eos(stream, null, opts);
	  if (!opts) opts = {};
	  callback = once(callback || noop);
	  var readable = opts.readable || opts.readable !== false && stream.readable;
	  var writable = opts.writable || opts.writable !== false && stream.writable;
	  var onlegacyfinish = function onlegacyfinish() {
	    if (!stream.writable) onfinish();
	  };
	  var writableEnded = stream._writableState && stream._writableState.finished;
	  var onfinish = function onfinish() {
	    writable = false;
	    writableEnded = true;
	    if (!readable) callback.call(stream);
	  };
	  var readableEnded = stream._readableState && stream._readableState.endEmitted;
	  var onend = function onend() {
	    readable = false;
	    readableEnded = true;
	    if (!writable) callback.call(stream);
	  };
	  var onerror = function onerror(err) {
	    callback.call(stream, err);
	  };
	  var onclose = function onclose() {
	    var err;
	    if (readable && !readableEnded) {
	      if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
	      return callback.call(stream, err);
	    }
	    if (writable && !writableEnded) {
	      if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
	      return callback.call(stream, err);
	    }
	  };
	  var onrequest = function onrequest() {
	    stream.req.on('finish', onfinish);
	  };
	  if (isRequest(stream)) {
	    stream.on('complete', onfinish);
	    stream.on('abort', onclose);
	    if (stream.req) onrequest();else stream.on('request', onrequest);
	  } else if (writable && !stream._writableState) {
	    // legacy streams
	    stream.on('end', onlegacyfinish);
	    stream.on('close', onlegacyfinish);
	  }
	  stream.on('end', onend);
	  stream.on('finish', onfinish);
	  if (opts.error !== false) stream.on('error', onerror);
	  stream.on('close', onclose);
	  return function () {
	    stream.removeListener('complete', onfinish);
	    stream.removeListener('abort', onclose);
	    stream.removeListener('request', onrequest);
	    if (stream.req) stream.req.removeListener('finish', onfinish);
	    stream.removeListener('end', onlegacyfinish);
	    stream.removeListener('close', onlegacyfinish);
	    stream.removeListener('finish', onfinish);
	    stream.removeListener('end', onend);
	    stream.removeListener('error', onerror);
	    stream.removeListener('close', onclose);
	  };
	}
	endOfStream = eos;
	return endOfStream;
}

var async_iterator;
var hasRequiredAsync_iterator;

function requireAsync_iterator () {
	if (hasRequiredAsync_iterator) return async_iterator;
	hasRequiredAsync_iterator = 1;

	var _Object$setPrototypeO;
	function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
	function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
	function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
	var finished = requireEndOfStream();
	var kLastResolve = Symbol('lastResolve');
	var kLastReject = Symbol('lastReject');
	var kError = Symbol('error');
	var kEnded = Symbol('ended');
	var kLastPromise = Symbol('lastPromise');
	var kHandlePromise = Symbol('handlePromise');
	var kStream = Symbol('stream');
	function createIterResult(value, done) {
	  return {
	    value: value,
	    done: done
	  };
	}
	function readAndResolve(iter) {
	  var resolve = iter[kLastResolve];
	  if (resolve !== null) {
	    var data = iter[kStream].read();
	    // we defer if data is null
	    // we can be expecting either 'end' or
	    // 'error'
	    if (data !== null) {
	      iter[kLastPromise] = null;
	      iter[kLastResolve] = null;
	      iter[kLastReject] = null;
	      resolve(createIterResult(data, false));
	    }
	  }
	}
	function onReadable(iter) {
	  // we wait for the next tick, because it might
	  // emit an error with process.nextTick
	  process.nextTick(readAndResolve, iter);
	}
	function wrapForNext(lastPromise, iter) {
	  return function (resolve, reject) {
	    lastPromise.then(function () {
	      if (iter[kEnded]) {
	        resolve(createIterResult(undefined, true));
	        return;
	      }
	      iter[kHandlePromise](resolve, reject);
	    }, reject);
	  };
	}
	var AsyncIteratorPrototype = Object.getPrototypeOf(function () {});
	var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = {
	  get stream() {
	    return this[kStream];
	  },
	  next: function next() {
	    var _this = this;
	    // if we have detected an error in the meanwhile
	    // reject straight away
	    var error = this[kError];
	    if (error !== null) {
	      return Promise.reject(error);
	    }
	    if (this[kEnded]) {
	      return Promise.resolve(createIterResult(undefined, true));
	    }
	    if (this[kStream].destroyed) {
	      // We need to defer via nextTick because if .destroy(err) is
	      // called, the error will be emitted via nextTick, and
	      // we cannot guarantee that there is no error lingering around
	      // waiting to be emitted.
	      return new Promise(function (resolve, reject) {
	        process.nextTick(function () {
	          if (_this[kError]) {
	            reject(_this[kError]);
	          } else {
	            resolve(createIterResult(undefined, true));
	          }
	        });
	      });
	    }

	    // if we have multiple next() calls
	    // we will wait for the previous Promise to finish
	    // this logic is optimized to support for await loops,
	    // where next() is only called once at a time
	    var lastPromise = this[kLastPromise];
	    var promise;
	    if (lastPromise) {
	      promise = new Promise(wrapForNext(lastPromise, this));
	    } else {
	      // fast path needed to support multiple this.push()
	      // without triggering the next() queue
	      var data = this[kStream].read();
	      if (data !== null) {
	        return Promise.resolve(createIterResult(data, false));
	      }
	      promise = new Promise(this[kHandlePromise]);
	    }
	    this[kLastPromise] = promise;
	    return promise;
	  }
	}, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () {
	  return this;
	}), _defineProperty(_Object$setPrototypeO, "return", function _return() {
	  var _this2 = this;
	  // destroy(err, cb) is a private API
	  // we can guarantee we have that here, because we control the
	  // Readable class this is attached to
	  return new Promise(function (resolve, reject) {
	    _this2[kStream].destroy(null, function (err) {
	      if (err) {
	        reject(err);
	        return;
	      }
	      resolve(createIterResult(undefined, true));
	    });
	  });
	}), _Object$setPrototypeO), AsyncIteratorPrototype);
	var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) {
	  var _Object$create;
	  var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, {
	    value: stream,
	    writable: true
	  }), _defineProperty(_Object$create, kLastResolve, {
	    value: null,
	    writable: true
	  }), _defineProperty(_Object$create, kLastReject, {
	    value: null,
	    writable: true
	  }), _defineProperty(_Object$create, kError, {
	    value: null,
	    writable: true
	  }), _defineProperty(_Object$create, kEnded, {
	    value: stream._readableState.endEmitted,
	    writable: true
	  }), _defineProperty(_Object$create, kHandlePromise, {
	    value: function value(resolve, reject) {
	      var data = iterator[kStream].read();
	      if (data) {
	        iterator[kLastPromise] = null;
	        iterator[kLastResolve] = null;
	        iterator[kLastReject] = null;
	        resolve(createIterResult(data, false));
	      } else {
	        iterator[kLastResolve] = resolve;
	        iterator[kLastReject] = reject;
	      }
	    },
	    writable: true
	  }), _Object$create));
	  iterator[kLastPromise] = null;
	  finished(stream, function (err) {
	    if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
	      var reject = iterator[kLastReject];
	      // reject if we are waiting for data in the Promise
	      // returned by next() and store the error
	      if (reject !== null) {
	        iterator[kLastPromise] = null;
	        iterator[kLastResolve] = null;
	        iterator[kLastReject] = null;
	        reject(err);
	      }
	      iterator[kError] = err;
	      return;
	    }
	    var resolve = iterator[kLastResolve];
	    if (resolve !== null) {
	      iterator[kLastPromise] = null;
	      iterator[kLastResolve] = null;
	      iterator[kLastReject] = null;
	      resolve(createIterResult(undefined, true));
	    }
	    iterator[kEnded] = true;
	  });
	  stream.on('readable', onReadable.bind(null, iterator));
	  return iterator;
	};
	async_iterator = createReadableStreamAsyncIterator;
	return async_iterator;
}

var from_1;
var hasRequiredFrom;

function requireFrom () {
	if (hasRequiredFrom) return from_1;
	hasRequiredFrom = 1;

	function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
	function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
	function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
	function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
	function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
	function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
	function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
	var ERR_INVALID_ARG_TYPE = requireErrors().codes.ERR_INVALID_ARG_TYPE;
	function from(Readable, iterable, opts) {
	  var iterator;
	  if (iterable && typeof iterable.next === 'function') {
	    iterator = iterable;
	  } else if (iterable && iterable[Symbol.asyncIterator]) iterator = iterable[Symbol.asyncIterator]();else if (iterable && iterable[Symbol.iterator]) iterator = iterable[Symbol.iterator]();else throw new ERR_INVALID_ARG_TYPE('iterable', ['Iterable'], iterable);
	  var readable = new Readable(_objectSpread({
	    objectMode: true
	  }, opts));
	  // Reading boolean to protect against _read
	  // being called before last iteration completion.
	  var reading = false;
	  readable._read = function () {
	    if (!reading) {
	      reading = true;
	      next();
	    }
	  };
	  function next() {
	    return _next2.apply(this, arguments);
	  }
	  function _next2() {
	    _next2 = _asyncToGenerator(function* () {
	      try {
	        var _yield$iterator$next = yield iterator.next(),
	          value = _yield$iterator$next.value,
	          done = _yield$iterator$next.done;
	        if (done) {
	          readable.push(null);
	        } else if (readable.push(yield value)) {
	          next();
	        } else {
	          reading = false;
	        }
	      } catch (err) {
	        readable.destroy(err);
	      }
	    });
	    return _next2.apply(this, arguments);
	  }
	  return readable;
	}
	from_1 = from;
	return from_1;
}

var _stream_readable;
var hasRequired_stream_readable;

function require_stream_readable () {
	if (hasRequired_stream_readable) return _stream_readable;
	hasRequired_stream_readable = 1;

	_stream_readable = Readable;

	/*<replacement>*/
	var Duplex;
	/*</replacement>*/

	Readable.ReadableState = ReadableState;

	/*<replacement>*/
	require$$0$1.EventEmitter;
	var EElistenerCount = function EElistenerCount(emitter, type) {
	  return emitter.listeners(type).length;
	};
	/*</replacement>*/

	/*<replacement>*/
	var Stream = requireStream();
	/*</replacement>*/

	var Buffer = require$$0$6.Buffer;
	var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
	function _uint8ArrayToBuffer(chunk) {
	  return Buffer.from(chunk);
	}
	function _isUint8Array(obj) {
	  return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
	}

	/*<replacement>*/
	var debugUtil = require$$0$5;
	var debug;
	if (debugUtil && debugUtil.debuglog) {
	  debug = debugUtil.debuglog('stream');
	} else {
	  debug = function debug() {};
	}
	/*</replacement>*/

	var BufferList = requireBuffer_list();
	var destroyImpl = requireDestroy();
	var _require = requireState(),
	  getHighWaterMark = _require.getHighWaterMark;
	var _require$codes = requireErrors().codes,
	  ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
	  ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF,
	  ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
	  ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;

	// Lazy loaded to improve the startup performance.
	var StringDecoder;
	var createReadableStreamAsyncIterator;
	var from;
	requireInherits()(Readable, Stream);
	var errorOrDestroy = destroyImpl.errorOrDestroy;
	var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
	function prependListener(emitter, event, fn) {
	  // Sadly this is not cacheable as some libraries bundle their own
	  // event emitter implementation with them.
	  if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);

	  // This is a hack to make sure that our error handler is attached before any
	  // userland ones.  NEVER DO THIS. This is here only because this code needs
	  // to continue to work with older versions of Node.js that do not include
	  // the prependListener() method. The goal is to eventually remove this hack.
	  if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
	}
	function ReadableState(options, stream, isDuplex) {
	  Duplex = Duplex || require_stream_duplex();
	  options = options || {};

	  // Duplex streams are both readable and writable, but share
	  // the same options object.
	  // However, some cases require setting options to different
	  // values for the readable and the writable sides of the duplex stream.
	  // These options can be provided separately as readableXXX and writableXXX.
	  if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;

	  // object stream flag. Used to make read(n) ignore n and to
	  // make all the buffer merging and length checks go away
	  this.objectMode = !!options.objectMode;
	  if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;

	  // the point at which it stops calling _read() to fill the buffer
	  // Note: 0 is a valid value, means "don't call _read preemptively ever"
	  this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex);

	  // A linked list is used to store data chunks instead of an array because the
	  // linked list can remove elements from the beginning faster than
	  // array.shift()
	  this.buffer = new BufferList();
	  this.length = 0;
	  this.pipes = null;
	  this.pipesCount = 0;
	  this.flowing = null;
	  this.ended = false;
	  this.endEmitted = false;
	  this.reading = false;

	  // a flag to be able to tell if the event 'readable'/'data' is emitted
	  // immediately, or on a later tick.  We set this to true at first, because
	  // any actions that shouldn't happen until "later" should generally also
	  // not happen before the first read call.
	  this.sync = true;

	  // whenever we return null, then we set a flag to say
	  // that we're awaiting a 'readable' event emission.
	  this.needReadable = false;
	  this.emittedReadable = false;
	  this.readableListening = false;
	  this.resumeScheduled = false;
	  this.paused = true;

	  // Should close be emitted on destroy. Defaults to true.
	  this.emitClose = options.emitClose !== false;

	  // Should .destroy() be called after 'end' (and potentially 'finish')
	  this.autoDestroy = !!options.autoDestroy;

	  // has it been destroyed
	  this.destroyed = false;

	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';

	  // the number of writers that are awaiting a drain event in .pipe()s
	  this.awaitDrain = 0;

	  // if true, a maybeReadMore has been scheduled
	  this.readingMore = false;
	  this.decoder = null;
	  this.encoding = null;
	  if (options.encoding) {
	    if (!StringDecoder) StringDecoder = requireString_decoder().StringDecoder;
	    this.decoder = new StringDecoder(options.encoding);
	    this.encoding = options.encoding;
	  }
	}
	function Readable(options) {
	  Duplex = Duplex || require_stream_duplex();
	  if (!(this instanceof Readable)) return new Readable(options);

	  // Checking for a Stream.Duplex instance is faster here instead of inside
	  // the ReadableState constructor, at least with V8 6.5
	  var isDuplex = this instanceof Duplex;
	  this._readableState = new ReadableState(options, this, isDuplex);

	  // legacy
	  this.readable = true;
	  if (options) {
	    if (typeof options.read === 'function') this._read = options.read;
	    if (typeof options.destroy === 'function') this._destroy = options.destroy;
	  }
	  Stream.call(this);
	}
	Object.defineProperty(Readable.prototype, 'destroyed', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    if (this._readableState === undefined) {
	      return false;
	    }
	    return this._readableState.destroyed;
	  },
	  set: function set(value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (!this._readableState) {
	      return;
	    }

	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._readableState.destroyed = value;
	  }
	});
	Readable.prototype.destroy = destroyImpl.destroy;
	Readable.prototype._undestroy = destroyImpl.undestroy;
	Readable.prototype._destroy = function (err, cb) {
	  cb(err);
	};

	// Manually shove something into the read() buffer.
	// This returns true if the highWaterMark has not been hit yet,
	// similar to how Writable.write() returns true if you should
	// write() some more.
	Readable.prototype.push = function (chunk, encoding) {
	  var state = this._readableState;
	  var skipChunkCheck;
	  if (!state.objectMode) {
	    if (typeof chunk === 'string') {
	      encoding = encoding || state.defaultEncoding;
	      if (encoding !== state.encoding) {
	        chunk = Buffer.from(chunk, encoding);
	        encoding = '';
	      }
	      skipChunkCheck = true;
	    }
	  } else {
	    skipChunkCheck = true;
	  }
	  return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
	};

	// Unshift should *always* be something directly out of read()
	Readable.prototype.unshift = function (chunk) {
	  return readableAddChunk(this, chunk, null, true, false);
	};
	function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
	  debug('readableAddChunk', chunk);
	  var state = stream._readableState;
	  if (chunk === null) {
	    state.reading = false;
	    onEofChunk(stream, state);
	  } else {
	    var er;
	    if (!skipChunkCheck) er = chunkInvalid(state, chunk);
	    if (er) {
	      errorOrDestroy(stream, er);
	    } else if (state.objectMode || chunk && chunk.length > 0) {
	      if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
	        chunk = _uint8ArrayToBuffer(chunk);
	      }
	      if (addToFront) {
	        if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true);
	      } else if (state.ended) {
	        errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF());
	      } else if (state.destroyed) {
	        return false;
	      } else {
	        state.reading = false;
	        if (state.decoder && !encoding) {
	          chunk = state.decoder.write(chunk);
	          if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
	        } else {
	          addChunk(stream, state, chunk, false);
	        }
	      }
	    } else if (!addToFront) {
	      state.reading = false;
	      maybeReadMore(stream, state);
	    }
	  }

	  // We can push more data if we are below the highWaterMark.
	  // Also, if we have no data yet, we can stand some more bytes.
	  // This is to work around cases where hwm=0, such as the repl.
	  return !state.ended && (state.length < state.highWaterMark || state.length === 0);
	}
	function addChunk(stream, state, chunk, addToFront) {
	  if (state.flowing && state.length === 0 && !state.sync) {
	    state.awaitDrain = 0;
	    stream.emit('data', chunk);
	  } else {
	    // update the buffer info.
	    state.length += state.objectMode ? 1 : chunk.length;
	    if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
	    if (state.needReadable) emitReadable(stream);
	  }
	  maybeReadMore(stream, state);
	}
	function chunkInvalid(state, chunk) {
	  var er;
	  if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
	    er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk);
	  }
	  return er;
	}
	Readable.prototype.isPaused = function () {
	  return this._readableState.flowing === false;
	};

	// backwards compatibility.
	Readable.prototype.setEncoding = function (enc) {
	  if (!StringDecoder) StringDecoder = requireString_decoder().StringDecoder;
	  var decoder = new StringDecoder(enc);
	  this._readableState.decoder = decoder;
	  // If setEncoding(null), decoder.encoding equals utf8
	  this._readableState.encoding = this._readableState.decoder.encoding;

	  // Iterate over current buffer to convert already stored Buffers:
	  var p = this._readableState.buffer.head;
	  var content = '';
	  while (p !== null) {
	    content += decoder.write(p.data);
	    p = p.next;
	  }
	  this._readableState.buffer.clear();
	  if (content !== '') this._readableState.buffer.push(content);
	  this._readableState.length = content.length;
	  return this;
	};

	// Don't raise the hwm > 1GB
	var MAX_HWM = 0x40000000;
	function computeNewHighWaterMark(n) {
	  if (n >= MAX_HWM) {
	    // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE.
	    n = MAX_HWM;
	  } else {
	    // Get the next highest power of 2 to prevent increasing hwm excessively in
	    // tiny amounts
	    n--;
	    n |= n >>> 1;
	    n |= n >>> 2;
	    n |= n >>> 4;
	    n |= n >>> 8;
	    n |= n >>> 16;
	    n++;
	  }
	  return n;
	}

	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function howMuchToRead(n, state) {
	  if (n <= 0 || state.length === 0 && state.ended) return 0;
	  if (state.objectMode) return 1;
	  if (n !== n) {
	    // Only flow one buffer at a time
	    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
	  }
	  // If we're asking for more than the current hwm, then raise the hwm.
	  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
	  if (n <= state.length) return n;
	  // Don't have enough
	  if (!state.ended) {
	    state.needReadable = true;
	    return 0;
	  }
	  return state.length;
	}

	// you can override either this method, or the async _read(n) below.
	Readable.prototype.read = function (n) {
	  debug('read', n);
	  n = parseInt(n, 10);
	  var state = this._readableState;
	  var nOrig = n;
	  if (n !== 0) state.emittedReadable = false;

	  // if we're doing read(0) to trigger a readable event, but we
	  // already have a bunch of data in the buffer, then just trigger
	  // the 'readable' event and move on.
	  if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) {
	    debug('read: emitReadable', state.length, state.ended);
	    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
	    return null;
	  }
	  n = howMuchToRead(n, state);

	  // if we've ended, and we're now clear, then finish it up.
	  if (n === 0 && state.ended) {
	    if (state.length === 0) endReadable(this);
	    return null;
	  }

	  // All the actual chunk generation logic needs to be
	  // *below* the call to _read.  The reason is that in certain
	  // synthetic stream cases, such as passthrough streams, _read
	  // may be a completely synchronous operation which may change
	  // the state of the read buffer, providing enough data when
	  // before there was *not* enough.
	  //
	  // So, the steps are:
	  // 1. Figure out what the state of things will be after we do
	  // a read from the buffer.
	  //
	  // 2. If that resulting state will trigger a _read, then call _read.
	  // Note that this may be asynchronous, or synchronous.  Yes, it is
	  // deeply ugly to write APIs this way, but that still doesn't mean
	  // that the Readable class should behave improperly, as streams are
	  // designed to be sync/async agnostic.
	  // Take note if the _read call is sync or async (ie, if the read call
	  // has returned yet), so that we know whether or not it's safe to emit
	  // 'readable' etc.
	  //
	  // 3. Actually pull the requested chunks out of the buffer and return.

	  // if we need a readable event, then we need to do some reading.
	  var doRead = state.needReadable;
	  debug('need readable', doRead);

	  // if we currently have less than the highWaterMark, then also read some
	  if (state.length === 0 || state.length - n < state.highWaterMark) {
	    doRead = true;
	    debug('length less than watermark', doRead);
	  }

	  // however, if we've ended, then there's no point, and if we're already
	  // reading, then it's unnecessary.
	  if (state.ended || state.reading) {
	    doRead = false;
	    debug('reading or ended', doRead);
	  } else if (doRead) {
	    debug('do read');
	    state.reading = true;
	    state.sync = true;
	    // if the length is currently zero, then we *need* a readable event.
	    if (state.length === 0) state.needReadable = true;
	    // call internal read method
	    this._read(state.highWaterMark);
	    state.sync = false;
	    // If _read pushed data synchronously, then `reading` will be false,
	    // and we need to re-evaluate how much data we can return to the user.
	    if (!state.reading) n = howMuchToRead(nOrig, state);
	  }
	  var ret;
	  if (n > 0) ret = fromList(n, state);else ret = null;
	  if (ret === null) {
	    state.needReadable = state.length <= state.highWaterMark;
	    n = 0;
	  } else {
	    state.length -= n;
	    state.awaitDrain = 0;
	  }
	  if (state.length === 0) {
	    // If we have nothing in the buffer, then we want to know
	    // as soon as we *do* get something into the buffer.
	    if (!state.ended) state.needReadable = true;

	    // If we tried to read() past the EOF, then emit end on the next tick.
	    if (nOrig !== n && state.ended) endReadable(this);
	  }
	  if (ret !== null) this.emit('data', ret);
	  return ret;
	};
	function onEofChunk(stream, state) {
	  debug('onEofChunk');
	  if (state.ended) return;
	  if (state.decoder) {
	    var chunk = state.decoder.end();
	    if (chunk && chunk.length) {
	      state.buffer.push(chunk);
	      state.length += state.objectMode ? 1 : chunk.length;
	    }
	  }
	  state.ended = true;
	  if (state.sync) {
	    // if we are sync, wait until next tick to emit the data.
	    // Otherwise we risk emitting data in the flow()
	    // the readable code triggers during a read() call
	    emitReadable(stream);
	  } else {
	    // emit 'readable' now to make sure it gets picked up.
	    state.needReadable = false;
	    if (!state.emittedReadable) {
	      state.emittedReadable = true;
	      emitReadable_(stream);
	    }
	  }
	}

	// Don't emit readable right away in sync mode, because this can trigger
	// another read() call => stack overflow.  This way, it might trigger
	// a nextTick recursion warning, but that's not so bad.
	function emitReadable(stream) {
	  var state = stream._readableState;
	  debug('emitReadable', state.needReadable, state.emittedReadable);
	  state.needReadable = false;
	  if (!state.emittedReadable) {
	    debug('emitReadable', state.flowing);
	    state.emittedReadable = true;
	    process.nextTick(emitReadable_, stream);
	  }
	}
	function emitReadable_(stream) {
	  var state = stream._readableState;
	  debug('emitReadable_', state.destroyed, state.length, state.ended);
	  if (!state.destroyed && (state.length || state.ended)) {
	    stream.emit('readable');
	    state.emittedReadable = false;
	  }

	  // The stream needs another readable event if
	  // 1. It is not flowing, as the flow mechanism will take
	  //    care of it.
	  // 2. It is not ended.
	  // 3. It is below the highWaterMark, so we can schedule
	  //    another readable later.
	  state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark;
	  flow(stream);
	}

	// at this point, the user has presumably seen the 'readable' event,
	// and called read() to consume some data.  that may have triggered
	// in turn another _read(n) call, in which case reading = true if
	// it's in progress.
	// However, if we're not ended, or reading, and the length < hwm,
	// then go ahead and try to read some more preemptively.
	function maybeReadMore(stream, state) {
	  if (!state.readingMore) {
	    state.readingMore = true;
	    process.nextTick(maybeReadMore_, stream, state);
	  }
	}
	function maybeReadMore_(stream, state) {
	  // Attempt to read more data if we should.
	  //
	  // The conditions for reading more data are (one of):
	  // - Not enough data buffered (state.length < state.highWaterMark). The loop
	  //   is responsible for filling the buffer with enough data if such data
	  //   is available. If highWaterMark is 0 and we are not in the flowing mode
	  //   we should _not_ attempt to buffer any extra data. We'll get more data
	  //   when the stream consumer calls read() instead.
	  // - No data in the buffer, and the stream is in flowing mode. In this mode
	  //   the loop below is responsible for ensuring read() is called. Failing to
	  //   call read here would abort the flow and there's no other mechanism for
	  //   continuing the flow if the stream consumer has just subscribed to the
	  //   'data' event.
	  //
	  // In addition to the above conditions to keep reading data, the following
	  // conditions prevent the data from being read:
	  // - The stream has ended (state.ended).
	  // - There is already a pending 'read' operation (state.reading). This is a
	  //   case where the the stream has called the implementation defined _read()
	  //   method, but they are processing the call asynchronously and have _not_
	  //   called push() with new data. In this case we skip performing more
	  //   read()s. The execution ends in this method again after the _read() ends
	  //   up calling push() with more data.
	  while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) {
	    var len = state.length;
	    debug('maybeReadMore read 0');
	    stream.read(0);
	    if (len === state.length)
	      // didn't get any data, stop spinning.
	      break;
	  }
	  state.readingMore = false;
	}

	// abstract method.  to be overridden in specific implementation classes.
	// call cb(er, data) where data is <= n in length.
	// for virtual (non-string, non-buffer) streams, "length" is somewhat
	// arbitrary, and perhaps not very meaningful.
	Readable.prototype._read = function (n) {
	  errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()'));
	};
	Readable.prototype.pipe = function (dest, pipeOpts) {
	  var src = this;
	  var state = this._readableState;
	  switch (state.pipesCount) {
	    case 0:
	      state.pipes = dest;
	      break;
	    case 1:
	      state.pipes = [state.pipes, dest];
	      break;
	    default:
	      state.pipes.push(dest);
	      break;
	  }
	  state.pipesCount += 1;
	  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
	  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
	  var endFn = doEnd ? onend : unpipe;
	  if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn);
	  dest.on('unpipe', onunpipe);
	  function onunpipe(readable, unpipeInfo) {
	    debug('onunpipe');
	    if (readable === src) {
	      if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
	        unpipeInfo.hasUnpiped = true;
	        cleanup();
	      }
	    }
	  }
	  function onend() {
	    debug('onend');
	    dest.end();
	  }

	  // when the dest drains, it reduces the awaitDrain counter
	  // on the source.  This would be more elegant with a .once()
	  // handler in flow(), but adding and removing repeatedly is
	  // too slow.
	  var ondrain = pipeOnDrain(src);
	  dest.on('drain', ondrain);
	  var cleanedUp = false;
	  function cleanup() {
	    debug('cleanup');
	    // cleanup event handlers once the pipe is broken
	    dest.removeListener('close', onclose);
	    dest.removeListener('finish', onfinish);
	    dest.removeListener('drain', ondrain);
	    dest.removeListener('error', onerror);
	    dest.removeListener('unpipe', onunpipe);
	    src.removeListener('end', onend);
	    src.removeListener('end', unpipe);
	    src.removeListener('data', ondata);
	    cleanedUp = true;

	    // if the reader is waiting for a drain event from this
	    // specific writer, then it would cause it to never start
	    // flowing again.
	    // So, if this is awaiting a drain, then we just call it now.
	    // If we don't know, then assume that we are waiting for one.
	    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
	  }
	  src.on('data', ondata);
	  function ondata(chunk) {
	    debug('ondata');
	    var ret = dest.write(chunk);
	    debug('dest.write', ret);
	    if (ret === false) {
	      // If the user unpiped during `dest.write()`, it is possible
	      // to get stuck in a permanently paused state if that write
	      // also returned false.
	      // => Check whether `dest` is still a piping destination.
	      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
	        debug('false write response, pause', state.awaitDrain);
	        state.awaitDrain++;
	      }
	      src.pause();
	    }
	  }

	  // if the dest has an error, then stop piping into it.
	  // however, don't suppress the throwing behavior for this.
	  function onerror(er) {
	    debug('onerror', er);
	    unpipe();
	    dest.removeListener('error', onerror);
	    if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er);
	  }

	  // Make sure our error handler is attached before userland ones.
	  prependListener(dest, 'error', onerror);

	  // Both close and finish should trigger unpipe, but only once.
	  function onclose() {
	    dest.removeListener('finish', onfinish);
	    unpipe();
	  }
	  dest.once('close', onclose);
	  function onfinish() {
	    debug('onfinish');
	    dest.removeListener('close', onclose);
	    unpipe();
	  }
	  dest.once('finish', onfinish);
	  function unpipe() {
	    debug('unpipe');
	    src.unpipe(dest);
	  }

	  // tell the dest that it's being piped to
	  dest.emit('pipe', src);

	  // start the flow if it hasn't been started already.
	  if (!state.flowing) {
	    debug('pipe resume');
	    src.resume();
	  }
	  return dest;
	};
	function pipeOnDrain(src) {
	  return function pipeOnDrainFunctionResult() {
	    var state = src._readableState;
	    debug('pipeOnDrain', state.awaitDrain);
	    if (state.awaitDrain) state.awaitDrain--;
	    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
	      state.flowing = true;
	      flow(src);
	    }
	  };
	}
	Readable.prototype.unpipe = function (dest) {
	  var state = this._readableState;
	  var unpipeInfo = {
	    hasUnpiped: false
	  };

	  // if we're not piping anywhere, then do nothing.
	  if (state.pipesCount === 0) return this;

	  // just one destination.  most common case.
	  if (state.pipesCount === 1) {
	    // passed in one, but it's not the right one.
	    if (dest && dest !== state.pipes) return this;
	    if (!dest) dest = state.pipes;

	    // got a match.
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	    if (dest) dest.emit('unpipe', this, unpipeInfo);
	    return this;
	  }

	  // slow case. multiple pipe destinations.

	  if (!dest) {
	    // remove all.
	    var dests = state.pipes;
	    var len = state.pipesCount;
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	    for (var i = 0; i < len; i++) dests[i].emit('unpipe', this, {
	      hasUnpiped: false
	    });
	    return this;
	  }

	  // try to find the right one.
	  var index = indexOf(state.pipes, dest);
	  if (index === -1) return this;
	  state.pipes.splice(index, 1);
	  state.pipesCount -= 1;
	  if (state.pipesCount === 1) state.pipes = state.pipes[0];
	  dest.emit('unpipe', this, unpipeInfo);
	  return this;
	};

	// set up data events if they are asked for
	// Ensure readable listeners eventually get something
	Readable.prototype.on = function (ev, fn) {
	  var res = Stream.prototype.on.call(this, ev, fn);
	  var state = this._readableState;
	  if (ev === 'data') {
	    // update readableListening so that resume() may be a no-op
	    // a few lines down. This is needed to support once('readable').
	    state.readableListening = this.listenerCount('readable') > 0;

	    // Try start flowing on next tick if stream isn't explicitly paused
	    if (state.flowing !== false) this.resume();
	  } else if (ev === 'readable') {
	    if (!state.endEmitted && !state.readableListening) {
	      state.readableListening = state.needReadable = true;
	      state.flowing = false;
	      state.emittedReadable = false;
	      debug('on readable', state.length, state.reading);
	      if (state.length) {
	        emitReadable(this);
	      } else if (!state.reading) {
	        process.nextTick(nReadingNextTick, this);
	      }
	    }
	  }
	  return res;
	};
	Readable.prototype.addListener = Readable.prototype.on;
	Readable.prototype.removeListener = function (ev, fn) {
	  var res = Stream.prototype.removeListener.call(this, ev, fn);
	  if (ev === 'readable') {
	    // We need to check if there is someone still listening to
	    // readable and reset the state. However this needs to happen
	    // after readable has been emitted but before I/O (nextTick) to
	    // support once('readable', fn) cycles. This means that calling
	    // resume within the same tick will have no
	    // effect.
	    process.nextTick(updateReadableListening, this);
	  }
	  return res;
	};
	Readable.prototype.removeAllListeners = function (ev) {
	  var res = Stream.prototype.removeAllListeners.apply(this, arguments);
	  if (ev === 'readable' || ev === undefined) {
	    // We need to check if there is someone still listening to
	    // readable and reset the state. However this needs to happen
	    // after readable has been emitted but before I/O (nextTick) to
	    // support once('readable', fn) cycles. This means that calling
	    // resume within the same tick will have no
	    // effect.
	    process.nextTick(updateReadableListening, this);
	  }
	  return res;
	};
	function updateReadableListening(self) {
	  var state = self._readableState;
	  state.readableListening = self.listenerCount('readable') > 0;
	  if (state.resumeScheduled && !state.paused) {
	    // flowing needs to be set to true now, otherwise
	    // the upcoming resume will not flow.
	    state.flowing = true;

	    // crude way to check if we should resume
	  } else if (self.listenerCount('data') > 0) {
	    self.resume();
	  }
	}
	function nReadingNextTick(self) {
	  debug('readable nexttick read 0');
	  self.read(0);
	}

	// pause() and resume() are remnants of the legacy readable stream API
	// If the user uses them, then switch into old mode.
	Readable.prototype.resume = function () {
	  var state = this._readableState;
	  if (!state.flowing) {
	    debug('resume');
	    // we flow only if there is no one listening
	    // for readable, but we still have to call
	    // resume()
	    state.flowing = !state.readableListening;
	    resume(this, state);
	  }
	  state.paused = false;
	  return this;
	};
	function resume(stream, state) {
	  if (!state.resumeScheduled) {
	    state.resumeScheduled = true;
	    process.nextTick(resume_, stream, state);
	  }
	}
	function resume_(stream, state) {
	  debug('resume', state.reading);
	  if (!state.reading) {
	    stream.read(0);
	  }
	  state.resumeScheduled = false;
	  stream.emit('resume');
	  flow(stream);
	  if (state.flowing && !state.reading) stream.read(0);
	}
	Readable.prototype.pause = function () {
	  debug('call pause flowing=%j', this._readableState.flowing);
	  if (this._readableState.flowing !== false) {
	    debug('pause');
	    this._readableState.flowing = false;
	    this.emit('pause');
	  }
	  this._readableState.paused = true;
	  return this;
	};
	function flow(stream) {
	  var state = stream._readableState;
	  debug('flow', state.flowing);
	  while (state.flowing && stream.read() !== null);
	}

	// wrap an old-style stream as the async data source.
	// This is *not* part of the readable stream interface.
	// It is an ugly unfortunate mess of history.
	Readable.prototype.wrap = function (stream) {
	  var _this = this;
	  var state = this._readableState;
	  var paused = false;
	  stream.on('end', function () {
	    debug('wrapped end');
	    if (state.decoder && !state.ended) {
	      var chunk = state.decoder.end();
	      if (chunk && chunk.length) _this.push(chunk);
	    }
	    _this.push(null);
	  });
	  stream.on('data', function (chunk) {
	    debug('wrapped data');
	    if (state.decoder) chunk = state.decoder.write(chunk);

	    // don't skip over falsy values in objectMode
	    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
	    var ret = _this.push(chunk);
	    if (!ret) {
	      paused = true;
	      stream.pause();
	    }
	  });

	  // proxy all the other methods.
	  // important when wrapping filters and duplexes.
	  for (var i in stream) {
	    if (this[i] === undefined && typeof stream[i] === 'function') {
	      this[i] = function methodWrap(method) {
	        return function methodWrapReturnFunction() {
	          return stream[method].apply(stream, arguments);
	        };
	      }(i);
	    }
	  }

	  // proxy certain important events.
	  for (var n = 0; n < kProxyEvents.length; n++) {
	    stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
	  }

	  // when we try to consume some more bytes, simply unpause the
	  // underlying stream.
	  this._read = function (n) {
	    debug('wrapped _read', n);
	    if (paused) {
	      paused = false;
	      stream.resume();
	    }
	  };
	  return this;
	};
	if (typeof Symbol === 'function') {
	  Readable.prototype[Symbol.asyncIterator] = function () {
	    if (createReadableStreamAsyncIterator === undefined) {
	      createReadableStreamAsyncIterator = requireAsync_iterator();
	    }
	    return createReadableStreamAsyncIterator(this);
	  };
	}
	Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._readableState.highWaterMark;
	  }
	});
	Object.defineProperty(Readable.prototype, 'readableBuffer', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._readableState && this._readableState.buffer;
	  }
	});
	Object.defineProperty(Readable.prototype, 'readableFlowing', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._readableState.flowing;
	  },
	  set: function set(state) {
	    if (this._readableState) {
	      this._readableState.flowing = state;
	    }
	  }
	});

	// exposed for testing purposes only.
	Readable._fromList = fromList;
	Object.defineProperty(Readable.prototype, 'readableLength', {
	  // making it explicit this property is not enumerable
	  // because otherwise some prototype manipulation in
	  // userland will fail
	  enumerable: false,
	  get: function get() {
	    return this._readableState.length;
	  }
	});

	// Pluck off n bytes from an array of buffers.
	// Length is the combined lengths of all the buffers in the list.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function fromList(n, state) {
	  // nothing buffered
	  if (state.length === 0) return null;
	  var ret;
	  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
	    // read it all, truncate the list
	    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length);
	    state.buffer.clear();
	  } else {
	    // read part of list
	    ret = state.buffer.consume(n, state.decoder);
	  }
	  return ret;
	}
	function endReadable(stream) {
	  var state = stream._readableState;
	  debug('endReadable', state.endEmitted);
	  if (!state.endEmitted) {
	    state.ended = true;
	    process.nextTick(endReadableNT, state, stream);
	  }
	}
	function endReadableNT(state, stream) {
	  debug('endReadableNT', state.endEmitted, state.length);

	  // Check that we didn't get one last unshift.
	  if (!state.endEmitted && state.length === 0) {
	    state.endEmitted = true;
	    stream.readable = false;
	    stream.emit('end');
	    if (state.autoDestroy) {
	      // In case of duplex streams we need a way to detect
	      // if the writable side is ready for autoDestroy as well
	      var wState = stream._writableState;
	      if (!wState || wState.autoDestroy && wState.finished) {
	        stream.destroy();
	      }
	    }
	  }
	}
	if (typeof Symbol === 'function') {
	  Readable.from = function (iterable, opts) {
	    if (from === undefined) {
	      from = requireFrom();
	    }
	    return from(Readable, iterable, opts);
	  };
	}
	function indexOf(xs, x) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    if (xs[i] === x) return i;
	  }
	  return -1;
	}
	return _stream_readable;
}

var _stream_transform;
var hasRequired_stream_transform;

function require_stream_transform () {
	if (hasRequired_stream_transform) return _stream_transform;
	hasRequired_stream_transform = 1;

	_stream_transform = Transform;
	var _require$codes = requireErrors().codes,
	  ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
	  ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
	  ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING,
	  ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0;
	var Duplex = require_stream_duplex();
	requireInherits()(Transform, Duplex);
	function afterTransform(er, data) {
	  var ts = this._transformState;
	  ts.transforming = false;
	  var cb = ts.writecb;
	  if (cb === null) {
	    return this.emit('error', new ERR_MULTIPLE_CALLBACK());
	  }
	  ts.writechunk = null;
	  ts.writecb = null;
	  if (data != null)
	    // single equals check for both `null` and `undefined`
	    this.push(data);
	  cb(er);
	  var rs = this._readableState;
	  rs.reading = false;
	  if (rs.needReadable || rs.length < rs.highWaterMark) {
	    this._read(rs.highWaterMark);
	  }
	}
	function Transform(options) {
	  if (!(this instanceof Transform)) return new Transform(options);
	  Duplex.call(this, options);
	  this._transformState = {
	    afterTransform: afterTransform.bind(this),
	    needTransform: false,
	    transforming: false,
	    writecb: null,
	    writechunk: null,
	    writeencoding: null
	  };

	  // start out asking for a readable event once data is transformed.
	  this._readableState.needReadable = true;

	  // we have implemented the _read method, and done the other things
	  // that Readable wants before the first _read call, so unset the
	  // sync guard flag.
	  this._readableState.sync = false;
	  if (options) {
	    if (typeof options.transform === 'function') this._transform = options.transform;
	    if (typeof options.flush === 'function') this._flush = options.flush;
	  }

	  // When the writable side finishes, then flush out anything remaining.
	  this.on('prefinish', prefinish);
	}
	function prefinish() {
	  var _this = this;
	  if (typeof this._flush === 'function' && !this._readableState.destroyed) {
	    this._flush(function (er, data) {
	      done(_this, er, data);
	    });
	  } else {
	    done(this, null, null);
	  }
	}
	Transform.prototype.push = function (chunk, encoding) {
	  this._transformState.needTransform = false;
	  return Duplex.prototype.push.call(this, chunk, encoding);
	};

	// This is the part where you do stuff!
	// override this function in implementation classes.
	// 'chunk' is an input chunk.
	//
	// Call `push(newChunk)` to pass along transformed output
	// to the readable side.  You may call 'push' zero or more times.
	//
	// Call `cb(err)` when you are done with this chunk.  If you pass
	// an error, then that'll put the hurt on the whole operation.  If you
	// never call cb(), then you'll never get another chunk.
	Transform.prototype._transform = function (chunk, encoding, cb) {
	  cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()'));
	};
	Transform.prototype._write = function (chunk, encoding, cb) {
	  var ts = this._transformState;
	  ts.writecb = cb;
	  ts.writechunk = chunk;
	  ts.writeencoding = encoding;
	  if (!ts.transforming) {
	    var rs = this._readableState;
	    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
	  }
	};

	// Doesn't matter what the args are here.
	// _transform does all the work.
	// That we got here means that the readable side wants more data.
	Transform.prototype._read = function (n) {
	  var ts = this._transformState;
	  if (ts.writechunk !== null && !ts.transforming) {
	    ts.transforming = true;
	    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
	  } else {
	    // mark that we need a transform, so that any data that comes in
	    // will get processed, now that we've asked for it.
	    ts.needTransform = true;
	  }
	};
	Transform.prototype._destroy = function (err, cb) {
	  Duplex.prototype._destroy.call(this, err, function (err2) {
	    cb(err2);
	  });
	};
	function done(stream, er, data) {
	  if (er) return stream.emit('error', er);
	  if (data != null)
	    // single equals check for both `null` and `undefined`
	    stream.push(data);

	  // TODO(BridgeAR): Write a test for these two error cases
	  // if there's nothing in the write buffer, then that means
	  // that nothing more will ever be provided
	  if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0();
	  if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING();
	  return stream.push(null);
	}
	return _stream_transform;
}

var _stream_passthrough;
var hasRequired_stream_passthrough;

function require_stream_passthrough () {
	if (hasRequired_stream_passthrough) return _stream_passthrough;
	hasRequired_stream_passthrough = 1;

	_stream_passthrough = PassThrough;
	var Transform = require_stream_transform();
	requireInherits()(PassThrough, Transform);
	function PassThrough(options) {
	  if (!(this instanceof PassThrough)) return new PassThrough(options);
	  Transform.call(this, options);
	}
	PassThrough.prototype._transform = function (chunk, encoding, cb) {
	  cb(null, chunk);
	};
	return _stream_passthrough;
}

var pipeline_1;
var hasRequiredPipeline;

function requirePipeline () {
	if (hasRequiredPipeline) return pipeline_1;
	hasRequiredPipeline = 1;

	var eos;
	function once(callback) {
	  var called = false;
	  return function () {
	    if (called) return;
	    called = true;
	    callback.apply(void 0, arguments);
	  };
	}
	var _require$codes = requireErrors().codes,
	  ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS,
	  ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED;
	function noop(err) {
	  // Rethrow the error if it exists to avoid swallowing it
	  if (err) throw err;
	}
	function isRequest(stream) {
	  return stream.setHeader && typeof stream.abort === 'function';
	}
	function destroyer(stream, reading, writing, callback) {
	  callback = once(callback);
	  var closed = false;
	  stream.on('close', function () {
	    closed = true;
	  });
	  if (eos === undefined) eos = requireEndOfStream();
	  eos(stream, {
	    readable: reading,
	    writable: writing
	  }, function (err) {
	    if (err) return callback(err);
	    closed = true;
	    callback();
	  });
	  var destroyed = false;
	  return function (err) {
	    if (closed) return;
	    if (destroyed) return;
	    destroyed = true;

	    // request.destroy just do .end - .abort is what we want
	    if (isRequest(stream)) return stream.abort();
	    if (typeof stream.destroy === 'function') return stream.destroy();
	    callback(err || new ERR_STREAM_DESTROYED('pipe'));
	  };
	}
	function call(fn) {
	  fn();
	}
	function pipe(from, to) {
	  return from.pipe(to);
	}
	function popCallback(streams) {
	  if (!streams.length) return noop;
	  if (typeof streams[streams.length - 1] !== 'function') return noop;
	  return streams.pop();
	}
	function pipeline() {
	  for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) {
	    streams[_key] = arguments[_key];
	  }
	  var callback = popCallback(streams);
	  if (Array.isArray(streams[0])) streams = streams[0];
	  if (streams.length < 2) {
	    throw new ERR_MISSING_ARGS('streams');
	  }
	  var error;
	  var destroys = streams.map(function (stream, i) {
	    var reading = i < streams.length - 1;
	    var writing = i > 0;
	    return destroyer(stream, reading, writing, function (err) {
	      if (!error) error = err;
	      if (err) destroys.forEach(call);
	      if (reading) return;
	      destroys.forEach(call);
	      callback(error);
	    });
	  });
	  return streams.reduce(pipe);
	}
	pipeline_1 = pipeline;
	return pipeline_1;
}

var hasRequiredReadable;

function requireReadable () {
	if (hasRequiredReadable) return readable.exports;
	hasRequiredReadable = 1;
	(function (module, exports) {
		var Stream = require$$0$4;
		if (process.env.READABLE_STREAM === 'disable' && Stream) {
		  module.exports = Stream.Readable;
		  Object.assign(module.exports, Stream);
		  module.exports.Stream = Stream;
		} else {
		  exports = module.exports = require_stream_readable();
		  exports.Stream = Stream || exports;
		  exports.Readable = exports;
		  exports.Writable = require_stream_writable();
		  exports.Duplex = require_stream_duplex();
		  exports.Transform = require_stream_transform();
		  exports.PassThrough = require_stream_passthrough();
		  exports.finished = requireEndOfStream();
		  exports.pipeline = requirePipeline();
		} 
	} (readable, readable.exports));
	return readable.exports;
}

var file = {exports: {}};

/**
 * Appends the elements of `values` to `array`.
 *
 * @private
 * @param {Array} array The array to modify.
 * @param {Array} values The values to append.
 * @returns {Array} Returns `array`.
 */

var _arrayPush;
var hasRequired_arrayPush;

function require_arrayPush () {
	if (hasRequired_arrayPush) return _arrayPush;
	hasRequired_arrayPush = 1;
	function arrayPush(array, values) {
	  var index = -1,
	      length = values.length,
	      offset = array.length;

	  while (++index < length) {
	    array[offset + index] = values[index];
	  }
	  return array;
	}

	_arrayPush = arrayPush;
	return _arrayPush;
}

var _isFlattenable;
var hasRequired_isFlattenable;

function require_isFlattenable () {
	if (hasRequired_isFlattenable) return _isFlattenable;
	hasRequired_isFlattenable = 1;
	var Symbol = require_Symbol(),
	    isArguments = requireIsArguments(),
	    isArray = requireIsArray();

	/** Built-in value references. */
	var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;

	/**
	 * Checks if `value` is a flattenable `arguments` object or array.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
	 */
	function isFlattenable(value) {
	  return isArray(value) || isArguments(value) ||
	    !!(spreadableSymbol && value && value[spreadableSymbol]);
	}

	_isFlattenable = isFlattenable;
	return _isFlattenable;
}

var _baseFlatten;
var hasRequired_baseFlatten;

function require_baseFlatten () {
	if (hasRequired_baseFlatten) return _baseFlatten;
	hasRequired_baseFlatten = 1;
	var arrayPush = require_arrayPush(),
	    isFlattenable = require_isFlattenable();

	/**
	 * The base implementation of `_.flatten` with support for restricting flattening.
	 *
	 * @private
	 * @param {Array} array The array to flatten.
	 * @param {number} depth The maximum recursion depth.
	 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
	 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
	 * @param {Array} [result=[]] The initial result value.
	 * @returns {Array} Returns the new flattened array.
	 */
	function baseFlatten(array, depth, predicate, isStrict, result) {
	  var index = -1,
	      length = array.length;

	  predicate || (predicate = isFlattenable);
	  result || (result = []);

	  while (++index < length) {
	    var value = array[index];
	    if (depth > 0 && predicate(value)) {
	      if (depth > 1) {
	        // Recursively flatten arrays (susceptible to call stack limits).
	        baseFlatten(value, depth - 1, predicate, isStrict, result);
	      } else {
	        arrayPush(result, value);
	      }
	    } else if (!isStrict) {
	      result[result.length] = value;
	    }
	  }
	  return result;
	}

	_baseFlatten = baseFlatten;
	return _baseFlatten;
}

var flatten_1;
var hasRequiredFlatten;

function requireFlatten () {
	if (hasRequiredFlatten) return flatten_1;
	hasRequiredFlatten = 1;
	var baseFlatten = require_baseFlatten();

	/**
	 * Flattens `array` a single level deep.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Array
	 * @param {Array} array The array to flatten.
	 * @returns {Array} Returns the new flattened array.
	 * @example
	 *
	 * _.flatten([1, [2, [3, [4]], 5]]);
	 * // => [1, 2, [3, [4]], 5]
	 */
	function flatten(array) {
	  var length = array == null ? 0 : array.length;
	  return length ? baseFlatten(array, 1) : [];
	}

	flatten_1 = flatten;
	return flatten_1;
}

var _nativeCreate;
var hasRequired_nativeCreate;

function require_nativeCreate () {
	if (hasRequired_nativeCreate) return _nativeCreate;
	hasRequired_nativeCreate = 1;
	var getNative = require_getNative();

	/* Built-in method references that are verified to be native. */
	var nativeCreate = getNative(Object, 'create');

	_nativeCreate = nativeCreate;
	return _nativeCreate;
}

var _hashClear;
var hasRequired_hashClear;

function require_hashClear () {
	if (hasRequired_hashClear) return _hashClear;
	hasRequired_hashClear = 1;
	var nativeCreate = require_nativeCreate();

	/**
	 * Removes all key-value entries from the hash.
	 *
	 * @private
	 * @name clear
	 * @memberOf Hash
	 */
	function hashClear() {
	  this.__data__ = nativeCreate ? nativeCreate(null) : {};
	  this.size = 0;
	}

	_hashClear = hashClear;
	return _hashClear;
}

/**
 * Removes `key` and its value from the hash.
 *
 * @private
 * @name delete
 * @memberOf Hash
 * @param {Object} hash The hash to modify.
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */

var _hashDelete;
var hasRequired_hashDelete;

function require_hashDelete () {
	if (hasRequired_hashDelete) return _hashDelete;
	hasRequired_hashDelete = 1;
	function hashDelete(key) {
	  var result = this.has(key) && delete this.__data__[key];
	  this.size -= result ? 1 : 0;
	  return result;
	}

	_hashDelete = hashDelete;
	return _hashDelete;
}

var _hashGet;
var hasRequired_hashGet;

function require_hashGet () {
	if (hasRequired_hashGet) return _hashGet;
	hasRequired_hashGet = 1;
	var nativeCreate = require_nativeCreate();

	/** Used to stand-in for `undefined` hash values. */
	var HASH_UNDEFINED = '__lodash_hash_undefined__';

	/** Used for built-in method references. */
	var objectProto = Object.prototype;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/**
	 * Gets the hash value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf Hash
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
	function hashGet(key) {
	  var data = this.__data__;
	  if (nativeCreate) {
	    var result = data[key];
	    return result === HASH_UNDEFINED ? undefined : result;
	  }
	  return hasOwnProperty.call(data, key) ? data[key] : undefined;
	}

	_hashGet = hashGet;
	return _hashGet;
}

var _hashHas;
var hasRequired_hashHas;

function require_hashHas () {
	if (hasRequired_hashHas) return _hashHas;
	hasRequired_hashHas = 1;
	var nativeCreate = require_nativeCreate();

	/** Used for built-in method references. */
	var objectProto = Object.prototype;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/**
	 * Checks if a hash value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf Hash
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function hashHas(key) {
	  var data = this.__data__;
	  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
	}

	_hashHas = hashHas;
	return _hashHas;
}

var _hashSet;
var hasRequired_hashSet;

function require_hashSet () {
	if (hasRequired_hashSet) return _hashSet;
	hasRequired_hashSet = 1;
	var nativeCreate = require_nativeCreate();

	/** Used to stand-in for `undefined` hash values. */
	var HASH_UNDEFINED = '__lodash_hash_undefined__';

	/**
	 * Sets the hash `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf Hash
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the hash instance.
	 */
	function hashSet(key, value) {
	  var data = this.__data__;
	  this.size += this.has(key) ? 0 : 1;
	  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
	  return this;
	}

	_hashSet = hashSet;
	return _hashSet;
}

var _Hash;
var hasRequired_Hash;

function require_Hash () {
	if (hasRequired_Hash) return _Hash;
	hasRequired_Hash = 1;
	var hashClear = require_hashClear(),
	    hashDelete = require_hashDelete(),
	    hashGet = require_hashGet(),
	    hashHas = require_hashHas(),
	    hashSet = require_hashSet();

	/**
	 * Creates a hash object.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function Hash(entries) {
	  var index = -1,
	      length = entries == null ? 0 : entries.length;

	  this.clear();
	  while (++index < length) {
	    var entry = entries[index];
	    this.set(entry[0], entry[1]);
	  }
	}

	// Add methods to `Hash`.
	Hash.prototype.clear = hashClear;
	Hash.prototype['delete'] = hashDelete;
	Hash.prototype.get = hashGet;
	Hash.prototype.has = hashHas;
	Hash.prototype.set = hashSet;

	_Hash = Hash;
	return _Hash;
}

/**
 * Removes all key-value entries from the list cache.
 *
 * @private
 * @name clear
 * @memberOf ListCache
 */

var _listCacheClear;
var hasRequired_listCacheClear;

function require_listCacheClear () {
	if (hasRequired_listCacheClear) return _listCacheClear;
	hasRequired_listCacheClear = 1;
	function listCacheClear() {
	  this.__data__ = [];
	  this.size = 0;
	}

	_listCacheClear = listCacheClear;
	return _listCacheClear;
}

var _assocIndexOf;
var hasRequired_assocIndexOf;

function require_assocIndexOf () {
	if (hasRequired_assocIndexOf) return _assocIndexOf;
	hasRequired_assocIndexOf = 1;
	var eq = requireEq();

	/**
	 * Gets the index at which the `key` is found in `array` of key-value pairs.
	 *
	 * @private
	 * @param {Array} array The array to inspect.
	 * @param {*} key The key to search for.
	 * @returns {number} Returns the index of the matched value, else `-1`.
	 */
	function assocIndexOf(array, key) {
	  var length = array.length;
	  while (length--) {
	    if (eq(array[length][0], key)) {
	      return length;
	    }
	  }
	  return -1;
	}

	_assocIndexOf = assocIndexOf;
	return _assocIndexOf;
}

var _listCacheDelete;
var hasRequired_listCacheDelete;

function require_listCacheDelete () {
	if (hasRequired_listCacheDelete) return _listCacheDelete;
	hasRequired_listCacheDelete = 1;
	var assocIndexOf = require_assocIndexOf();

	/** Used for built-in method references. */
	var arrayProto = Array.prototype;

	/** Built-in value references. */
	var splice = arrayProto.splice;

	/**
	 * Removes `key` and its value from the list cache.
	 *
	 * @private
	 * @name delete
	 * @memberOf ListCache
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
	function listCacheDelete(key) {
	  var data = this.__data__,
	      index = assocIndexOf(data, key);

	  if (index < 0) {
	    return false;
	  }
	  var lastIndex = data.length - 1;
	  if (index == lastIndex) {
	    data.pop();
	  } else {
	    splice.call(data, index, 1);
	  }
	  --this.size;
	  return true;
	}

	_listCacheDelete = listCacheDelete;
	return _listCacheDelete;
}

var _listCacheGet;
var hasRequired_listCacheGet;

function require_listCacheGet () {
	if (hasRequired_listCacheGet) return _listCacheGet;
	hasRequired_listCacheGet = 1;
	var assocIndexOf = require_assocIndexOf();

	/**
	 * Gets the list cache value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf ListCache
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
	function listCacheGet(key) {
	  var data = this.__data__,
	      index = assocIndexOf(data, key);

	  return index < 0 ? undefined : data[index][1];
	}

	_listCacheGet = listCacheGet;
	return _listCacheGet;
}

var _listCacheHas;
var hasRequired_listCacheHas;

function require_listCacheHas () {
	if (hasRequired_listCacheHas) return _listCacheHas;
	hasRequired_listCacheHas = 1;
	var assocIndexOf = require_assocIndexOf();

	/**
	 * Checks if a list cache value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf ListCache
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function listCacheHas(key) {
	  return assocIndexOf(this.__data__, key) > -1;
	}

	_listCacheHas = listCacheHas;
	return _listCacheHas;
}

var _listCacheSet;
var hasRequired_listCacheSet;

function require_listCacheSet () {
	if (hasRequired_listCacheSet) return _listCacheSet;
	hasRequired_listCacheSet = 1;
	var assocIndexOf = require_assocIndexOf();

	/**
	 * Sets the list cache `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf ListCache
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the list cache instance.
	 */
	function listCacheSet(key, value) {
	  var data = this.__data__,
	      index = assocIndexOf(data, key);

	  if (index < 0) {
	    ++this.size;
	    data.push([key, value]);
	  } else {
	    data[index][1] = value;
	  }
	  return this;
	}

	_listCacheSet = listCacheSet;
	return _listCacheSet;
}

var _ListCache;
var hasRequired_ListCache;

function require_ListCache () {
	if (hasRequired_ListCache) return _ListCache;
	hasRequired_ListCache = 1;
	var listCacheClear = require_listCacheClear(),
	    listCacheDelete = require_listCacheDelete(),
	    listCacheGet = require_listCacheGet(),
	    listCacheHas = require_listCacheHas(),
	    listCacheSet = require_listCacheSet();

	/**
	 * Creates an list cache object.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function ListCache(entries) {
	  var index = -1,
	      length = entries == null ? 0 : entries.length;

	  this.clear();
	  while (++index < length) {
	    var entry = entries[index];
	    this.set(entry[0], entry[1]);
	  }
	}

	// Add methods to `ListCache`.
	ListCache.prototype.clear = listCacheClear;
	ListCache.prototype['delete'] = listCacheDelete;
	ListCache.prototype.get = listCacheGet;
	ListCache.prototype.has = listCacheHas;
	ListCache.prototype.set = listCacheSet;

	_ListCache = ListCache;
	return _ListCache;
}

var _Map;
var hasRequired_Map;

function require_Map () {
	if (hasRequired_Map) return _Map;
	hasRequired_Map = 1;
	var getNative = require_getNative(),
	    root = require_root();

	/* Built-in method references that are verified to be native. */
	var Map = getNative(root, 'Map');

	_Map = Map;
	return _Map;
}

var _mapCacheClear;
var hasRequired_mapCacheClear;

function require_mapCacheClear () {
	if (hasRequired_mapCacheClear) return _mapCacheClear;
	hasRequired_mapCacheClear = 1;
	var Hash = require_Hash(),
	    ListCache = require_ListCache(),
	    Map = require_Map();

	/**
	 * Removes all key-value entries from the map.
	 *
	 * @private
	 * @name clear
	 * @memberOf MapCache
	 */
	function mapCacheClear() {
	  this.size = 0;
	  this.__data__ = {
	    'hash': new Hash,
	    'map': new (Map || ListCache),
	    'string': new Hash
	  };
	}

	_mapCacheClear = mapCacheClear;
	return _mapCacheClear;
}

/**
 * Checks if `value` is suitable for use as unique object key.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
 */

var _isKeyable;
var hasRequired_isKeyable;

function require_isKeyable () {
	if (hasRequired_isKeyable) return _isKeyable;
	hasRequired_isKeyable = 1;
	function isKeyable(value) {
	  var type = typeof value;
	  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
	    ? (value !== '__proto__')
	    : (value === null);
	}

	_isKeyable = isKeyable;
	return _isKeyable;
}

var _getMapData;
var hasRequired_getMapData;

function require_getMapData () {
	if (hasRequired_getMapData) return _getMapData;
	hasRequired_getMapData = 1;
	var isKeyable = require_isKeyable();

	/**
	 * Gets the data for `map`.
	 *
	 * @private
	 * @param {Object} map The map to query.
	 * @param {string} key The reference key.
	 * @returns {*} Returns the map data.
	 */
	function getMapData(map, key) {
	  var data = map.__data__;
	  return isKeyable(key)
	    ? data[typeof key == 'string' ? 'string' : 'hash']
	    : data.map;
	}

	_getMapData = getMapData;
	return _getMapData;
}

var _mapCacheDelete;
var hasRequired_mapCacheDelete;

function require_mapCacheDelete () {
	if (hasRequired_mapCacheDelete) return _mapCacheDelete;
	hasRequired_mapCacheDelete = 1;
	var getMapData = require_getMapData();

	/**
	 * Removes `key` and its value from the map.
	 *
	 * @private
	 * @name delete
	 * @memberOf MapCache
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
	function mapCacheDelete(key) {
	  var result = getMapData(this, key)['delete'](key);
	  this.size -= result ? 1 : 0;
	  return result;
	}

	_mapCacheDelete = mapCacheDelete;
	return _mapCacheDelete;
}

var _mapCacheGet;
var hasRequired_mapCacheGet;

function require_mapCacheGet () {
	if (hasRequired_mapCacheGet) return _mapCacheGet;
	hasRequired_mapCacheGet = 1;
	var getMapData = require_getMapData();

	/**
	 * Gets the map value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf MapCache
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
	function mapCacheGet(key) {
	  return getMapData(this, key).get(key);
	}

	_mapCacheGet = mapCacheGet;
	return _mapCacheGet;
}

var _mapCacheHas;
var hasRequired_mapCacheHas;

function require_mapCacheHas () {
	if (hasRequired_mapCacheHas) return _mapCacheHas;
	hasRequired_mapCacheHas = 1;
	var getMapData = require_getMapData();

	/**
	 * Checks if a map value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf MapCache
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function mapCacheHas(key) {
	  return getMapData(this, key).has(key);
	}

	_mapCacheHas = mapCacheHas;
	return _mapCacheHas;
}

var _mapCacheSet;
var hasRequired_mapCacheSet;

function require_mapCacheSet () {
	if (hasRequired_mapCacheSet) return _mapCacheSet;
	hasRequired_mapCacheSet = 1;
	var getMapData = require_getMapData();

	/**
	 * Sets the map `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf MapCache
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the map cache instance.
	 */
	function mapCacheSet(key, value) {
	  var data = getMapData(this, key),
	      size = data.size;

	  data.set(key, value);
	  this.size += data.size == size ? 0 : 1;
	  return this;
	}

	_mapCacheSet = mapCacheSet;
	return _mapCacheSet;
}

var _MapCache;
var hasRequired_MapCache;

function require_MapCache () {
	if (hasRequired_MapCache) return _MapCache;
	hasRequired_MapCache = 1;
	var mapCacheClear = require_mapCacheClear(),
	    mapCacheDelete = require_mapCacheDelete(),
	    mapCacheGet = require_mapCacheGet(),
	    mapCacheHas = require_mapCacheHas(),
	    mapCacheSet = require_mapCacheSet();

	/**
	 * Creates a map cache object to store key-value pairs.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function MapCache(entries) {
	  var index = -1,
	      length = entries == null ? 0 : entries.length;

	  this.clear();
	  while (++index < length) {
	    var entry = entries[index];
	    this.set(entry[0], entry[1]);
	  }
	}

	// Add methods to `MapCache`.
	MapCache.prototype.clear = mapCacheClear;
	MapCache.prototype['delete'] = mapCacheDelete;
	MapCache.prototype.get = mapCacheGet;
	MapCache.prototype.has = mapCacheHas;
	MapCache.prototype.set = mapCacheSet;

	_MapCache = MapCache;
	return _MapCache;
}

/** Used to stand-in for `undefined` hash values. */

var _setCacheAdd;
var hasRequired_setCacheAdd;

function require_setCacheAdd () {
	if (hasRequired_setCacheAdd) return _setCacheAdd;
	hasRequired_setCacheAdd = 1;
	var HASH_UNDEFINED = '__lodash_hash_undefined__';

	/**
	 * Adds `value` to the array cache.
	 *
	 * @private
	 * @name add
	 * @memberOf SetCache
	 * @alias push
	 * @param {*} value The value to cache.
	 * @returns {Object} Returns the cache instance.
	 */
	function setCacheAdd(value) {
	  this.__data__.set(value, HASH_UNDEFINED);
	  return this;
	}

	_setCacheAdd = setCacheAdd;
	return _setCacheAdd;
}

/**
 * Checks if `value` is in the array cache.
 *
 * @private
 * @name has
 * @memberOf SetCache
 * @param {*} value The value to search for.
 * @returns {number} Returns `true` if `value` is found, else `false`.
 */

var _setCacheHas;
var hasRequired_setCacheHas;

function require_setCacheHas () {
	if (hasRequired_setCacheHas) return _setCacheHas;
	hasRequired_setCacheHas = 1;
	function setCacheHas(value) {
	  return this.__data__.has(value);
	}

	_setCacheHas = setCacheHas;
	return _setCacheHas;
}

var _SetCache;
var hasRequired_SetCache;

function require_SetCache () {
	if (hasRequired_SetCache) return _SetCache;
	hasRequired_SetCache = 1;
	var MapCache = require_MapCache(),
	    setCacheAdd = require_setCacheAdd(),
	    setCacheHas = require_setCacheHas();

	/**
	 *
	 * Creates an array cache object to store unique values.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [values] The values to cache.
	 */
	function SetCache(values) {
	  var index = -1,
	      length = values == null ? 0 : values.length;

	  this.__data__ = new MapCache;
	  while (++index < length) {
	    this.add(values[index]);
	  }
	}

	// Add methods to `SetCache`.
	SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
	SetCache.prototype.has = setCacheHas;

	_SetCache = SetCache;
	return _SetCache;
}

/**
 * The base implementation of `_.findIndex` and `_.findLastIndex` without
 * support for iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Function} predicate The function invoked per iteration.
 * @param {number} fromIndex The index to search from.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */

var _baseFindIndex;
var hasRequired_baseFindIndex;

function require_baseFindIndex () {
	if (hasRequired_baseFindIndex) return _baseFindIndex;
	hasRequired_baseFindIndex = 1;
	function baseFindIndex(array, predicate, fromIndex, fromRight) {
	  var length = array.length,
	      index = fromIndex + (fromRight ? 1 : -1);

	  while ((fromRight ? index-- : ++index < length)) {
	    if (predicate(array[index], index, array)) {
	      return index;
	    }
	  }
	  return -1;
	}

	_baseFindIndex = baseFindIndex;
	return _baseFindIndex;
}

/**
 * The base implementation of `_.isNaN` without support for number objects.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
 */

var _baseIsNaN;
var hasRequired_baseIsNaN;

function require_baseIsNaN () {
	if (hasRequired_baseIsNaN) return _baseIsNaN;
	hasRequired_baseIsNaN = 1;
	function baseIsNaN(value) {
	  return value !== value;
	}

	_baseIsNaN = baseIsNaN;
	return _baseIsNaN;
}

/**
 * A specialized version of `_.indexOf` which performs strict equality
 * comparisons of values, i.e. `===`.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} value The value to search for.
 * @param {number} fromIndex The index to search from.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */

var _strictIndexOf;
var hasRequired_strictIndexOf;

function require_strictIndexOf () {
	if (hasRequired_strictIndexOf) return _strictIndexOf;
	hasRequired_strictIndexOf = 1;
	function strictIndexOf(array, value, fromIndex) {
	  var index = fromIndex - 1,
	      length = array.length;

	  while (++index < length) {
	    if (array[index] === value) {
	      return index;
	    }
	  }
	  return -1;
	}

	_strictIndexOf = strictIndexOf;
	return _strictIndexOf;
}

var _baseIndexOf;
var hasRequired_baseIndexOf;

function require_baseIndexOf () {
	if (hasRequired_baseIndexOf) return _baseIndexOf;
	hasRequired_baseIndexOf = 1;
	var baseFindIndex = require_baseFindIndex(),
	    baseIsNaN = require_baseIsNaN(),
	    strictIndexOf = require_strictIndexOf();

	/**
	 * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
	 *
	 * @private
	 * @param {Array} array The array to inspect.
	 * @param {*} value The value to search for.
	 * @param {number} fromIndex The index to search from.
	 * @returns {number} Returns the index of the matched value, else `-1`.
	 */
	function baseIndexOf(array, value, fromIndex) {
	  return value === value
	    ? strictIndexOf(array, value, fromIndex)
	    : baseFindIndex(array, baseIsNaN, fromIndex);
	}

	_baseIndexOf = baseIndexOf;
	return _baseIndexOf;
}

var _arrayIncludes;
var hasRequired_arrayIncludes;

function require_arrayIncludes () {
	if (hasRequired_arrayIncludes) return _arrayIncludes;
	hasRequired_arrayIncludes = 1;
	var baseIndexOf = require_baseIndexOf();

	/**
	 * A specialized version of `_.includes` for arrays without support for
	 * specifying an index to search from.
	 *
	 * @private
	 * @param {Array} [array] The array to inspect.
	 * @param {*} target The value to search for.
	 * @returns {boolean} Returns `true` if `target` is found, else `false`.
	 */
	function arrayIncludes(array, value) {
	  var length = array == null ? 0 : array.length;
	  return !!length && baseIndexOf(array, value, 0) > -1;
	}

	_arrayIncludes = arrayIncludes;
	return _arrayIncludes;
}

/**
 * This function is like `arrayIncludes` except that it accepts a comparator.
 *
 * @private
 * @param {Array} [array] The array to inspect.
 * @param {*} target The value to search for.
 * @param {Function} comparator The comparator invoked per element.
 * @returns {boolean} Returns `true` if `target` is found, else `false`.
 */

var _arrayIncludesWith;
var hasRequired_arrayIncludesWith;

function require_arrayIncludesWith () {
	if (hasRequired_arrayIncludesWith) return _arrayIncludesWith;
	hasRequired_arrayIncludesWith = 1;
	function arrayIncludesWith(array, value, comparator) {
	  var index = -1,
	      length = array == null ? 0 : array.length;

	  while (++index < length) {
	    if (comparator(value, array[index])) {
	      return true;
	    }
	  }
	  return false;
	}

	_arrayIncludesWith = arrayIncludesWith;
	return _arrayIncludesWith;
}

/**
 * A specialized version of `_.map` for arrays without support for iteratee
 * shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the new mapped array.
 */

var _arrayMap;
var hasRequired_arrayMap;

function require_arrayMap () {
	if (hasRequired_arrayMap) return _arrayMap;
	hasRequired_arrayMap = 1;
	function arrayMap(array, iteratee) {
	  var index = -1,
	      length = array == null ? 0 : array.length,
	      result = Array(length);

	  while (++index < length) {
	    result[index] = iteratee(array[index], index, array);
	  }
	  return result;
	}

	_arrayMap = arrayMap;
	return _arrayMap;
}

/**
 * Checks if a `cache` value for `key` exists.
 *
 * @private
 * @param {Object} cache The cache to query.
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */

var _cacheHas;
var hasRequired_cacheHas;

function require_cacheHas () {
	if (hasRequired_cacheHas) return _cacheHas;
	hasRequired_cacheHas = 1;
	function cacheHas(cache, key) {
	  return cache.has(key);
	}

	_cacheHas = cacheHas;
	return _cacheHas;
}

var _baseDifference;
var hasRequired_baseDifference;

function require_baseDifference () {
	if (hasRequired_baseDifference) return _baseDifference;
	hasRequired_baseDifference = 1;
	var SetCache = require_SetCache(),
	    arrayIncludes = require_arrayIncludes(),
	    arrayIncludesWith = require_arrayIncludesWith(),
	    arrayMap = require_arrayMap(),
	    baseUnary = require_baseUnary(),
	    cacheHas = require_cacheHas();

	/** Used as the size to enable large array optimizations. */
	var LARGE_ARRAY_SIZE = 200;

	/**
	 * The base implementation of methods like `_.difference` without support
	 * for excluding multiple arrays or iteratee shorthands.
	 *
	 * @private
	 * @param {Array} array The array to inspect.
	 * @param {Array} values The values to exclude.
	 * @param {Function} [iteratee] The iteratee invoked per element.
	 * @param {Function} [comparator] The comparator invoked per element.
	 * @returns {Array} Returns the new array of filtered values.
	 */
	function baseDifference(array, values, iteratee, comparator) {
	  var index = -1,
	      includes = arrayIncludes,
	      isCommon = true,
	      length = array.length,
	      result = [],
	      valuesLength = values.length;

	  if (!length) {
	    return result;
	  }
	  if (iteratee) {
	    values = arrayMap(values, baseUnary(iteratee));
	  }
	  if (comparator) {
	    includes = arrayIncludesWith;
	    isCommon = false;
	  }
	  else if (values.length >= LARGE_ARRAY_SIZE) {
	    includes = cacheHas;
	    isCommon = false;
	    values = new SetCache(values);
	  }
	  outer:
	  while (++index < length) {
	    var value = array[index],
	        computed = iteratee == null ? value : iteratee(value);

	    value = (comparator || value !== 0) ? value : 0;
	    if (isCommon && computed === computed) {
	      var valuesIndex = valuesLength;
	      while (valuesIndex--) {
	        if (values[valuesIndex] === computed) {
	          continue outer;
	        }
	      }
	      result.push(value);
	    }
	    else if (!includes(values, computed, comparator)) {
	      result.push(value);
	    }
	  }
	  return result;
	}

	_baseDifference = baseDifference;
	return _baseDifference;
}

var isArrayLikeObject_1;
var hasRequiredIsArrayLikeObject;

function requireIsArrayLikeObject () {
	if (hasRequiredIsArrayLikeObject) return isArrayLikeObject_1;
	hasRequiredIsArrayLikeObject = 1;
	var isArrayLike = requireIsArrayLike(),
	    isObjectLike = requireIsObjectLike();

	/**
	 * This method is like `_.isArrayLike` except that it also checks if `value`
	 * is an object.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an array-like object,
	 *  else `false`.
	 * @example
	 *
	 * _.isArrayLikeObject([1, 2, 3]);
	 * // => true
	 *
	 * _.isArrayLikeObject(document.body.children);
	 * // => true
	 *
	 * _.isArrayLikeObject('abc');
	 * // => false
	 *
	 * _.isArrayLikeObject(_.noop);
	 * // => false
	 */
	function isArrayLikeObject(value) {
	  return isObjectLike(value) && isArrayLike(value);
	}

	isArrayLikeObject_1 = isArrayLikeObject;
	return isArrayLikeObject_1;
}

var difference_1;
var hasRequiredDifference;

function requireDifference () {
	if (hasRequiredDifference) return difference_1;
	hasRequiredDifference = 1;
	var baseDifference = require_baseDifference(),
	    baseFlatten = require_baseFlatten(),
	    baseRest = require_baseRest(),
	    isArrayLikeObject = requireIsArrayLikeObject();

	/**
	 * Creates an array of `array` values not included in the other given arrays
	 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	 * for equality comparisons. The order and references of result values are
	 * determined by the first array.
	 *
	 * **Note:** Unlike `_.pullAll`, this method returns a new array.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Array
	 * @param {Array} array The array to inspect.
	 * @param {...Array} [values] The values to exclude.
	 * @returns {Array} Returns the new array of filtered values.
	 * @see _.without, _.xor
	 * @example
	 *
	 * _.difference([2, 1], [2, 3]);
	 * // => [1]
	 */
	var difference = baseRest(function(array, values) {
	  return isArrayLikeObject(array)
	    ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
	    : [];
	});

	difference_1 = difference;
	return difference_1;
}

var _Set;
var hasRequired_Set;

function require_Set () {
	if (hasRequired_Set) return _Set;
	hasRequired_Set = 1;
	var getNative = require_getNative(),
	    root = require_root();

	/* Built-in method references that are verified to be native. */
	var Set = getNative(root, 'Set');

	_Set = Set;
	return _Set;
}

/**
 * This method returns `undefined`.
 *
 * @static
 * @memberOf _
 * @since 2.3.0
 * @category Util
 * @example
 *
 * _.times(2, _.noop);
 * // => [undefined, undefined]
 */

var noop_1;
var hasRequiredNoop;

function requireNoop () {
	if (hasRequiredNoop) return noop_1;
	hasRequiredNoop = 1;
	function noop() {
	  // No operation performed.
	}

	noop_1 = noop;
	return noop_1;
}

/**
 * Converts `set` to an array of its values.
 *
 * @private
 * @param {Object} set The set to convert.
 * @returns {Array} Returns the values.
 */

var _setToArray;
var hasRequired_setToArray;

function require_setToArray () {
	if (hasRequired_setToArray) return _setToArray;
	hasRequired_setToArray = 1;
	function setToArray(set) {
	  var index = -1,
	      result = Array(set.size);

	  set.forEach(function(value) {
	    result[++index] = value;
	  });
	  return result;
	}

	_setToArray = setToArray;
	return _setToArray;
}

var _createSet;
var hasRequired_createSet;

function require_createSet () {
	if (hasRequired_createSet) return _createSet;
	hasRequired_createSet = 1;
	var Set = require_Set(),
	    noop = requireNoop(),
	    setToArray = require_setToArray();

	/** Used as references for various `Number` constants. */
	var INFINITY = 1 / 0;

	/**
	 * Creates a set object of `values`.
	 *
	 * @private
	 * @param {Array} values The values to add to the set.
	 * @returns {Object} Returns the new set.
	 */
	var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
	  return new Set(values);
	};

	_createSet = createSet;
	return _createSet;
}

var _baseUniq;
var hasRequired_baseUniq;

function require_baseUniq () {
	if (hasRequired_baseUniq) return _baseUniq;
	hasRequired_baseUniq = 1;
	var SetCache = require_SetCache(),
	    arrayIncludes = require_arrayIncludes(),
	    arrayIncludesWith = require_arrayIncludesWith(),
	    cacheHas = require_cacheHas(),
	    createSet = require_createSet(),
	    setToArray = require_setToArray();

	/** Used as the size to enable large array optimizations. */
	var LARGE_ARRAY_SIZE = 200;

	/**
	 * The base implementation of `_.uniqBy` without support for iteratee shorthands.
	 *
	 * @private
	 * @param {Array} array The array to inspect.
	 * @param {Function} [iteratee] The iteratee invoked per element.
	 * @param {Function} [comparator] The comparator invoked per element.
	 * @returns {Array} Returns the new duplicate free array.
	 */
	function baseUniq(array, iteratee, comparator) {
	  var index = -1,
	      includes = arrayIncludes,
	      length = array.length,
	      isCommon = true,
	      result = [],
	      seen = result;

	  if (comparator) {
	    isCommon = false;
	    includes = arrayIncludesWith;
	  }
	  else if (length >= LARGE_ARRAY_SIZE) {
	    var set = iteratee ? null : createSet(array);
	    if (set) {
	      return setToArray(set);
	    }
	    isCommon = false;
	    includes = cacheHas;
	    seen = new SetCache;
	  }
	  else {
	    seen = iteratee ? [] : result;
	  }
	  outer:
	  while (++index < length) {
	    var value = array[index],
	        computed = iteratee ? iteratee(value) : value;

	    value = (comparator || value !== 0) ? value : 0;
	    if (isCommon && computed === computed) {
	      var seenIndex = seen.length;
	      while (seenIndex--) {
	        if (seen[seenIndex] === computed) {
	          continue outer;
	        }
	      }
	      if (iteratee) {
	        seen.push(computed);
	      }
	      result.push(value);
	    }
	    else if (!includes(seen, computed, comparator)) {
	      if (seen !== result) {
	        seen.push(computed);
	      }
	      result.push(value);
	    }
	  }
	  return result;
	}

	_baseUniq = baseUniq;
	return _baseUniq;
}

var union_1;
var hasRequiredUnion;

function requireUnion () {
	if (hasRequiredUnion) return union_1;
	hasRequiredUnion = 1;
	var baseFlatten = require_baseFlatten(),
	    baseRest = require_baseRest(),
	    baseUniq = require_baseUniq(),
	    isArrayLikeObject = requireIsArrayLikeObject();

	/**
	 * Creates an array of unique values, in order, from all given arrays using
	 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	 * for equality comparisons.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Array
	 * @param {...Array} [arrays] The arrays to inspect.
	 * @returns {Array} Returns the new array of combined values.
	 * @example
	 *
	 * _.union([2], [1, 2]);
	 * // => [2, 1]
	 */
	var union = baseRest(function(arrays) {
	  return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
	});

	union_1 = union;
	return union_1;
}

/**
 * Creates a unary function that invokes `func` with its argument transformed.
 *
 * @private
 * @param {Function} func The function to wrap.
 * @param {Function} transform The argument transform.
 * @returns {Function} Returns the new function.
 */

var _overArg;
var hasRequired_overArg;

function require_overArg () {
	if (hasRequired_overArg) return _overArg;
	hasRequired_overArg = 1;
	function overArg(func, transform) {
	  return function(arg) {
	    return func(transform(arg));
	  };
	}

	_overArg = overArg;
	return _overArg;
}

var _getPrototype;
var hasRequired_getPrototype;

function require_getPrototype () {
	if (hasRequired_getPrototype) return _getPrototype;
	hasRequired_getPrototype = 1;
	var overArg = require_overArg();

	/** Built-in value references. */
	var getPrototype = overArg(Object.getPrototypeOf, Object);

	_getPrototype = getPrototype;
	return _getPrototype;
}

var isPlainObject_1;
var hasRequiredIsPlainObject;

function requireIsPlainObject () {
	if (hasRequiredIsPlainObject) return isPlainObject_1;
	hasRequiredIsPlainObject = 1;
	var baseGetTag = require_baseGetTag(),
	    getPrototype = require_getPrototype(),
	    isObjectLike = requireIsObjectLike();

	/** `Object#toString` result references. */
	var objectTag = '[object Object]';

	/** Used for built-in method references. */
	var funcProto = Function.prototype,
	    objectProto = Object.prototype;

	/** Used to resolve the decompiled source of functions. */
	var funcToString = funcProto.toString;

	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;

	/** Used to infer the `Object` constructor. */
	var objectCtorString = funcToString.call(Object);

	/**
	 * Checks if `value` is a plain object, that is, an object created by the
	 * `Object` constructor or one with a `[[Prototype]]` of `null`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.8.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
	 * @example
	 *
	 * function Foo() {
	 *   this.a = 1;
	 * }
	 *
	 * _.isPlainObject(new Foo);
	 * // => false
	 *
	 * _.isPlainObject([1, 2, 3]);
	 * // => false
	 *
	 * _.isPlainObject({ 'x': 0, 'y': 0 });
	 * // => true
	 *
	 * _.isPlainObject(Object.create(null));
	 * // => true
	 */
	function isPlainObject(value) {
	  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
	    return false;
	  }
	  var proto = getPrototype(value);
	  if (proto === null) {
	    return true;
	  }
	  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
	  return typeof Ctor == 'function' && Ctor instanceof Ctor &&
	    funcToString.call(Ctor) == objectCtorString;
	}

	isPlainObject_1 = isPlainObject;
	return isPlainObject_1;
}

var old = {};

var hasRequiredOld;

function requireOld () {
	if (hasRequiredOld) return old;
	hasRequiredOld = 1;
	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.

	var pathModule = require$$1;
	var isWindows = process.platform === 'win32';
	var fs = require$$0$2;

	// JavaScript implementation of realpath, ported from node pre-v6

	var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);

	function rethrow() {
	  // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
	  // is fairly slow to generate.
	  var callback;
	  if (DEBUG) {
	    var backtrace = new Error;
	    callback = debugCallback;
	  } else
	    callback = missingCallback;

	  return callback;

	  function debugCallback(err) {
	    if (err) {
	      backtrace.message = err.message;
	      err = backtrace;
	      missingCallback(err);
	    }
	  }

	  function missingCallback(err) {
	    if (err) {
	      if (process.throwDeprecation)
	        throw err;  // Forgot a callback but don't know where? Use NODE_DEBUG=fs
	      else if (!process.noDeprecation) {
	        var msg = 'fs: missing callback ' + (err.stack || err.message);
	        if (process.traceDeprecation)
	          console.trace(msg);
	        else
	          console.error(msg);
	      }
	    }
	  }
	}

	function maybeCallback(cb) {
	  return typeof cb === 'function' ? cb : rethrow();
	}

	pathModule.normalize;

	// Regexp that finds the next partion of a (partial) path
	// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
	if (isWindows) {
	  var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
	} else {
	  var nextPartRe = /(.*?)(?:[\/]+|$)/g;
	}

	// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
	if (isWindows) {
	  var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
	} else {
	  var splitRootRe = /^[\/]*/;
	}

	old.realpathSync = function realpathSync(p, cache) {
	  // make p is absolute
	  p = pathModule.resolve(p);

	  if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
	    return cache[p];
	  }

	  var original = p,
	      seenLinks = {},
	      knownHard = {};

	  // current character position in p
	  var pos;
	  // the partial path so far, including a trailing slash if any
	  var current;
	  // the partial path without a trailing slash (except when pointing at a root)
	  var base;
	  // the partial path scanned in the previous round, with slash
	  var previous;

	  start();

	  function start() {
	    // Skip over roots
	    var m = splitRootRe.exec(p);
	    pos = m[0].length;
	    current = m[0];
	    base = m[0];
	    previous = '';

	    // On windows, check that the root exists. On unix there is no need.
	    if (isWindows && !knownHard[base]) {
	      fs.lstatSync(base);
	      knownHard[base] = true;
	    }
	  }

	  // walk down the path, swapping out linked pathparts for their real
	  // values
	  // NB: p.length changes.
	  while (pos < p.length) {
	    // find the next part
	    nextPartRe.lastIndex = pos;
	    var result = nextPartRe.exec(p);
	    previous = current;
	    current += result[0];
	    base = previous + result[1];
	    pos = nextPartRe.lastIndex;

	    // continue if not a symlink
	    if (knownHard[base] || (cache && cache[base] === base)) {
	      continue;
	    }

	    var resolvedLink;
	    if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
	      // some known symbolic link.  no need to stat again.
	      resolvedLink = cache[base];
	    } else {
	      var stat = fs.lstatSync(base);
	      if (!stat.isSymbolicLink()) {
	        knownHard[base] = true;
	        if (cache) cache[base] = base;
	        continue;
	      }

	      // read the link if it wasn't read before
	      // dev/ino always return 0 on windows, so skip the check.
	      var linkTarget = null;
	      if (!isWindows) {
	        var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
	        if (seenLinks.hasOwnProperty(id)) {
	          linkTarget = seenLinks[id];
	        }
	      }
	      if (linkTarget === null) {
	        fs.statSync(base);
	        linkTarget = fs.readlinkSync(base);
	      }
	      resolvedLink = pathModule.resolve(previous, linkTarget);
	      // track this, if given a cache.
	      if (cache) cache[base] = resolvedLink;
	      if (!isWindows) seenLinks[id] = linkTarget;
	    }

	    // resolve the link, then start over
	    p = pathModule.resolve(resolvedLink, p.slice(pos));
	    start();
	  }

	  if (cache) cache[original] = p;

	  return p;
	};


	old.realpath = function realpath(p, cache, cb) {
	  if (typeof cb !== 'function') {
	    cb = maybeCallback(cache);
	    cache = null;
	  }

	  // make p is absolute
	  p = pathModule.resolve(p);

	  if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
	    return process.nextTick(cb.bind(null, null, cache[p]));
	  }

	  var original = p,
	      seenLinks = {},
	      knownHard = {};

	  // current character position in p
	  var pos;
	  // the partial path so far, including a trailing slash if any
	  var current;
	  // the partial path without a trailing slash (except when pointing at a root)
	  var base;
	  // the partial path scanned in the previous round, with slash
	  var previous;

	  start();

	  function start() {
	    // Skip over roots
	    var m = splitRootRe.exec(p);
	    pos = m[0].length;
	    current = m[0];
	    base = m[0];
	    previous = '';

	    // On windows, check that the root exists. On unix there is no need.
	    if (isWindows && !knownHard[base]) {
	      fs.lstat(base, function(err) {
	        if (err) return cb(err);
	        knownHard[base] = true;
	        LOOP();
	      });
	    } else {
	      process.nextTick(LOOP);
	    }
	  }

	  // walk down the path, swapping out linked pathparts for their real
	  // values
	  function LOOP() {
	    // stop if scanned past end of path
	    if (pos >= p.length) {
	      if (cache) cache[original] = p;
	      return cb(null, p);
	    }

	    // find the next part
	    nextPartRe.lastIndex = pos;
	    var result = nextPartRe.exec(p);
	    previous = current;
	    current += result[0];
	    base = previous + result[1];
	    pos = nextPartRe.lastIndex;

	    // continue if not a symlink
	    if (knownHard[base] || (cache && cache[base] === base)) {
	      return process.nextTick(LOOP);
	    }

	    if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
	      // known symbolic link.  no need to stat again.
	      return gotResolvedLink(cache[base]);
	    }

	    return fs.lstat(base, gotStat);
	  }

	  function gotStat(err, stat) {
	    if (err) return cb(err);

	    // if not a symlink, skip to the next path part
	    if (!stat.isSymbolicLink()) {
	      knownHard[base] = true;
	      if (cache) cache[base] = base;
	      return process.nextTick(LOOP);
	    }

	    // stat & read the link if not read before
	    // call gotTarget as soon as the link target is known
	    // dev/ino always return 0 on windows, so skip the check.
	    if (!isWindows) {
	      var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
	      if (seenLinks.hasOwnProperty(id)) {
	        return gotTarget(null, seenLinks[id], base);
	      }
	    }
	    fs.stat(base, function(err) {
	      if (err) return cb(err);

	      fs.readlink(base, function(err, target) {
	        if (!isWindows) seenLinks[id] = target;
	        gotTarget(err, target);
	      });
	    });
	  }

	  function gotTarget(err, target, base) {
	    if (err) return cb(err);

	    var resolvedLink = pathModule.resolve(previous, target);
	    if (cache) cache[base] = resolvedLink;
	    gotResolvedLink(resolvedLink);
	  }

	  function gotResolvedLink(resolvedLink) {
	    // resolve the link, then start over
	    p = pathModule.resolve(resolvedLink, p.slice(pos));
	    start();
	  }
	};
	return old;
}

var fs_realpath;
var hasRequiredFs_realpath;

function requireFs_realpath () {
	if (hasRequiredFs_realpath) return fs_realpath;
	hasRequiredFs_realpath = 1;
	fs_realpath = realpath;
	realpath.realpath = realpath;
	realpath.sync = realpathSync;
	realpath.realpathSync = realpathSync;
	realpath.monkeypatch = monkeypatch;
	realpath.unmonkeypatch = unmonkeypatch;

	var fs = require$$0$2;
	var origRealpath = fs.realpath;
	var origRealpathSync = fs.realpathSync;

	var version = process.version;
	var ok = /^v[0-5]\./.test(version);
	var old = requireOld();

	function newError (er) {
	  return er && er.syscall === 'realpath' && (
	    er.code === 'ELOOP' ||
	    er.code === 'ENOMEM' ||
	    er.code === 'ENAMETOOLONG'
	  )
	}

	function realpath (p, cache, cb) {
	  if (ok) {
	    return origRealpath(p, cache, cb)
	  }

	  if (typeof cache === 'function') {
	    cb = cache;
	    cache = null;
	  }
	  origRealpath(p, cache, function (er, result) {
	    if (newError(er)) {
	      old.realpath(p, cache, cb);
	    } else {
	      cb(er, result);
	    }
	  });
	}

	function realpathSync (p, cache) {
	  if (ok) {
	    return origRealpathSync(p, cache)
	  }

	  try {
	    return origRealpathSync(p, cache)
	  } catch (er) {
	    if (newError(er)) {
	      return old.realpathSync(p, cache)
	    } else {
	      throw er
	    }
	  }
	}

	function monkeypatch () {
	  fs.realpath = realpath;
	  fs.realpathSync = realpathSync;
	}

	function unmonkeypatch () {
	  fs.realpath = origRealpath;
	  fs.realpathSync = origRealpathSync;
	}
	return fs_realpath;
}

var common = {};

var hasRequiredCommon;

function requireCommon () {
	if (hasRequiredCommon) return common;
	hasRequiredCommon = 1;
	common.setopts = setopts;
	common.ownProp = ownProp;
	common.makeAbs = makeAbs;
	common.finish = finish;
	common.mark = mark;
	common.isIgnored = isIgnored;
	common.childrenIgnored = childrenIgnored;

	function ownProp (obj, field) {
	  return Object.prototype.hasOwnProperty.call(obj, field)
	}

	var fs = require$$0$2;
	var path = require$$1;
	var minimatch = requireMinimatch();
	var isAbsolute = require$$1.isAbsolute;
	var Minimatch = minimatch.Minimatch;

	function alphasort (a, b) {
	  return a.localeCompare(b, 'en')
	}

	function setupIgnores (self, options) {
	  self.ignore = options.ignore || [];

	  if (!Array.isArray(self.ignore))
	    self.ignore = [self.ignore];

	  if (self.ignore.length) {
	    self.ignore = self.ignore.map(ignoreMap);
	  }
	}

	// ignore patterns are always in dot:true mode.
	function ignoreMap (pattern) {
	  var gmatcher = null;
	  if (pattern.slice(-3) === '/**') {
	    var gpattern = pattern.replace(/(\/\*\*)+$/, '');
	    gmatcher = new Minimatch(gpattern, { dot: true });
	  }

	  return {
	    matcher: new Minimatch(pattern, { dot: true }),
	    gmatcher: gmatcher
	  }
	}

	function setopts (self, pattern, options) {
	  if (!options)
	    options = {};

	  // base-matching: just use globstar for that.
	  if (options.matchBase && -1 === pattern.indexOf("/")) {
	    if (options.noglobstar) {
	      throw new Error("base matching requires globstar")
	    }
	    pattern = "**/" + pattern;
	  }

	  self.windowsPathsNoEscape = !!options.windowsPathsNoEscape ||
	    options.allowWindowsEscape === false;
	  if (self.windowsPathsNoEscape) {
	    pattern = pattern.replace(/\\/g, '/');
	  }

	  self.silent = !!options.silent;
	  self.pattern = pattern;
	  self.strict = options.strict !== false;
	  self.realpath = !!options.realpath;
	  self.realpathCache = options.realpathCache || Object.create(null);
	  self.follow = !!options.follow;
	  self.dot = !!options.dot;
	  self.mark = !!options.mark;
	  self.nodir = !!options.nodir;
	  if (self.nodir)
	    self.mark = true;
	  self.sync = !!options.sync;
	  self.nounique = !!options.nounique;
	  self.nonull = !!options.nonull;
	  self.nosort = !!options.nosort;
	  self.nocase = !!options.nocase;
	  self.stat = !!options.stat;
	  self.noprocess = !!options.noprocess;
	  self.absolute = !!options.absolute;
	  self.fs = options.fs || fs;

	  self.maxLength = options.maxLength || Infinity;
	  self.cache = options.cache || Object.create(null);
	  self.statCache = options.statCache || Object.create(null);
	  self.symlinks = options.symlinks || Object.create(null);

	  setupIgnores(self, options);

	  self.changedCwd = false;
	  var cwd = process.cwd();
	  if (!ownProp(options, "cwd"))
	    self.cwd = path.resolve(cwd);
	  else {
	    self.cwd = path.resolve(options.cwd);
	    self.changedCwd = self.cwd !== cwd;
	  }

	  self.root = options.root || path.resolve(self.cwd, "/");
	  self.root = path.resolve(self.root);

	  // TODO: is an absolute `cwd` supposed to be resolved against `root`?
	  // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test')
	  self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd);
	  self.nomount = !!options.nomount;

	  if (process.platform === "win32") {
	    self.root = self.root.replace(/\\/g, "/");
	    self.cwd = self.cwd.replace(/\\/g, "/");
	    self.cwdAbs = self.cwdAbs.replace(/\\/g, "/");
	  }

	  // disable comments and negation in Minimatch.
	  // Note that they are not supported in Glob itself anyway.
	  options.nonegate = true;
	  options.nocomment = true;

	  self.minimatch = new Minimatch(pattern, options);
	  self.options = self.minimatch.options;
	}

	function finish (self) {
	  var nou = self.nounique;
	  var all = nou ? [] : Object.create(null);

	  for (var i = 0, l = self.matches.length; i < l; i ++) {
	    var matches = self.matches[i];
	    if (!matches || Object.keys(matches).length === 0) {
	      if (self.nonull) {
	        // do like the shell, and spit out the literal glob
	        var literal = self.minimatch.globSet[i];
	        if (nou)
	          all.push(literal);
	        else
	          all[literal] = true;
	      }
	    } else {
	      // had matches
	      var m = Object.keys(matches);
	      if (nou)
	        all.push.apply(all, m);
	      else
	        m.forEach(function (m) {
	          all[m] = true;
	        });
	    }
	  }

	  if (!nou)
	    all = Object.keys(all);

	  if (!self.nosort)
	    all = all.sort(alphasort);

	  // at *some* point we statted all of these
	  if (self.mark) {
	    for (var i = 0; i < all.length; i++) {
	      all[i] = self._mark(all[i]);
	    }
	    if (self.nodir) {
	      all = all.filter(function (e) {
	        var notDir = !(/\/$/.test(e));
	        var c = self.cache[e] || self.cache[makeAbs(self, e)];
	        if (notDir && c)
	          notDir = c !== 'DIR' && !Array.isArray(c);
	        return notDir
	      });
	    }
	  }

	  if (self.ignore.length)
	    all = all.filter(function(m) {
	      return !isIgnored(self, m)
	    });

	  self.found = all;
	}

	function mark (self, p) {
	  var abs = makeAbs(self, p);
	  var c = self.cache[abs];
	  var m = p;
	  if (c) {
	    var isDir = c === 'DIR' || Array.isArray(c);
	    var slash = p.slice(-1) === '/';

	    if (isDir && !slash)
	      m += '/';
	    else if (!isDir && slash)
	      m = m.slice(0, -1);

	    if (m !== p) {
	      var mabs = makeAbs(self, m);
	      self.statCache[mabs] = self.statCache[abs];
	      self.cache[mabs] = self.cache[abs];
	    }
	  }

	  return m
	}

	// lotta situps...
	function makeAbs (self, f) {
	  var abs = f;
	  if (f.charAt(0) === '/') {
	    abs = path.join(self.root, f);
	  } else if (isAbsolute(f) || f === '') {
	    abs = f;
	  } else if (self.changedCwd) {
	    abs = path.resolve(self.cwd, f);
	  } else {
	    abs = path.resolve(f);
	  }

	  if (process.platform === 'win32')
	    abs = abs.replace(/\\/g, '/');

	  return abs
	}


	// Return true, if pattern ends with globstar '**', for the accompanying parent directory.
	// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents
	function isIgnored (self, path) {
	  if (!self.ignore.length)
	    return false

	  return self.ignore.some(function(item) {
	    return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path))
	  })
	}

	function childrenIgnored (self, path) {
	  if (!self.ignore.length)
	    return false

	  return self.ignore.some(function(item) {
	    return !!(item.gmatcher && item.gmatcher.match(path))
	  })
	}
	return common;
}

var sync;
var hasRequiredSync;

function requireSync () {
	if (hasRequiredSync) return sync;
	hasRequiredSync = 1;
	sync = globSync;
	globSync.GlobSync = GlobSync;

	var rp = requireFs_realpath();
	var minimatch = requireMinimatch();
	minimatch.Minimatch;
	requireGlob().Glob;
	var path = require$$1;
	var assert = require$$5;
	var isAbsolute = require$$1.isAbsolute;
	var common = requireCommon();
	var setopts = common.setopts;
	var ownProp = common.ownProp;
	var childrenIgnored = common.childrenIgnored;
	var isIgnored = common.isIgnored;

	function globSync (pattern, options) {
	  if (typeof options === 'function' || arguments.length === 3)
	    throw new TypeError('callback provided to sync glob\n'+
	                        'See: https://github.com/isaacs/node-glob/issues/167')

	  return new GlobSync(pattern, options).found
	}

	function GlobSync (pattern, options) {
	  if (!pattern)
	    throw new Error('must provide pattern')

	  if (typeof options === 'function' || arguments.length === 3)
	    throw new TypeError('callback provided to sync glob\n'+
	                        'See: https://github.com/isaacs/node-glob/issues/167')

	  if (!(this instanceof GlobSync))
	    return new GlobSync(pattern, options)

	  setopts(this, pattern, options);

	  if (this.noprocess)
	    return this

	  var n = this.minimatch.set.length;
	  this.matches = new Array(n);
	  for (var i = 0; i < n; i ++) {
	    this._process(this.minimatch.set[i], i, false);
	  }
	  this._finish();
	}

	GlobSync.prototype._finish = function () {
	  assert.ok(this instanceof GlobSync);
	  if (this.realpath) {
	    var self = this;
	    this.matches.forEach(function (matchset, index) {
	      var set = self.matches[index] = Object.create(null);
	      for (var p in matchset) {
	        try {
	          p = self._makeAbs(p);
	          var real = rp.realpathSync(p, self.realpathCache);
	          set[real] = true;
	        } catch (er) {
	          if (er.syscall === 'stat')
	            set[self._makeAbs(p)] = true;
	          else
	            throw er
	        }
	      }
	    });
	  }
	  common.finish(this);
	};


	GlobSync.prototype._process = function (pattern, index, inGlobStar) {
	  assert.ok(this instanceof GlobSync);

	  // Get the first [n] parts of pattern that are all strings.
	  var n = 0;
	  while (typeof pattern[n] === 'string') {
	    n ++;
	  }
	  // now n is the index of the first one that is *not* a string.

	  // See if there's anything else
	  var prefix;
	  switch (n) {
	    // if not, then this is rather simple
	    case pattern.length:
	      this._processSimple(pattern.join('/'), index);
	      return

	    case 0:
	      // pattern *starts* with some non-trivial item.
	      // going to readdir(cwd), but not include the prefix in matches.
	      prefix = null;
	      break

	    default:
	      // pattern has some string bits in the front.
	      // whatever it starts with, whether that's 'absolute' like /foo/bar,
	      // or 'relative' like '../baz'
	      prefix = pattern.slice(0, n).join('/');
	      break
	  }

	  var remain = pattern.slice(n);

	  // get the list of entries.
	  var read;
	  if (prefix === null)
	    read = '.';
	  else if (isAbsolute(prefix) ||
	      isAbsolute(pattern.map(function (p) {
	        return typeof p === 'string' ? p : '[*]'
	      }).join('/'))) {
	    if (!prefix || !isAbsolute(prefix))
	      prefix = '/' + prefix;
	    read = prefix;
	  } else
	    read = prefix;

	  var abs = this._makeAbs(read);

	  //if ignored, skip processing
	  if (childrenIgnored(this, read))
	    return

	  var isGlobStar = remain[0] === minimatch.GLOBSTAR;
	  if (isGlobStar)
	    this._processGlobStar(prefix, read, abs, remain, index, inGlobStar);
	  else
	    this._processReaddir(prefix, read, abs, remain, index, inGlobStar);
	};


	GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) {
	  var entries = this._readdir(abs, inGlobStar);

	  // if the abs isn't a dir, then nothing can match!
	  if (!entries)
	    return

	  // It will only match dot entries if it starts with a dot, or if
	  // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
	  var pn = remain[0];
	  var negate = !!this.minimatch.negate;
	  var rawGlob = pn._glob;
	  var dotOk = this.dot || rawGlob.charAt(0) === '.';

	  var matchedEntries = [];
	  for (var i = 0; i < entries.length; i++) {
	    var e = entries[i];
	    if (e.charAt(0) !== '.' || dotOk) {
	      var m;
	      if (negate && !prefix) {
	        m = !e.match(pn);
	      } else {
	        m = e.match(pn);
	      }
	      if (m)
	        matchedEntries.push(e);
	    }
	  }

	  var len = matchedEntries.length;
	  // If there are no matched entries, then nothing matches.
	  if (len === 0)
	    return

	  // if this is the last remaining pattern bit, then no need for
	  // an additional stat *unless* the user has specified mark or
	  // stat explicitly.  We know they exist, since readdir returned
	  // them.

	  if (remain.length === 1 && !this.mark && !this.stat) {
	    if (!this.matches[index])
	      this.matches[index] = Object.create(null);

	    for (var i = 0; i < len; i ++) {
	      var e = matchedEntries[i];
	      if (prefix) {
	        if (prefix.slice(-1) !== '/')
	          e = prefix + '/' + e;
	        else
	          e = prefix + e;
	      }

	      if (e.charAt(0) === '/' && !this.nomount) {
	        e = path.join(this.root, e);
	      }
	      this._emitMatch(index, e);
	    }
	    // This was the last one, and no stats were needed
	    return
	  }

	  // now test all matched entries as stand-ins for that part
	  // of the pattern.
	  remain.shift();
	  for (var i = 0; i < len; i ++) {
	    var e = matchedEntries[i];
	    var newPattern;
	    if (prefix)
	      newPattern = [prefix, e];
	    else
	      newPattern = [e];
	    this._process(newPattern.concat(remain), index, inGlobStar);
	  }
	};


	GlobSync.prototype._emitMatch = function (index, e) {
	  if (isIgnored(this, e))
	    return

	  var abs = this._makeAbs(e);

	  if (this.mark)
	    e = this._mark(e);

	  if (this.absolute) {
	    e = abs;
	  }

	  if (this.matches[index][e])
	    return

	  if (this.nodir) {
	    var c = this.cache[abs];
	    if (c === 'DIR' || Array.isArray(c))
	      return
	  }

	  this.matches[index][e] = true;

	  if (this.stat)
	    this._stat(e);
	};


	GlobSync.prototype._readdirInGlobStar = function (abs) {
	  // follow all symlinked directories forever
	  // just proceed as if this is a non-globstar situation
	  if (this.follow)
	    return this._readdir(abs, false)

	  var entries;
	  var lstat;
	  try {
	    lstat = this.fs.lstatSync(abs);
	  } catch (er) {
	    if (er.code === 'ENOENT') {
	      // lstat failed, doesn't exist
	      return null
	    }
	  }

	  var isSym = lstat && lstat.isSymbolicLink();
	  this.symlinks[abs] = isSym;

	  // If it's not a symlink or a dir, then it's definitely a regular file.
	  // don't bother doing a readdir in that case.
	  if (!isSym && lstat && !lstat.isDirectory())
	    this.cache[abs] = 'FILE';
	  else
	    entries = this._readdir(abs, false);

	  return entries
	};

	GlobSync.prototype._readdir = function (abs, inGlobStar) {

	  if (inGlobStar && !ownProp(this.symlinks, abs))
	    return this._readdirInGlobStar(abs)

	  if (ownProp(this.cache, abs)) {
	    var c = this.cache[abs];
	    if (!c || c === 'FILE')
	      return null

	    if (Array.isArray(c))
	      return c
	  }

	  try {
	    return this._readdirEntries(abs, this.fs.readdirSync(abs))
	  } catch (er) {
	    this._readdirError(abs, er);
	    return null
	  }
	};

	GlobSync.prototype._readdirEntries = function (abs, entries) {
	  // if we haven't asked to stat everything, then just
	  // assume that everything in there exists, so we can avoid
	  // having to stat it a second time.
	  if (!this.mark && !this.stat) {
	    for (var i = 0; i < entries.length; i ++) {
	      var e = entries[i];
	      if (abs === '/')
	        e = abs + e;
	      else
	        e = abs + '/' + e;
	      this.cache[e] = true;
	    }
	  }

	  this.cache[abs] = entries;

	  // mark and cache dir-ness
	  return entries
	};

	GlobSync.prototype._readdirError = function (f, er) {
	  // handle errors, and cache the information
	  switch (er.code) {
	    case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
	    case 'ENOTDIR': // totally normal. means it *does* exist.
	      var abs = this._makeAbs(f);
	      this.cache[abs] = 'FILE';
	      if (abs === this.cwdAbs) {
	        var error = new Error(er.code + ' invalid cwd ' + this.cwd);
	        error.path = this.cwd;
	        error.code = er.code;
	        throw error
	      }
	      break

	    case 'ENOENT': // not terribly unusual
	    case 'ELOOP':
	    case 'ENAMETOOLONG':
	    case 'UNKNOWN':
	      this.cache[this._makeAbs(f)] = false;
	      break

	    default: // some unusual error.  Treat as failure.
	      this.cache[this._makeAbs(f)] = false;
	      if (this.strict)
	        throw er
	      if (!this.silent)
	        console.error('glob error', er);
	      break
	  }
	};

	GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) {

	  var entries = this._readdir(abs, inGlobStar);

	  // no entries means not a dir, so it can never have matches
	  // foo.txt/** doesn't match foo.txt
	  if (!entries)
	    return

	  // test without the globstar, and with every child both below
	  // and replacing the globstar.
	  var remainWithoutGlobStar = remain.slice(1);
	  var gspref = prefix ? [ prefix ] : [];
	  var noGlobStar = gspref.concat(remainWithoutGlobStar);

	  // the noGlobStar pattern exits the inGlobStar state
	  this._process(noGlobStar, index, false);

	  var len = entries.length;
	  var isSym = this.symlinks[abs];

	  // If it's a symlink, and we're in a globstar, then stop
	  if (isSym && inGlobStar)
	    return

	  for (var i = 0; i < len; i++) {
	    var e = entries[i];
	    if (e.charAt(0) === '.' && !this.dot)
	      continue

	    // these two cases enter the inGlobStar state
	    var instead = gspref.concat(entries[i], remainWithoutGlobStar);
	    this._process(instead, index, true);

	    var below = gspref.concat(entries[i], remain);
	    this._process(below, index, true);
	  }
	};

	GlobSync.prototype._processSimple = function (prefix, index) {
	  // XXX review this.  Shouldn't it be doing the mounting etc
	  // before doing stat?  kinda weird?
	  var exists = this._stat(prefix);

	  if (!this.matches[index])
	    this.matches[index] = Object.create(null);

	  // If it doesn't exist, then just mark the lack of results
	  if (!exists)
	    return

	  if (prefix && isAbsolute(prefix) && !this.nomount) {
	    var trail = /[\/\\]$/.test(prefix);
	    if (prefix.charAt(0) === '/') {
	      prefix = path.join(this.root, prefix);
	    } else {
	      prefix = path.resolve(this.root, prefix);
	      if (trail)
	        prefix += '/';
	    }
	  }

	  if (process.platform === 'win32')
	    prefix = prefix.replace(/\\/g, '/');

	  // Mark this as a match
	  this._emitMatch(index, prefix);
	};

	// Returns either 'DIR', 'FILE', or false
	GlobSync.prototype._stat = function (f) {
	  var abs = this._makeAbs(f);
	  var needDir = f.slice(-1) === '/';

	  if (f.length > this.maxLength)
	    return false

	  if (!this.stat && ownProp(this.cache, abs)) {
	    var c = this.cache[abs];

	    if (Array.isArray(c))
	      c = 'DIR';

	    // It exists, but maybe not how we need it
	    if (!needDir || c === 'DIR')
	      return c

	    if (needDir && c === 'FILE')
	      return false

	    // otherwise we have to stat, because maybe c=true
	    // if we know it exists, but not what it is.
	  }
	  var stat = this.statCache[abs];
	  if (!stat) {
	    var lstat;
	    try {
	      lstat = this.fs.lstatSync(abs);
	    } catch (er) {
	      if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
	        this.statCache[abs] = false;
	        return false
	      }
	    }

	    if (lstat && lstat.isSymbolicLink()) {
	      try {
	        stat = this.fs.statSync(abs);
	      } catch (er) {
	        stat = lstat;
	      }
	    } else {
	      stat = lstat;
	    }
	  }

	  this.statCache[abs] = stat;

	  var c = true;
	  if (stat)
	    c = stat.isDirectory() ? 'DIR' : 'FILE';

	  this.cache[abs] = this.cache[abs] || c;

	  if (needDir && c === 'FILE')
	    return false

	  return c
	};

	GlobSync.prototype._mark = function (p) {
	  return common.mark(this, p)
	};

	GlobSync.prototype._makeAbs = function (f) {
	  return common.makeAbs(this, f)
	};
	return sync;
}

var wrappy_1;
var hasRequiredWrappy;

function requireWrappy () {
	if (hasRequiredWrappy) return wrappy_1;
	hasRequiredWrappy = 1;
	// Returns a wrapper function that returns a wrapped callback
	// The wrapper function should do some stuff, and return a
	// presumably different callback function.
	// This makes sure that own properties are retained, so that
	// decorations and such are not lost along the way.
	wrappy_1 = wrappy;
	function wrappy (fn, cb) {
	  if (fn && cb) return wrappy(fn)(cb)

	  if (typeof fn !== 'function')
	    throw new TypeError('need wrapper function')

	  Object.keys(fn).forEach(function (k) {
	    wrapper[k] = fn[k];
	  });

	  return wrapper

	  function wrapper() {
	    var args = new Array(arguments.length);
	    for (var i = 0; i < args.length; i++) {
	      args[i] = arguments[i];
	    }
	    var ret = fn.apply(this, args);
	    var cb = args[args.length-1];
	    if (typeof ret === 'function' && ret !== cb) {
	      Object.keys(cb).forEach(function (k) {
	        ret[k] = cb[k];
	      });
	    }
	    return ret
	  }
	}
	return wrappy_1;
}

var once = {exports: {}};

var hasRequiredOnce;

function requireOnce () {
	if (hasRequiredOnce) return once.exports;
	hasRequiredOnce = 1;
	var wrappy = requireWrappy();
	once.exports = wrappy(once$1);
	once.exports.strict = wrappy(onceStrict);

	once$1.proto = once$1(function () {
	  Object.defineProperty(Function.prototype, 'once', {
	    value: function () {
	      return once$1(this)
	    },
	    configurable: true
	  });

	  Object.defineProperty(Function.prototype, 'onceStrict', {
	    value: function () {
	      return onceStrict(this)
	    },
	    configurable: true
	  });
	});

	function once$1 (fn) {
	  var f = function () {
	    if (f.called) return f.value
	    f.called = true;
	    return f.value = fn.apply(this, arguments)
	  };
	  f.called = false;
	  return f
	}

	function onceStrict (fn) {
	  var f = function () {
	    if (f.called)
	      throw new Error(f.onceError)
	    f.called = true;
	    return f.value = fn.apply(this, arguments)
	  };
	  var name = fn.name || 'Function wrapped with `once`';
	  f.onceError = name + " shouldn't be called more than once";
	  f.called = false;
	  return f
	}
	return once.exports;
}

var inflight_1;
var hasRequiredInflight;

function requireInflight () {
	if (hasRequiredInflight) return inflight_1;
	hasRequiredInflight = 1;
	var wrappy = requireWrappy();
	var reqs = Object.create(null);
	var once = requireOnce();

	inflight_1 = wrappy(inflight);

	function inflight (key, cb) {
	  if (reqs[key]) {
	    reqs[key].push(cb);
	    return null
	  } else {
	    reqs[key] = [cb];
	    return makeres(key)
	  }
	}

	function makeres (key) {
	  return once(function RES () {
	    var cbs = reqs[key];
	    var len = cbs.length;
	    var args = slice(arguments);

	    // XXX It's somewhat ambiguous whether a new callback added in this
	    // pass should be queued for later execution if something in the
	    // list of callbacks throws, or if it should just be discarded.
	    // However, it's such an edge case that it hardly matters, and either
	    // choice is likely as surprising as the other.
	    // As it happens, we do go ahead and schedule it for later execution.
	    try {
	      for (var i = 0; i < len; i++) {
	        cbs[i].apply(null, args);
	      }
	    } finally {
	      if (cbs.length > len) {
	        // added more in the interim.
	        // de-zalgo, just in case, but don't call again.
	        cbs.splice(0, len);
	        process.nextTick(function () {
	          RES.apply(null, args);
	        });
	      } else {
	        delete reqs[key];
	      }
	    }
	  })
	}

	function slice (args) {
	  var length = args.length;
	  var array = [];

	  for (var i = 0; i < length; i++) array[i] = args[i];
	  return array
	}
	return inflight_1;
}

var glob_1;
var hasRequiredGlob;

function requireGlob () {
	if (hasRequiredGlob) return glob_1;
	hasRequiredGlob = 1;
	// Approach:
	//
	// 1. Get the minimatch set
	// 2. For each pattern in the set, PROCESS(pattern, false)
	// 3. Store matches per-set, then uniq them
	//
	// PROCESS(pattern, inGlobStar)
	// Get the first [n] items from pattern that are all strings
	// Join these together.  This is PREFIX.
	//   If there is no more remaining, then stat(PREFIX) and
	//   add to matches if it succeeds.  END.
	//
	// If inGlobStar and PREFIX is symlink and points to dir
	//   set ENTRIES = []
	// else readdir(PREFIX) as ENTRIES
	//   If fail, END
	//
	// with ENTRIES
	//   If pattern[n] is GLOBSTAR
	//     // handle the case where the globstar match is empty
	//     // by pruning it out, and testing the resulting pattern
	//     PROCESS(pattern[0..n] + pattern[n+1 .. $], false)
	//     // handle other cases.
	//     for ENTRY in ENTRIES (not dotfiles)
	//       // attach globstar + tail onto the entry
	//       // Mark that this entry is a globstar match
	//       PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true)
	//
	//   else // not globstar
	//     for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
	//       Test ENTRY against pattern[n]
	//       If fails, continue
	//       If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
	//
	// Caveat:
	//   Cache all stats and readdirs results to minimize syscall.  Since all
	//   we ever care about is existence and directory-ness, we can just keep
	//   `true` for files, and [children,...] for directories, or `false` for
	//   things that don't exist.

	glob_1 = glob;

	var rp = requireFs_realpath();
	var minimatch = requireMinimatch();
	minimatch.Minimatch;
	var inherits = requireInherits();
	var EE = require$$0$1.EventEmitter;
	var path = require$$1;
	var assert = require$$5;
	var isAbsolute = require$$1.isAbsolute;
	var globSync = requireSync();
	var common = requireCommon();
	var setopts = common.setopts;
	var ownProp = common.ownProp;
	var inflight = requireInflight();
	var childrenIgnored = common.childrenIgnored;
	var isIgnored = common.isIgnored;

	var once = requireOnce();

	function glob (pattern, options, cb) {
	  if (typeof options === 'function') cb = options, options = {};
	  if (!options) options = {};

	  if (options.sync) {
	    if (cb)
	      throw new TypeError('callback provided to sync glob')
	    return globSync(pattern, options)
	  }

	  return new Glob(pattern, options, cb)
	}

	glob.sync = globSync;
	var GlobSync = glob.GlobSync = globSync.GlobSync;

	// old api surface
	glob.glob = glob;

	function extend (origin, add) {
	  if (add === null || typeof add !== 'object') {
	    return origin
	  }

	  var keys = Object.keys(add);
	  var i = keys.length;
	  while (i--) {
	    origin[keys[i]] = add[keys[i]];
	  }
	  return origin
	}

	glob.hasMagic = function (pattern, options_) {
	  var options = extend({}, options_);
	  options.noprocess = true;

	  var g = new Glob(pattern, options);
	  var set = g.minimatch.set;

	  if (!pattern)
	    return false

	  if (set.length > 1)
	    return true

	  for (var j = 0; j < set[0].length; j++) {
	    if (typeof set[0][j] !== 'string')
	      return true
	  }

	  return false
	};

	glob.Glob = Glob;
	inherits(Glob, EE);
	function Glob (pattern, options, cb) {
	  if (typeof options === 'function') {
	    cb = options;
	    options = null;
	  }

	  if (options && options.sync) {
	    if (cb)
	      throw new TypeError('callback provided to sync glob')
	    return new GlobSync(pattern, options)
	  }

	  if (!(this instanceof Glob))
	    return new Glob(pattern, options, cb)

	  setopts(this, pattern, options);
	  this._didRealPath = false;

	  // process each pattern in the minimatch set
	  var n = this.minimatch.set.length;

	  // The matches are stored as {<filename>: true,...} so that
	  // duplicates are automagically pruned.
	  // Later, we do an Object.keys() on these.
	  // Keep them as a list so we can fill in when nonull is set.
	  this.matches = new Array(n);

	  if (typeof cb === 'function') {
	    cb = once(cb);
	    this.on('error', cb);
	    this.on('end', function (matches) {
	      cb(null, matches);
	    });
	  }

	  var self = this;
	  this._processing = 0;

	  this._emitQueue = [];
	  this._processQueue = [];
	  this.paused = false;

	  if (this.noprocess)
	    return this

	  if (n === 0)
	    return done()

	  var sync = true;
	  for (var i = 0; i < n; i ++) {
	    this._process(this.minimatch.set[i], i, false, done);
	  }
	  sync = false;

	  function done () {
	    --self._processing;
	    if (self._processing <= 0) {
	      if (sync) {
	        process.nextTick(function () {
	          self._finish();
	        });
	      } else {
	        self._finish();
	      }
	    }
	  }
	}

	Glob.prototype._finish = function () {
	  assert(this instanceof Glob);
	  if (this.aborted)
	    return

	  if (this.realpath && !this._didRealpath)
	    return this._realpath()

	  common.finish(this);
	  this.emit('end', this.found);
	};

	Glob.prototype._realpath = function () {
	  if (this._didRealpath)
	    return

	  this._didRealpath = true;

	  var n = this.matches.length;
	  if (n === 0)
	    return this._finish()

	  var self = this;
	  for (var i = 0; i < this.matches.length; i++)
	    this._realpathSet(i, next);

	  function next () {
	    if (--n === 0)
	      self._finish();
	  }
	};

	Glob.prototype._realpathSet = function (index, cb) {
	  var matchset = this.matches[index];
	  if (!matchset)
	    return cb()

	  var found = Object.keys(matchset);
	  var self = this;
	  var n = found.length;

	  if (n === 0)
	    return cb()

	  var set = this.matches[index] = Object.create(null);
	  found.forEach(function (p, i) {
	    // If there's a problem with the stat, then it means that
	    // one or more of the links in the realpath couldn't be
	    // resolved.  just return the abs value in that case.
	    p = self._makeAbs(p);
	    rp.realpath(p, self.realpathCache, function (er, real) {
	      if (!er)
	        set[real] = true;
	      else if (er.syscall === 'stat')
	        set[p] = true;
	      else
	        self.emit('error', er); // srsly wtf right here

	      if (--n === 0) {
	        self.matches[index] = set;
	        cb();
	      }
	    });
	  });
	};

	Glob.prototype._mark = function (p) {
	  return common.mark(this, p)
	};

	Glob.prototype._makeAbs = function (f) {
	  return common.makeAbs(this, f)
	};

	Glob.prototype.abort = function () {
	  this.aborted = true;
	  this.emit('abort');
	};

	Glob.prototype.pause = function () {
	  if (!this.paused) {
	    this.paused = true;
	    this.emit('pause');
	  }
	};

	Glob.prototype.resume = function () {
	  if (this.paused) {
	    this.emit('resume');
	    this.paused = false;
	    if (this._emitQueue.length) {
	      var eq = this._emitQueue.slice(0);
	      this._emitQueue.length = 0;
	      for (var i = 0; i < eq.length; i ++) {
	        var e = eq[i];
	        this._emitMatch(e[0], e[1]);
	      }
	    }
	    if (this._processQueue.length) {
	      var pq = this._processQueue.slice(0);
	      this._processQueue.length = 0;
	      for (var i = 0; i < pq.length; i ++) {
	        var p = pq[i];
	        this._processing--;
	        this._process(p[0], p[1], p[2], p[3]);
	      }
	    }
	  }
	};

	Glob.prototype._process = function (pattern, index, inGlobStar, cb) {
	  assert(this instanceof Glob);
	  assert(typeof cb === 'function');

	  if (this.aborted)
	    return

	  this._processing++;
	  if (this.paused) {
	    this._processQueue.push([pattern, index, inGlobStar, cb]);
	    return
	  }

	  //console.error('PROCESS %d', this._processing, pattern)

	  // Get the first [n] parts of pattern that are all strings.
	  var n = 0;
	  while (typeof pattern[n] === 'string') {
	    n ++;
	  }
	  // now n is the index of the first one that is *not* a string.

	  // see if there's anything else
	  var prefix;
	  switch (n) {
	    // if not, then this is rather simple
	    case pattern.length:
	      this._processSimple(pattern.join('/'), index, cb);
	      return

	    case 0:
	      // pattern *starts* with some non-trivial item.
	      // going to readdir(cwd), but not include the prefix in matches.
	      prefix = null;
	      break

	    default:
	      // pattern has some string bits in the front.
	      // whatever it starts with, whether that's 'absolute' like /foo/bar,
	      // or 'relative' like '../baz'
	      prefix = pattern.slice(0, n).join('/');
	      break
	  }

	  var remain = pattern.slice(n);

	  // get the list of entries.
	  var read;
	  if (prefix === null)
	    read = '.';
	  else if (isAbsolute(prefix) ||
	      isAbsolute(pattern.map(function (p) {
	        return typeof p === 'string' ? p : '[*]'
	      }).join('/'))) {
	    if (!prefix || !isAbsolute(prefix))
	      prefix = '/' + prefix;
	    read = prefix;
	  } else
	    read = prefix;

	  var abs = this._makeAbs(read);

	  //if ignored, skip _processing
	  if (childrenIgnored(this, read))
	    return cb()

	  var isGlobStar = remain[0] === minimatch.GLOBSTAR;
	  if (isGlobStar)
	    this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb);
	  else
	    this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb);
	};

	Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) {
	  var self = this;
	  this._readdir(abs, inGlobStar, function (er, entries) {
	    return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
	  });
	};

	Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {

	  // if the abs isn't a dir, then nothing can match!
	  if (!entries)
	    return cb()

	  // It will only match dot entries if it starts with a dot, or if
	  // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
	  var pn = remain[0];
	  var negate = !!this.minimatch.negate;
	  var rawGlob = pn._glob;
	  var dotOk = this.dot || rawGlob.charAt(0) === '.';

	  var matchedEntries = [];
	  for (var i = 0; i < entries.length; i++) {
	    var e = entries[i];
	    if (e.charAt(0) !== '.' || dotOk) {
	      var m;
	      if (negate && !prefix) {
	        m = !e.match(pn);
	      } else {
	        m = e.match(pn);
	      }
	      if (m)
	        matchedEntries.push(e);
	    }
	  }

	  //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries)

	  var len = matchedEntries.length;
	  // If there are no matched entries, then nothing matches.
	  if (len === 0)
	    return cb()

	  // if this is the last remaining pattern bit, then no need for
	  // an additional stat *unless* the user has specified mark or
	  // stat explicitly.  We know they exist, since readdir returned
	  // them.

	  if (remain.length === 1 && !this.mark && !this.stat) {
	    if (!this.matches[index])
	      this.matches[index] = Object.create(null);

	    for (var i = 0; i < len; i ++) {
	      var e = matchedEntries[i];
	      if (prefix) {
	        if (prefix !== '/')
	          e = prefix + '/' + e;
	        else
	          e = prefix + e;
	      }

	      if (e.charAt(0) === '/' && !this.nomount) {
	        e = path.join(this.root, e);
	      }
	      this._emitMatch(index, e);
	    }
	    // This was the last one, and no stats were needed
	    return cb()
	  }

	  // now test all matched entries as stand-ins for that part
	  // of the pattern.
	  remain.shift();
	  for (var i = 0; i < len; i ++) {
	    var e = matchedEntries[i];
	    if (prefix) {
	      if (prefix !== '/')
	        e = prefix + '/' + e;
	      else
	        e = prefix + e;
	    }
	    this._process([e].concat(remain), index, inGlobStar, cb);
	  }
	  cb();
	};

	Glob.prototype._emitMatch = function (index, e) {
	  if (this.aborted)
	    return

	  if (isIgnored(this, e))
	    return

	  if (this.paused) {
	    this._emitQueue.push([index, e]);
	    return
	  }

	  var abs = isAbsolute(e) ? e : this._makeAbs(e);

	  if (this.mark)
	    e = this._mark(e);

	  if (this.absolute)
	    e = abs;

	  if (this.matches[index][e])
	    return

	  if (this.nodir) {
	    var c = this.cache[abs];
	    if (c === 'DIR' || Array.isArray(c))
	      return
	  }

	  this.matches[index][e] = true;

	  var st = this.statCache[abs];
	  if (st)
	    this.emit('stat', e, st);

	  this.emit('match', e);
	};

	Glob.prototype._readdirInGlobStar = function (abs, cb) {
	  if (this.aborted)
	    return

	  // follow all symlinked directories forever
	  // just proceed as if this is a non-globstar situation
	  if (this.follow)
	    return this._readdir(abs, false, cb)

	  var lstatkey = 'lstat\0' + abs;
	  var self = this;
	  var lstatcb = inflight(lstatkey, lstatcb_);

	  if (lstatcb)
	    self.fs.lstat(abs, lstatcb);

	  function lstatcb_ (er, lstat) {
	    if (er && er.code === 'ENOENT')
	      return cb()

	    var isSym = lstat && lstat.isSymbolicLink();
	    self.symlinks[abs] = isSym;

	    // If it's not a symlink or a dir, then it's definitely a regular file.
	    // don't bother doing a readdir in that case.
	    if (!isSym && lstat && !lstat.isDirectory()) {
	      self.cache[abs] = 'FILE';
	      cb();
	    } else
	      self._readdir(abs, false, cb);
	  }
	};

	Glob.prototype._readdir = function (abs, inGlobStar, cb) {
	  if (this.aborted)
	    return

	  cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb);
	  if (!cb)
	    return

	  //console.error('RD %j %j', +inGlobStar, abs)
	  if (inGlobStar && !ownProp(this.symlinks, abs))
	    return this._readdirInGlobStar(abs, cb)

	  if (ownProp(this.cache, abs)) {
	    var c = this.cache[abs];
	    if (!c || c === 'FILE')
	      return cb()

	    if (Array.isArray(c))
	      return cb(null, c)
	  }

	  var self = this;
	  self.fs.readdir(abs, readdirCb(this, abs, cb));
	};

	function readdirCb (self, abs, cb) {
	  return function (er, entries) {
	    if (er)
	      self._readdirError(abs, er, cb);
	    else
	      self._readdirEntries(abs, entries, cb);
	  }
	}

	Glob.prototype._readdirEntries = function (abs, entries, cb) {
	  if (this.aborted)
	    return

	  // if we haven't asked to stat everything, then just
	  // assume that everything in there exists, so we can avoid
	  // having to stat it a second time.
	  if (!this.mark && !this.stat) {
	    for (var i = 0; i < entries.length; i ++) {
	      var e = entries[i];
	      if (abs === '/')
	        e = abs + e;
	      else
	        e = abs + '/' + e;
	      this.cache[e] = true;
	    }
	  }

	  this.cache[abs] = entries;
	  return cb(null, entries)
	};

	Glob.prototype._readdirError = function (f, er, cb) {
	  if (this.aborted)
	    return

	  // handle errors, and cache the information
	  switch (er.code) {
	    case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
	    case 'ENOTDIR': // totally normal. means it *does* exist.
	      var abs = this._makeAbs(f);
	      this.cache[abs] = 'FILE';
	      if (abs === this.cwdAbs) {
	        var error = new Error(er.code + ' invalid cwd ' + this.cwd);
	        error.path = this.cwd;
	        error.code = er.code;
	        this.emit('error', error);
	        this.abort();
	      }
	      break

	    case 'ENOENT': // not terribly unusual
	    case 'ELOOP':
	    case 'ENAMETOOLONG':
	    case 'UNKNOWN':
	      this.cache[this._makeAbs(f)] = false;
	      break

	    default: // some unusual error.  Treat as failure.
	      this.cache[this._makeAbs(f)] = false;
	      if (this.strict) {
	        this.emit('error', er);
	        // If the error is handled, then we abort
	        // if not, we threw out of here
	        this.abort();
	      }
	      if (!this.silent)
	        console.error('glob error', er);
	      break
	  }

	  return cb()
	};

	Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) {
	  var self = this;
	  this._readdir(abs, inGlobStar, function (er, entries) {
	    self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb);
	  });
	};


	Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
	  //console.error('pgs2', prefix, remain[0], entries)

	  // no entries means not a dir, so it can never have matches
	  // foo.txt/** doesn't match foo.txt
	  if (!entries)
	    return cb()

	  // test without the globstar, and with every child both below
	  // and replacing the globstar.
	  var remainWithoutGlobStar = remain.slice(1);
	  var gspref = prefix ? [ prefix ] : [];
	  var noGlobStar = gspref.concat(remainWithoutGlobStar);

	  // the noGlobStar pattern exits the inGlobStar state
	  this._process(noGlobStar, index, false, cb);

	  var isSym = this.symlinks[abs];
	  var len = entries.length;

	  // If it's a symlink, and we're in a globstar, then stop
	  if (isSym && inGlobStar)
	    return cb()

	  for (var i = 0; i < len; i++) {
	    var e = entries[i];
	    if (e.charAt(0) === '.' && !this.dot)
	      continue

	    // these two cases enter the inGlobStar state
	    var instead = gspref.concat(entries[i], remainWithoutGlobStar);
	    this._process(instead, index, true, cb);

	    var below = gspref.concat(entries[i], remain);
	    this._process(below, index, true, cb);
	  }

	  cb();
	};

	Glob.prototype._processSimple = function (prefix, index, cb) {
	  // XXX review this.  Shouldn't it be doing the mounting etc
	  // before doing stat?  kinda weird?
	  var self = this;
	  this._stat(prefix, function (er, exists) {
	    self._processSimple2(prefix, index, er, exists, cb);
	  });
	};
	Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) {

	  //console.error('ps2', prefix, exists)

	  if (!this.matches[index])
	    this.matches[index] = Object.create(null);

	  // If it doesn't exist, then just mark the lack of results
	  if (!exists)
	    return cb()

	  if (prefix && isAbsolute(prefix) && !this.nomount) {
	    var trail = /[\/\\]$/.test(prefix);
	    if (prefix.charAt(0) === '/') {
	      prefix = path.join(this.root, prefix);
	    } else {
	      prefix = path.resolve(this.root, prefix);
	      if (trail)
	        prefix += '/';
	    }
	  }

	  if (process.platform === 'win32')
	    prefix = prefix.replace(/\\/g, '/');

	  // Mark this as a match
	  this._emitMatch(index, prefix);
	  cb();
	};

	// Returns either 'DIR', 'FILE', or false
	Glob.prototype._stat = function (f, cb) {
	  var abs = this._makeAbs(f);
	  var needDir = f.slice(-1) === '/';

	  if (f.length > this.maxLength)
	    return cb()

	  if (!this.stat && ownProp(this.cache, abs)) {
	    var c = this.cache[abs];

	    if (Array.isArray(c))
	      c = 'DIR';

	    // It exists, but maybe not how we need it
	    if (!needDir || c === 'DIR')
	      return cb(null, c)

	    if (needDir && c === 'FILE')
	      return cb()

	    // otherwise we have to stat, because maybe c=true
	    // if we know it exists, but not what it is.
	  }
	  var stat = this.statCache[abs];
	  if (stat !== undefined) {
	    if (stat === false)
	      return cb(null, stat)
	    else {
	      var type = stat.isDirectory() ? 'DIR' : 'FILE';
	      if (needDir && type === 'FILE')
	        return cb()
	      else
	        return cb(null, type, stat)
	    }
	  }

	  var self = this;
	  var statcb = inflight('stat\0' + abs, lstatcb_);
	  if (statcb)
	    self.fs.lstat(abs, statcb);

	  function lstatcb_ (er, lstat) {
	    if (lstat && lstat.isSymbolicLink()) {
	      // If it's a symlink, then treat it as the target, unless
	      // the target does not exist, then treat it as a file.
	      return self.fs.stat(abs, function (er, stat) {
	        if (er)
	          self._stat2(f, abs, null, lstat, cb);
	        else
	          self._stat2(f, abs, er, stat, cb);
	      })
	    } else {
	      self._stat2(f, abs, er, lstat, cb);
	    }
	  }
	};

	Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
	  if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
	    this.statCache[abs] = false;
	    return cb()
	  }

	  var needDir = f.slice(-1) === '/';
	  this.statCache[abs] = stat;

	  if (abs.slice(-1) === '/' && stat && !stat.isDirectory())
	    return cb(null, false, stat)

	  var c = true;
	  if (stat)
	    c = stat.isDirectory() ? 'DIR' : 'FILE';
	  this.cache[abs] = this.cache[abs] || c;

	  if (needDir && c === 'FILE')
	    return cb()

	  return cb(null, c, stat)
	};
	return glob_1;
}

/**
 * archiver-utils
 *
 * Copyright (c) 2012-2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-archiver/blob/master/LICENSE-MIT
 */

var hasRequiredFile;

function requireFile () {
	if (hasRequiredFile) return file.exports;
	hasRequiredFile = 1;
	var fs = requireGracefulFs();
	var path = require$$1;

	var flatten = requireFlatten();
	var difference = requireDifference();
	var union = requireUnion();
	var isPlainObject = requireIsPlainObject();

	var glob = requireGlob();

	var file$1 = file.exports = {};

	var pathSeparatorRe = /[\/\\]/g;

	// Process specified wildcard glob patterns or filenames against a
	// callback, excluding and uniquing files in the result set.
	var processPatterns = function(patterns, fn) {
	  // Filepaths to return.
	  var result = [];
	  // Iterate over flattened patterns array.
	  flatten(patterns).forEach(function(pattern) {
	    // If the first character is ! it should be omitted
	    var exclusion = pattern.indexOf('!') === 0;
	    // If the pattern is an exclusion, remove the !
	    if (exclusion) { pattern = pattern.slice(1); }
	    // Find all matching files for this pattern.
	    var matches = fn(pattern);
	    if (exclusion) {
	      // If an exclusion, remove matching files.
	      result = difference(result, matches);
	    } else {
	      // Otherwise add matching files.
	      result = union(result, matches);
	    }
	  });
	  return result;
	};

	// True if the file path exists.
	file$1.exists = function() {
	  var filepath = path.join.apply(path, arguments);
	  return fs.existsSync(filepath);
	};

	// Return an array of all file paths that match the given wildcard patterns.
	file$1.expand = function(...args) {
	  // If the first argument is an options object, save those options to pass
	  // into the File.prototype.glob.sync method.
	  var options = isPlainObject(args[0]) ? args.shift() : {};
	  // Use the first argument if it's an Array, otherwise convert the arguments
	  // object to an array and use that.
	  var patterns = Array.isArray(args[0]) ? args[0] : args;
	  // Return empty set if there are no patterns or filepaths.
	  if (patterns.length === 0) { return []; }
	  // Return all matching filepaths.
	  var matches = processPatterns(patterns, function(pattern) {
	    // Find all matching files for this pattern.
	    return glob.sync(pattern, options);
	  });
	  // Filter result set?
	  if (options.filter) {
	    matches = matches.filter(function(filepath) {
	      filepath = path.join(options.cwd || '', filepath);
	      try {
	        if (typeof options.filter === 'function') {
	          return options.filter(filepath);
	        } else {
	          // If the file is of the right type and exists, this should work.
	          return fs.statSync(filepath)[options.filter]();
	        }
	      } catch(e) {
	        // Otherwise, it's probably not the right type.
	        return false;
	      }
	    });
	  }
	  return matches;
	};

	// Build a multi task "files" object dynamically.
	file$1.expandMapping = function(patterns, destBase, options) {
	  options = Object.assign({
	    rename: function(destBase, destPath) {
	      return path.join(destBase || '', destPath);
	    }
	  }, options);
	  var files = [];
	  var fileByDest = {};
	  // Find all files matching pattern, using passed-in options.
	  file$1.expand(options, patterns).forEach(function(src) {
	    var destPath = src;
	    // Flatten?
	    if (options.flatten) {
	      destPath = path.basename(destPath);
	    }
	    // Change the extension?
	    if (options.ext) {
	      destPath = destPath.replace(/(\.[^\/]*)?$/, options.ext);
	    }
	    // Generate destination filename.
	    var dest = options.rename(destBase, destPath, options);
	    // Prepend cwd to src path if necessary.
	    if (options.cwd) { src = path.join(options.cwd, src); }
	    // Normalize filepaths to be unix-style.
	    dest = dest.replace(pathSeparatorRe, '/');
	    src = src.replace(pathSeparatorRe, '/');
	    // Map correct src path to dest path.
	    if (fileByDest[dest]) {
	      // If dest already exists, push this src onto that dest's src array.
	      fileByDest[dest].src.push(src);
	    } else {
	      // Otherwise create a new src-dest file mapping object.
	      files.push({
	        src: [src],
	        dest: dest,
	      });
	      // And store a reference for later use.
	      fileByDest[dest] = files[files.length - 1];
	    }
	  });
	  return files;
	};

	// reusing bits of grunt's multi-task source normalization
	file$1.normalizeFilesArray = function(data) {
	  var files = [];

	  data.forEach(function(obj) {
	    if ('src' in obj || 'dest' in obj) {
	      files.push(obj);
	    }
	  });

	  if (files.length === 0) {
	    return [];
	  }

	  files = _(files).chain().forEach(function(obj) {
	    if (!('src' in obj) || !obj.src) { return; }
	    // Normalize .src properties to flattened array.
	    if (Array.isArray(obj.src)) {
	      obj.src = flatten(obj.src);
	    } else {
	      obj.src = [obj.src];
	    }
	  }).map(function(obj) {
	    // Build options object, removing unwanted properties.
	    var expandOptions = Object.assign({}, obj);
	    delete expandOptions.src;
	    delete expandOptions.dest;

	    // Expand file mappings.
	    if (obj.expand) {
	      return file$1.expandMapping(obj.src, obj.dest, expandOptions).map(function(mapObj) {
	        // Copy obj properties to result.
	        var result = Object.assign({}, obj);
	        // Make a clone of the orig obj available.
	        result.orig = Object.assign({}, obj);
	        // Set .src and .dest, processing both as templates.
	        result.src = mapObj.src;
	        result.dest = mapObj.dest;
	        // Remove unwanted properties.
	        ['expand', 'cwd', 'flatten', 'rename', 'ext'].forEach(function(prop) {
	          delete result[prop];
	        });
	        return result;
	      });
	    }

	    // Copy obj properties to result, adding an .orig property.
	    var result = Object.assign({}, obj);
	    // Make a clone of the orig obj available.
	    result.orig = Object.assign({}, obj);

	    if ('src' in result) {
	      // Expose an expand-on-demand getter method as .src.
	      Object.defineProperty(result, 'src', {
	        enumerable: true,
	        get: function fn() {
	          var src;
	          if (!('result' in fn)) {
	            src = obj.src;
	            // If src is an array, flatten it. Otherwise, make it into an array.
	            src = Array.isArray(src) ? flatten(src) : [src];
	            // Expand src files, memoizing result.
	            fn.result = file$1.expand(expandOptions, src);
	          }
	          return fn.result;
	        }
	      });
	    }

	    if ('dest' in result) {
	      result.dest = obj.dest;
	    }

	    return result;
	  }).flatten().value();

	  return files;
	};
	return file.exports;
}

/**
 * archiver-utils
 *
 * Copyright (c) 2015 Chris Talkington.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/archiver-utils/blob/master/LICENSE
 */

var hasRequiredArchiverUtils;

function requireArchiverUtils () {
	if (hasRequiredArchiverUtils) return archiverUtils.exports;
	hasRequiredArchiverUtils = 1;
	var fs = requireGracefulFs();
	var path = require$$1;
	var lazystream = requireLazystream();
	var normalizePath = requireNormalizePath();
	var defaults = requireDefaults();

	var Stream = require$$0$4.Stream;
	var PassThrough = requireReadable().PassThrough;

	var utils = archiverUtils.exports = {};
	utils.file = requireFile();

	utils.collectStream = function(source, callback) {
	  var collection = [];
	  var size = 0;

	  source.on('error', callback);

	  source.on('data', function(chunk) {
	    collection.push(chunk);
	    size += chunk.length;
	  });

	  source.on('end', function() {
	    var buf = Buffer.alloc(size);
	    var offset = 0;

	    collection.forEach(function(data) {
	      data.copy(buf, offset);
	      offset += data.length;
	    });

	    callback(null, buf);
	  });
	};

	utils.dateify = function(dateish) {
	  dateish = dateish || new Date();

	  if (dateish instanceof Date) {
	    dateish = dateish;
	  } else if (typeof dateish === 'string') {
	    dateish = new Date(dateish);
	  } else {
	    dateish = new Date();
	  }

	  return dateish;
	};

	// this is slightly different from lodash version
	utils.defaults = function(object, source, guard) {
	  var args = arguments;
	  args[0] = args[0] || {};

	  return defaults(...args);
	};

	utils.isStream = function(source) {
	  return source instanceof Stream;
	};

	utils.lazyReadStream = function(filepath) {
	  return new lazystream.Readable(function() {
	    return fs.createReadStream(filepath);
	  });
	};

	utils.normalizeInputSource = function(source) {
	  if (source === null) {
	    return Buffer.alloc(0);
	  } else if (typeof source === 'string') {
	    return Buffer.from(source);
	  } else if (utils.isStream(source)) {
	    // Always pipe through a PassThrough stream to guarantee pausing the stream if it's already flowing,
	    // since it will only be processed in a (distant) future iteration of the event loop, and will lose
	    // data if already flowing now.
	    return source.pipe(new PassThrough());
	  }

	  return source;
	};

	utils.sanitizePath = function(filepath) {
	  return normalizePath(filepath, false).replace(/^\w+:/, '').replace(/^(\.\.\/|\/)+/, '');
	};

	utils.trailingSlashIt = function(str) {
	  return str.slice(-1) !== '/' ? str + '/' : str;
	};

	utils.unixifyPath = function(filepath) {
	  return normalizePath(filepath, false).replace(/^\w+:/, '');
	};

	utils.walkdir = function(dirpath, base, callback) {
	  var results = [];

	  if (typeof base === 'function') {
	    callback = base;
	    base = dirpath;
	  }

	  fs.readdir(dirpath, function(err, list) {
	    var i = 0;
	    var file;
	    var filepath;

	    if (err) {
	      return callback(err);
	    }

	    (function next() {
	      file = list[i++];

	      if (!file) {
	        return callback(null, results);
	      }

	      filepath = path.join(dirpath, file);

	      fs.stat(filepath, function(err, stats) {
	        results.push({
	          path: filepath,
	          relative: path.relative(base, filepath).replace(/\\/g, '/'),
	          stats: stats
	        });

	        if (stats && stats.isDirectory()) {
	          utils.walkdir(filepath, base, function(err, res) {
		    if(err){
		      return callback(err);
		    }

	            res.forEach(function(dirEntry) {
	              results.push(dirEntry);
	            });
			  
	            next();  
	          });
	        } else {
	          next();
	        }
	      });
	    })();
	  });
	};
	return archiverUtils.exports;
}

var error = {exports: {}};

/**
 * Archiver Core
 *
 * @ignore
 * @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
 * @copyright (c) 2012-2014 Chris Talkington, contributors.
 */

var hasRequiredError;

function requireError () {
	if (hasRequiredError) return error.exports;
	hasRequiredError = 1;
	(function (module, exports) {
		var util = require$$0$5;

		const ERROR_CODES = {
		  'ABORTED': 'archive was aborted',
		  'DIRECTORYDIRPATHREQUIRED': 'diretory dirpath argument must be a non-empty string value',
		  'DIRECTORYFUNCTIONINVALIDDATA': 'invalid data returned by directory custom data function',
		  'ENTRYNAMEREQUIRED': 'entry name must be a non-empty string value',
		  'FILEFILEPATHREQUIRED': 'file filepath argument must be a non-empty string value',
		  'FINALIZING': 'archive already finalizing',
		  'QUEUECLOSED': 'queue closed',
		  'NOENDMETHOD': 'no suitable finalize/end method defined by module',
		  'DIRECTORYNOTSUPPORTED': 'support for directory entries not defined by module',
		  'FORMATSET': 'archive format already set',
		  'INPUTSTEAMBUFFERREQUIRED': 'input source must be valid Stream or Buffer instance',
		  'MODULESET': 'module already set',
		  'SYMLINKNOTSUPPORTED': 'support for symlink entries not defined by module',
		  'SYMLINKFILEPATHREQUIRED': 'symlink filepath argument must be a non-empty string value',
		  'SYMLINKTARGETREQUIRED': 'symlink target argument must be a non-empty string value',
		  'ENTRYNOTSUPPORTED': 'entry not supported'
		};

		function ArchiverError(code, data) {
		  Error.captureStackTrace(this, this.constructor);
		  //this.name = this.constructor.name;
		  this.message = ERROR_CODES[code] || code;
		  this.code = code;
		  this.data = data;
		}

		util.inherits(ArchiverError, Error);

		module.exports = ArchiverError; 
	} (error));
	return error.exports;
}

/**
 * Archiver Core
 *
 * @ignore
 * @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
 * @copyright (c) 2012-2014 Chris Talkington, contributors.
 */

var core;
var hasRequiredCore;

function requireCore () {
	if (hasRequiredCore) return core;
	hasRequiredCore = 1;
	var fs = require$$0$2;
	var glob = requireReaddirGlob();
	var async = require$$2;
	var path = require$$1;
	var util = requireArchiverUtils();

	var inherits = require$$0$5.inherits;
	var ArchiverError = requireError();
	var Transform = requireReadable().Transform;

	var win32 = process.platform === 'win32';

	/**
	 * @constructor
	 * @param {String} format The archive format to use.
	 * @param {(CoreOptions|TransformOptions)} options See also {@link ZipOptions} and {@link TarOptions}.
	 */
	var Archiver = function(format, options) {
	  if (!(this instanceof Archiver)) {
	    return new Archiver(format, options);
	  }

	  if (typeof format !== 'string') {
	    options = format;
	    format = 'zip';
	  }

	  options = this.options = util.defaults(options, {
	    highWaterMark: 1024 * 1024,
	    statConcurrency: 4
	  });

	  Transform.call(this, options);

	  this._format = false;
	  this._module = false;
	  this._pending = 0;
	  this._pointer = 0;

	  this._entriesCount = 0;
	  this._entriesProcessedCount = 0;
	  this._fsEntriesTotalBytes = 0;
	  this._fsEntriesProcessedBytes = 0;

	  this._queue = async.queue(this._onQueueTask.bind(this), 1);
	  this._queue.drain(this._onQueueDrain.bind(this));

	  this._statQueue = async.queue(this._onStatQueueTask.bind(this), options.statConcurrency);
	  this._statQueue.drain(this._onQueueDrain.bind(this));

	  this._state = {
	    aborted: false,
	    finalize: false,
	    finalizing: false,
	    finalized: false,
	    modulePiped: false
	  };

	  this._streams = [];
	};

	inherits(Archiver, Transform);

	/**
	 * Internal logic for `abort`.
	 *
	 * @private
	 * @return void
	 */
	Archiver.prototype._abort = function() {
	  this._state.aborted = true;
	  this._queue.kill();
	  this._statQueue.kill();

	  if (this._queue.idle()) {
	    this._shutdown();
	  }
	};

	/**
	 * Internal helper for appending files.
	 *
	 * @private
	 * @param  {String} filepath The source filepath.
	 * @param  {EntryData} data The entry data.
	 * @return void
	 */
	Archiver.prototype._append = function(filepath, data) {
	  data = data || {};

	  var task = {
	    source: null,
	    filepath: filepath
	  };

	  if (!data.name) {
	    data.name = filepath;
	  }

	  data.sourcePath = filepath;
	  task.data = data;
	  this._entriesCount++;

	  if (data.stats && data.stats instanceof fs.Stats) {
	    task = this._updateQueueTaskWithStats(task, data.stats);
	    if (task) {
	      if (data.stats.size) {
	        this._fsEntriesTotalBytes += data.stats.size;
	      }

	      this._queue.push(task);
	    }
	  } else {
	    this._statQueue.push(task);
	  }
	};

	/**
	 * Internal logic for `finalize`.
	 *
	 * @private
	 * @return void
	 */
	Archiver.prototype._finalize = function() {
	  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
	    return;
	  }

	  this._state.finalizing = true;

	  this._moduleFinalize();

	  this._state.finalizing = false;
	  this._state.finalized = true;
	};

	/**
	 * Checks the various state variables to determine if we can `finalize`.
	 *
	 * @private
	 * @return {Boolean}
	 */
	Archiver.prototype._maybeFinalize = function() {
	  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
	    return false;
	  }

	  if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
	    this._finalize();
	    return true;
	  }

	  return false;
	};

	/**
	 * Appends an entry to the module.
	 *
	 * @private
	 * @fires  Archiver#entry
	 * @param  {(Buffer|Stream)} source
	 * @param  {EntryData} data
	 * @param  {Function} callback
	 * @return void
	 */
	Archiver.prototype._moduleAppend = function(source, data, callback) {
	  if (this._state.aborted) {
	    callback();
	    return;
	  }

	  this._module.append(source, data, function(err) {
	    this._task = null;

	    if (this._state.aborted) {
	      this._shutdown();
	      return;
	    }

	    if (err) {
	      this.emit('error', err);
	      setImmediate(callback);
	      return;
	    }

	    /**
	     * Fires when the entry's input has been processed and appended to the archive.
	     *
	     * @event Archiver#entry
	     * @type {EntryData}
	     */
	    this.emit('entry', data);
	    this._entriesProcessedCount++;

	    if (data.stats && data.stats.size) {
	      this._fsEntriesProcessedBytes += data.stats.size;
	    }

	    /**
	     * @event Archiver#progress
	     * @type {ProgressData}
	     */
	    this.emit('progress', {
	      entries: {
	        total: this._entriesCount,
	        processed: this._entriesProcessedCount
	      },
	      fs: {
	        totalBytes: this._fsEntriesTotalBytes,
	        processedBytes: this._fsEntriesProcessedBytes
	      }
	    });

	    setImmediate(callback);
	  }.bind(this));
	};

	/**
	 * Finalizes the module.
	 *
	 * @private
	 * @return void
	 */
	Archiver.prototype._moduleFinalize = function() {
	  if (typeof this._module.finalize === 'function') {
	    this._module.finalize();
	  } else if (typeof this._module.end === 'function') {
	    this._module.end();
	  } else {
	    this.emit('error', new ArchiverError('NOENDMETHOD'));
	  }
	};

	/**
	 * Pipes the module to our internal stream with error bubbling.
	 *
	 * @private
	 * @return void
	 */
	Archiver.prototype._modulePipe = function() {
	  this._module.on('error', this._onModuleError.bind(this));
	  this._module.pipe(this);
	  this._state.modulePiped = true;
	};

	/**
	 * Determines if the current module supports a defined feature.
	 *
	 * @private
	 * @param  {String} key
	 * @return {Boolean}
	 */
	Archiver.prototype._moduleSupports = function(key) {
	  if (!this._module.supports || !this._module.supports[key]) {
	    return false;
	  }

	  return this._module.supports[key];
	};

	/**
	 * Unpipes the module from our internal stream.
	 *
	 * @private
	 * @return void
	 */
	Archiver.prototype._moduleUnpipe = function() {
	  this._module.unpipe(this);
	  this._state.modulePiped = false;
	};

	/**
	 * Normalizes entry data with fallbacks for key properties.
	 *
	 * @private
	 * @param  {Object} data
	 * @param  {fs.Stats} stats
	 * @return {Object}
	 */
	Archiver.prototype._normalizeEntryData = function(data, stats) {
	  data = util.defaults(data, {
	    type: 'file',
	    name: null,
	    date: null,
	    mode: null,
	    prefix: null,
	    sourcePath: null,
	    stats: false
	  });

	  if (stats && data.stats === false) {
	    data.stats = stats;
	  }

	  var isDir = data.type === 'directory';

	  if (data.name) {
	    if (typeof data.prefix === 'string' && '' !== data.prefix) {
	      data.name = data.prefix + '/' + data.name;
	      data.prefix = null;
	    }

	    data.name = util.sanitizePath(data.name);

	    if (data.type !== 'symlink' && data.name.slice(-1) === '/') {
	      isDir = true;
	      data.type = 'directory';
	    } else if (isDir) {
	      data.name += '/';
	    }
	  }

	  // 511 === 0777; 493 === 0755; 438 === 0666; 420 === 0644
	  if (typeof data.mode === 'number') {
	    if (win32) {
	      data.mode &= 511;
	    } else {
	      data.mode &= 4095;
	    }
	  } else if (data.stats && data.mode === null) {
	    if (win32) {
	      data.mode = data.stats.mode & 511;
	    } else {
	      data.mode = data.stats.mode & 4095;
	    }

	    // stat isn't reliable on windows; force 0755 for dir
	    if (win32 && isDir) {
	      data.mode = 493;
	    }
	  } else if (data.mode === null) {
	    data.mode = isDir ? 493 : 420;
	  }

	  if (data.stats && data.date === null) {
	    data.date = data.stats.mtime;
	  } else {
	    data.date = util.dateify(data.date);
	  }

	  return data;
	};

	/**
	 * Error listener that re-emits error on to our internal stream.
	 *
	 * @private
	 * @param  {Error} err
	 * @return void
	 */
	Archiver.prototype._onModuleError = function(err) {
	  /**
	   * @event Archiver#error
	   * @type {ErrorData}
	   */
	  this.emit('error', err);
	};

	/**
	 * Checks the various state variables after queue has drained to determine if
	 * we need to `finalize`.
	 *
	 * @private
	 * @return void
	 */
	Archiver.prototype._onQueueDrain = function() {
	  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
	    return;
	  }

	  if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
	    this._finalize();
	  }
	};

	/**
	 * Appends each queue task to the module.
	 *
	 * @private
	 * @param  {Object} task
	 * @param  {Function} callback
	 * @return void
	 */
	Archiver.prototype._onQueueTask = function(task, callback) {
	  var fullCallback = () => {
	    if(task.data.callback) {
	      task.data.callback();
	    }
	    callback();
	  };

	  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
	    fullCallback();
	    return;
	  }

	  this._task = task;
	  this._moduleAppend(task.source, task.data, fullCallback);
	};

	/**
	 * Performs a file stat and reinjects the task back into the queue.
	 *
	 * @private
	 * @param  {Object} task
	 * @param  {Function} callback
	 * @return void
	 */
	Archiver.prototype._onStatQueueTask = function(task, callback) {
	  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
	    callback();
	    return;
	  }

	  fs.lstat(task.filepath, function(err, stats) {
	    if (this._state.aborted) {
	      setImmediate(callback);
	      return;
	    }

	    if (err) {
	      this._entriesCount--;

	      /**
	       * @event Archiver#warning
	       * @type {ErrorData}
	       */
	      this.emit('warning', err);
	      setImmediate(callback);
	      return;
	    }

	    task = this._updateQueueTaskWithStats(task, stats);

	    if (task) {
	      if (stats.size) {
	        this._fsEntriesTotalBytes += stats.size;
	      }

	      this._queue.push(task);
	    }

	    setImmediate(callback);
	  }.bind(this));
	};

	/**
	 * Unpipes the module and ends our internal stream.
	 *
	 * @private
	 * @return void
	 */
	Archiver.prototype._shutdown = function() {
	  this._moduleUnpipe();
	  this.end();
	};

	/**
	 * Tracks the bytes emitted by our internal stream.
	 *
	 * @private
	 * @param  {Buffer} chunk
	 * @param  {String} encoding
	 * @param  {Function} callback
	 * @return void
	 */
	Archiver.prototype._transform = function(chunk, encoding, callback) {
	  if (chunk) {
	    this._pointer += chunk.length;
	  }

	  callback(null, chunk);
	};

	/**
	 * Updates and normalizes a queue task using stats data.
	 *
	 * @private
	 * @param  {Object} task
	 * @param  {fs.Stats} stats
	 * @return {Object}
	 */
	Archiver.prototype._updateQueueTaskWithStats = function(task, stats) {
	  if (stats.isFile()) {
	    task.data.type = 'file';
	    task.data.sourceType = 'stream';
	    task.source = util.lazyReadStream(task.filepath);
	  } else if (stats.isDirectory() && this._moduleSupports('directory')) {
	    task.data.name = util.trailingSlashIt(task.data.name);
	    task.data.type = 'directory';
	    task.data.sourcePath = util.trailingSlashIt(task.filepath);
	    task.data.sourceType = 'buffer';
	    task.source = Buffer.concat([]);
	  } else if (stats.isSymbolicLink() && this._moduleSupports('symlink')) {
	    var linkPath = fs.readlinkSync(task.filepath);
	    var dirName = path.dirname(task.filepath);
	    task.data.type = 'symlink';
	    task.data.linkname = path.relative(dirName, path.resolve(dirName, linkPath));
	    task.data.sourceType = 'buffer';
	    task.source = Buffer.concat([]);
	  } else {
	    if (stats.isDirectory()) {
	      this.emit('warning', new ArchiverError('DIRECTORYNOTSUPPORTED', task.data));
	    } else if (stats.isSymbolicLink()) {
	      this.emit('warning', new ArchiverError('SYMLINKNOTSUPPORTED', task.data));
	    } else {
	      this.emit('warning', new ArchiverError('ENTRYNOTSUPPORTED', task.data));
	    }

	    return null;
	  }

	  task.data = this._normalizeEntryData(task.data, stats);

	  return task;
	};

	/**
	 * Aborts the archiving process, taking a best-effort approach, by:
	 *
	 * - removing any pending queue tasks
	 * - allowing any active queue workers to finish
	 * - detaching internal module pipes
	 * - ending both sides of the Transform stream
	 *
	 * It will NOT drain any remaining sources.
	 *
	 * @return {this}
	 */
	Archiver.prototype.abort = function() {
	  if (this._state.aborted || this._state.finalized) {
	    return this;
	  }

	  this._abort();

	  return this;
	};

	/**
	 * Appends an input source (text string, buffer, or stream) to the instance.
	 *
	 * When the instance has received, processed, and emitted the input, the `entry`
	 * event is fired.
	 *
	 * @fires  Archiver#entry
	 * @param  {(Buffer|Stream|String)} source The input source.
	 * @param  {EntryData} data See also {@link ZipEntryData} and {@link TarEntryData}.
	 * @return {this}
	 */
	Archiver.prototype.append = function(source, data) {
	  if (this._state.finalize || this._state.aborted) {
	    this.emit('error', new ArchiverError('QUEUECLOSED'));
	    return this;
	  }

	  data = this._normalizeEntryData(data);

	  if (typeof data.name !== 'string' || data.name.length === 0) {
	    this.emit('error', new ArchiverError('ENTRYNAMEREQUIRED'));
	    return this;
	  }

	  if (data.type === 'directory' && !this._moduleSupports('directory')) {
	    this.emit('error', new ArchiverError('DIRECTORYNOTSUPPORTED', { name: data.name }));
	    return this;
	  }

	  source = util.normalizeInputSource(source);

	  if (Buffer.isBuffer(source)) {
	    data.sourceType = 'buffer';
	  } else if (util.isStream(source)) {
	    data.sourceType = 'stream';
	  } else {
	    this.emit('error', new ArchiverError('INPUTSTEAMBUFFERREQUIRED', { name: data.name }));
	    return this;
	  }

	  this._entriesCount++;
	  this._queue.push({
	    data: data,
	    source: source
	  });

	  return this;
	};

	/**
	 * Appends a directory and its files, recursively, given its dirpath.
	 *
	 * @param  {String} dirpath The source directory path.
	 * @param  {String} destpath The destination path within the archive.
	 * @param  {(EntryData|Function)} data See also [ZipEntryData]{@link ZipEntryData} and
	 * [TarEntryData]{@link TarEntryData}.
	 * @return {this}
	 */
	Archiver.prototype.directory = function(dirpath, destpath, data) {
	  if (this._state.finalize || this._state.aborted) {
	    this.emit('error', new ArchiverError('QUEUECLOSED'));
	    return this;
	  }

	  if (typeof dirpath !== 'string' || dirpath.length === 0) {
	    this.emit('error', new ArchiverError('DIRECTORYDIRPATHREQUIRED'));
	    return this;
	  }

	  this._pending++;

	  if (destpath === false) {
	    destpath = '';
	  } else if (typeof destpath !== 'string'){
	    destpath = dirpath;
	  }

	  var dataFunction = false;
	  if (typeof data === 'function') {
	    dataFunction = data;
	    data = {};
	  } else if (typeof data !== 'object') {
	    data = {};
	  }

	  var globOptions = {
	    stat: true,
	    dot: true
	  };

	  function onGlobEnd() {
	    this._pending--;
	    this._maybeFinalize();
	  }

	  function onGlobError(err) {
	    this.emit('error', err);
	  }

	  function onGlobMatch(match){
	    globber.pause();

	    var ignoreMatch = false;
	    var entryData = Object.assign({}, data);
	    entryData.name = match.relative;
	    entryData.prefix = destpath;
	    entryData.stats = match.stat;
	    entryData.callback = globber.resume.bind(globber);

	    try {
	      if (dataFunction) {
	        entryData = dataFunction(entryData);

	        if (entryData === false) {
	          ignoreMatch = true;
	        } else if (typeof entryData !== 'object') {
	          throw new ArchiverError('DIRECTORYFUNCTIONINVALIDDATA', { dirpath: dirpath });
	        }
	      }
	    } catch(e) {
	      this.emit('error', e);
	      return;
	    }

	    if (ignoreMatch) {
	      globber.resume();
	      return;
	    }

	    this._append(match.absolute, entryData);
	  }

	  var globber = glob(dirpath, globOptions);
	  globber.on('error', onGlobError.bind(this));
	  globber.on('match', onGlobMatch.bind(this));
	  globber.on('end', onGlobEnd.bind(this));

	  return this;
	};

	/**
	 * Appends a file given its filepath using a
	 * [lazystream]{@link https://github.com/jpommerening/node-lazystream} wrapper to
	 * prevent issues with open file limits.
	 *
	 * When the instance has received, processed, and emitted the file, the `entry`
	 * event is fired.
	 *
	 * @param  {String} filepath The source filepath.
	 * @param  {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
	 * [TarEntryData]{@link TarEntryData}.
	 * @return {this}
	 */
	Archiver.prototype.file = function(filepath, data) {
	  if (this._state.finalize || this._state.aborted) {
	    this.emit('error', new ArchiverError('QUEUECLOSED'));
	    return this;
	  }

	  if (typeof filepath !== 'string' || filepath.length === 0) {
	    this.emit('error', new ArchiverError('FILEFILEPATHREQUIRED'));
	    return this;
	  }

	  this._append(filepath, data);

	  return this;
	};

	/**
	 * Appends multiple files that match a glob pattern.
	 *
	 * @param  {String} pattern The [glob pattern]{@link https://github.com/isaacs/minimatch} to match.
	 * @param  {Object} options See [node-readdir-glob]{@link https://github.com/yqnn/node-readdir-glob#options}.
	 * @param  {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
	 * [TarEntryData]{@link TarEntryData}.
	 * @return {this}
	 */
	Archiver.prototype.glob = function(pattern, options, data) {
	  this._pending++;

	  options = util.defaults(options, {
	    stat: true,
	    pattern: pattern
	  });

	  function onGlobEnd() {
	    this._pending--;
	    this._maybeFinalize();
	  }

	  function onGlobError(err) {
	    this.emit('error', err);
	  }

	  function onGlobMatch(match){
	    globber.pause();
	    var entryData = Object.assign({}, data);
	    entryData.callback = globber.resume.bind(globber);
	    entryData.stats = match.stat;
	    entryData.name = match.relative;

	    this._append(match.absolute, entryData);
	  }

	  var globber = glob(options.cwd || '.', options);
	  globber.on('error', onGlobError.bind(this));
	  globber.on('match', onGlobMatch.bind(this));
	  globber.on('end', onGlobEnd.bind(this));

	  return this;
	};

	/**
	 * Finalizes the instance and prevents further appending to the archive
	 * structure (queue will continue til drained).
	 *
	 * The `end`, `close` or `finish` events on the destination stream may fire
	 * right after calling this method so you should set listeners beforehand to
	 * properly detect stream completion.
	 *
	 * @return {Promise}
	 */
	Archiver.prototype.finalize = function() {
	  if (this._state.aborted) {
	    var abortedError = new ArchiverError('ABORTED');
	    this.emit('error', abortedError);
	    return Promise.reject(abortedError);
	  }

	  if (this._state.finalize) {
	    var finalizingError = new ArchiverError('FINALIZING');
	    this.emit('error', finalizingError);
	    return Promise.reject(finalizingError);
	  }

	  this._state.finalize = true;

	  if (this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
	    this._finalize();
	  }

	  var self = this;

	  return new Promise(function(resolve, reject) {
	    var errored;

	    self._module.on('end', function() {
	      if (!errored) {
	        resolve();
	      }
	    });

	    self._module.on('error', function(err) {
	      errored = true;
	      reject(err);
	    });
	  })
	};

	/**
	 * Sets the module format name used for archiving.
	 *
	 * @param {String} format The name of the format.
	 * @return {this}
	 */
	Archiver.prototype.setFormat = function(format) {
	  if (this._format) {
	    this.emit('error', new ArchiverError('FORMATSET'));
	    return this;
	  }

	  this._format = format;

	  return this;
	};

	/**
	 * Sets the module used for archiving.
	 *
	 * @param {Function} module The function for archiver to interact with.
	 * @return {this}
	 */
	Archiver.prototype.setModule = function(module) {
	  if (this._state.aborted) {
	    this.emit('error', new ArchiverError('ABORTED'));
	    return this;
	  }

	  if (this._state.module) {
	    this.emit('error', new ArchiverError('MODULESET'));
	    return this;
	  }

	  this._module = module;
	  this._modulePipe();

	  return this;
	};

	/**
	 * Appends a symlink to the instance.
	 *
	 * This does NOT interact with filesystem and is used for programmatically creating symlinks.
	 *
	 * @param  {String} filepath The symlink path (within archive).
	 * @param  {String} target The target path (within archive).
	 * @param  {Number} mode Sets the entry permissions.
	 * @return {this}
	 */
	Archiver.prototype.symlink = function(filepath, target, mode) {
	  if (this._state.finalize || this._state.aborted) {
	    this.emit('error', new ArchiverError('QUEUECLOSED'));
	    return this;
	  }

	  if (typeof filepath !== 'string' || filepath.length === 0) {
	    this.emit('error', new ArchiverError('SYMLINKFILEPATHREQUIRED'));
	    return this;
	  }

	  if (typeof target !== 'string' || target.length === 0) {
	    this.emit('error', new ArchiverError('SYMLINKTARGETREQUIRED', { filepath: filepath }));
	    return this;
	  }

	  if (!this._moduleSupports('symlink')) {
	    this.emit('error', new ArchiverError('SYMLINKNOTSUPPORTED', { filepath: filepath }));
	    return this;
	  }

	  var data = {};
	  data.type = 'symlink';
	  data.name = filepath.replace(/\\/g, '/');
	  data.linkname = target.replace(/\\/g, '/');
	  data.sourceType = 'buffer';

	  if (typeof mode === "number") {
	    data.mode = mode;
	  }

	  this._entriesCount++;
	  this._queue.push({
	    data: data,
	    source: Buffer.concat([])
	  });

	  return this;
	};

	/**
	 * Returns the current length (in bytes) that has been emitted.
	 *
	 * @return {Number}
	 */
	Archiver.prototype.pointer = function() {
	  return this._pointer;
	};

	/**
	 * Middleware-like helper that has yet to be fully implemented.
	 *
	 * @private
	 * @param  {Function} plugin
	 * @return {this}
	 */
	Archiver.prototype.use = function(plugin) {
	  this._streams.push(plugin);
	  return this;
	};

	core = Archiver;

	/**
	 * @typedef {Object} CoreOptions
	 * @global
	 * @property {Number} [statConcurrency=4] Sets the number of workers used to
	 * process the internal fs stat queue.
	 */

	/**
	 * @typedef {Object} TransformOptions
	 * @property {Boolean} [allowHalfOpen=true] If set to false, then the stream
	 * will automatically end the readable side when the writable side ends and vice
	 * versa.
	 * @property {Boolean} [readableObjectMode=false] Sets objectMode for readable
	 * side of the stream. Has no effect if objectMode is true.
	 * @property {Boolean} [writableObjectMode=false] Sets objectMode for writable
	 * side of the stream. Has no effect if objectMode is true.
	 * @property {Boolean} [decodeStrings=true] Whether or not to decode strings
	 * into Buffers before passing them to _write(). `Writable`
	 * @property {String} [encoding=NULL] If specified, then buffers will be decoded
	 * to strings using the specified encoding. `Readable`
	 * @property {Number} [highWaterMark=16kb] The maximum number of bytes to store
	 * in the internal buffer before ceasing to read from the underlying resource.
	 * `Readable` `Writable`
	 * @property {Boolean} [objectMode=false] Whether this stream should behave as a
	 * stream of objects. Meaning that stream.read(n) returns a single value instead
	 * of a Buffer of size n. `Readable` `Writable`
	 */

	/**
	 * @typedef {Object} EntryData
	 * @property {String} name Sets the entry name including internal path.
	 * @property {(String|Date)} [date=NOW()] Sets the entry date.
	 * @property {Number} [mode=D:0755/F:0644] Sets the entry permissions.
	 * @property {String} [prefix] Sets a path prefix for the entry name. Useful
	 * when working with methods like `directory` or `glob`.
	 * @property {fs.Stats} [stats] Sets the fs stat data for this entry allowing
	 * for reduction of fs stat calls when stat data is already known.
	 */

	/**
	 * @typedef {Object} ErrorData
	 * @property {String} message The message of the error.
	 * @property {String} code The error code assigned to this error.
	 * @property {String} data Additional data provided for reporting or debugging (where available).
	 */

	/**
	 * @typedef {Object} ProgressData
	 * @property {Object} entries
	 * @property {Number} entries.total Number of entries that have been appended.
	 * @property {Number} entries.processed Number of entries that have been processed.
	 * @property {Object} fs
	 * @property {Number} fs.totalBytes Number of bytes that have been appended. Calculated asynchronously and might not be accurate: it growth while entries are added. (based on fs.Stats)
	 * @property {Number} fs.processedBytes Number of bytes that have been processed. (based on fs.Stats)
	 */
	return core;
}

var zipStream = {exports: {}};

var archiveEntry = {exports: {}};

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var hasRequiredArchiveEntry;

function requireArchiveEntry () {
	if (hasRequiredArchiveEntry) return archiveEntry.exports;
	hasRequiredArchiveEntry = 1;
	var ArchiveEntry = archiveEntry.exports = function() {};

	ArchiveEntry.prototype.getName = function() {};

	ArchiveEntry.prototype.getSize = function() {};

	ArchiveEntry.prototype.getLastModifiedDate = function() {};

	ArchiveEntry.prototype.isDirectory = function() {};
	return archiveEntry.exports;
}

var zipArchiveEntry = {exports: {}};

var generalPurposeBit = {exports: {}};

var util$1 = {exports: {}};

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var hasRequiredUtil$1;

function requireUtil$1 () {
	if (hasRequiredUtil$1) return util$1.exports;
	hasRequiredUtil$1 = 1;
	var util = util$1.exports = {};

	util.dateToDos = function(d, forceLocalTime) {
	  forceLocalTime = forceLocalTime || false;

	  var year = forceLocalTime ? d.getFullYear() : d.getUTCFullYear();

	  if (year < 1980) {
	    return 2162688; // 1980-1-1 00:00:00
	  } else if (year >= 2044) {
	    return 2141175677; // 2043-12-31 23:59:58
	  }

	  var val = {
	    year: year,
	    month: forceLocalTime ? d.getMonth() : d.getUTCMonth(),
	    date: forceLocalTime ? d.getDate() : d.getUTCDate(),
	    hours: forceLocalTime ? d.getHours() : d.getUTCHours(),
	    minutes: forceLocalTime ? d.getMinutes() : d.getUTCMinutes(),
	    seconds: forceLocalTime ? d.getSeconds() : d.getUTCSeconds()
	  };

	  return ((val.year - 1980) << 25) | ((val.month + 1) << 21) | (val.date << 16) |
	    (val.hours << 11) | (val.minutes << 5) | (val.seconds / 2);
	};

	util.dosToDate = function(dos) {
	  return new Date(((dos >> 25) & 0x7f) + 1980, ((dos >> 21) & 0x0f) - 1, (dos >> 16) & 0x1f, (dos >> 11) & 0x1f, (dos >> 5) & 0x3f, (dos & 0x1f) << 1);
	};

	util.fromDosTime = function(buf) {
	  return util.dosToDate(buf.readUInt32LE(0));
	};

	util.getEightBytes = function(v) {
	  var buf = Buffer.alloc(8);
	  buf.writeUInt32LE(v % 0x0100000000, 0);
	  buf.writeUInt32LE((v / 0x0100000000) | 0, 4);

	  return buf;
	};

	util.getShortBytes = function(v) {
	  var buf = Buffer.alloc(2);
	  buf.writeUInt16LE((v & 0xFFFF) >>> 0, 0);

	  return buf;
	};

	util.getShortBytesValue = function(buf, offset) {
	  return buf.readUInt16LE(offset);
	};

	util.getLongBytes = function(v) {
	  var buf = Buffer.alloc(4);
	  buf.writeUInt32LE((v & 0xFFFFFFFF) >>> 0, 0);

	  return buf;
	};

	util.getLongBytesValue = function(buf, offset) {
	  return buf.readUInt32LE(offset);
	};

	util.toDosTime = function(d) {
	  return util.getLongBytes(util.dateToDos(d));
	};
	return util$1.exports;
}

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var hasRequiredGeneralPurposeBit;

function requireGeneralPurposeBit () {
	if (hasRequiredGeneralPurposeBit) return generalPurposeBit.exports;
	hasRequiredGeneralPurposeBit = 1;
	var zipUtil = requireUtil$1();

	var DATA_DESCRIPTOR_FLAG = 1 << 3;
	var ENCRYPTION_FLAG = 1 << 0;
	var NUMBER_OF_SHANNON_FANO_TREES_FLAG = 1 << 2;
	var SLIDING_DICTIONARY_SIZE_FLAG = 1 << 1;
	var STRONG_ENCRYPTION_FLAG = 1 << 6;
	var UFT8_NAMES_FLAG = 1 << 11;

	var GeneralPurposeBit = generalPurposeBit.exports = function() {
	  if (!(this instanceof GeneralPurposeBit)) {
	    return new GeneralPurposeBit();
	  }

	  this.descriptor = false;
	  this.encryption = false;
	  this.utf8 = false;
	  this.numberOfShannonFanoTrees = 0;
	  this.strongEncryption = false;
	  this.slidingDictionarySize = 0;

	  return this;
	};

	GeneralPurposeBit.prototype.encode = function() {
	  return zipUtil.getShortBytes(
	    (this.descriptor ? DATA_DESCRIPTOR_FLAG : 0) |
	    (this.utf8 ? UFT8_NAMES_FLAG : 0) |
	    (this.encryption ? ENCRYPTION_FLAG : 0) |
	    (this.strongEncryption ? STRONG_ENCRYPTION_FLAG : 0)
	  );
	};

	GeneralPurposeBit.prototype.parse = function(buf, offset) {
	  var flag = zipUtil.getShortBytesValue(buf, offset);
	  var gbp = new GeneralPurposeBit();

	  gbp.useDataDescriptor((flag & DATA_DESCRIPTOR_FLAG) !== 0);
	  gbp.useUTF8ForNames((flag & UFT8_NAMES_FLAG) !== 0);
	  gbp.useStrongEncryption((flag & STRONG_ENCRYPTION_FLAG) !== 0);
	  gbp.useEncryption((flag & ENCRYPTION_FLAG) !== 0);
	  gbp.setSlidingDictionarySize((flag & SLIDING_DICTIONARY_SIZE_FLAG) !== 0 ? 8192 : 4096);
	  gbp.setNumberOfShannonFanoTrees((flag & NUMBER_OF_SHANNON_FANO_TREES_FLAG) !== 0 ? 3 : 2);

	  return gbp;
	};

	GeneralPurposeBit.prototype.setNumberOfShannonFanoTrees = function(n) {
	  this.numberOfShannonFanoTrees = n;
	};

	GeneralPurposeBit.prototype.getNumberOfShannonFanoTrees = function() {
	  return this.numberOfShannonFanoTrees;
	};

	GeneralPurposeBit.prototype.setSlidingDictionarySize = function(n) {
	  this.slidingDictionarySize = n;
	};

	GeneralPurposeBit.prototype.getSlidingDictionarySize = function() {
	  return this.slidingDictionarySize;
	};

	GeneralPurposeBit.prototype.useDataDescriptor = function(b) {
	  this.descriptor = b;
	};

	GeneralPurposeBit.prototype.usesDataDescriptor = function() {
	  return this.descriptor;
	};

	GeneralPurposeBit.prototype.useEncryption = function(b) {
	  this.encryption = b;
	};

	GeneralPurposeBit.prototype.usesEncryption = function() {
	  return this.encryption;
	};

	GeneralPurposeBit.prototype.useStrongEncryption = function(b) {
	  this.strongEncryption = b;
	};

	GeneralPurposeBit.prototype.usesStrongEncryption = function() {
	  return this.strongEncryption;
	};

	GeneralPurposeBit.prototype.useUTF8ForNames = function(b) {
	  this.utf8 = b;
	};

	GeneralPurposeBit.prototype.usesUTF8ForNames = function() {
	  return this.utf8;
	};
	return generalPurposeBit.exports;
}

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var unixStat;
var hasRequiredUnixStat;

function requireUnixStat () {
	if (hasRequiredUnixStat) return unixStat;
	hasRequiredUnixStat = 1;
	unixStat = {
	    /**
	     * Bits used for permissions (and sticky bit)
	     */
	    PERM_MASK: 4095, // 07777

	    /**
	     * Bits used to indicate the filesystem object type.
	     */
	    FILE_TYPE_FLAG: 61440, // 0170000

	    /**
	     * Indicates symbolic links.
	     */
	    LINK_FLAG: 40960, // 0120000

	    /**
	     * Indicates plain files.
	     */
	    FILE_FLAG: 32768, // 0100000

	    /**
	     * Indicates directories.
	     */
	    DIR_FLAG: 16384, // 040000

	    // ----------------------------------------------------------
	    // somewhat arbitrary choices that are quite common for shared
	    // installations
	    // -----------------------------------------------------------

	    /**
	     * Default permissions for symbolic links.
	     */
	    DEFAULT_LINK_PERM: 511, // 0777

	    /**
	     * Default permissions for directories.
	     */
	    DEFAULT_DIR_PERM: 493, // 0755

	    /**
	     * Default permissions for plain files.
	     */
	    DEFAULT_FILE_PERM: 420 // 0644
	};
	return unixStat;
}

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var constants$5;
var hasRequiredConstants$5;

function requireConstants$5 () {
	if (hasRequiredConstants$5) return constants$5;
	hasRequiredConstants$5 = 1;
	constants$5 = {
	  WORD: 4,
	  DWORD: 8,
	  EMPTY: Buffer.alloc(0),

	  SHORT: 2,
	  SHORT_MASK: 0xffff,
	  SHORT_SHIFT: 16,
	  SHORT_ZERO: Buffer.from(Array(2)),
	  LONG: 4,
	  LONG_ZERO: Buffer.from(Array(4)),

	  MIN_VERSION_INITIAL: 10,
	  MIN_VERSION_DATA_DESCRIPTOR: 20,
	  MIN_VERSION_ZIP64: 45,
	  VERSION_MADEBY: 45,

	  METHOD_STORED: 0,
	  METHOD_DEFLATED: 8,

	  PLATFORM_UNIX: 3,
	  PLATFORM_FAT: 0,

	  SIG_LFH: 0x04034b50,
	  SIG_DD: 0x08074b50,
	  SIG_CFH: 0x02014b50,
	  SIG_EOCD: 0x06054b50,
	  SIG_ZIP64_EOCD: 0x06064B50,
	  SIG_ZIP64_EOCD_LOC: 0x07064B50,

	  ZIP64_MAGIC_SHORT: 0xffff,
	  ZIP64_MAGIC: 0xffffffff,
	  ZIP64_EXTRA_ID: 0x0001,

	  ZLIB_NO_COMPRESSION: 0,
	  ZLIB_BEST_SPEED: 1,
	  ZLIB_BEST_COMPRESSION: 9,
	  ZLIB_DEFAULT_COMPRESSION: -1,

	  MODE_MASK: 0xFFF,
	  DEFAULT_FILE_MODE: 33188, // 010644 = -rw-r--r-- = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
	  DEFAULT_DIR_MODE: 16877,  // 040755 = drwxr-xr-x = S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH

	  EXT_FILE_ATTR_DIR: 1106051088,  // 010173200020 = drwxr-xr-x = (((S_IFDIR | 0755) << 16) | S_DOS_D)
	  EXT_FILE_ATTR_FILE: 2175008800, // 020151000040 = -rw-r--r-- = (((S_IFREG | 0644) << 16) | S_DOS_A) >>> 0

	  // Unix file types
	  S_IFMT: 61440,   // 0170000 type of file mask
	  S_IFIFO: 4096,   // 010000 named pipe (fifo)
	  S_IFCHR: 8192,   // 020000 character special
	  S_IFDIR: 16384,  // 040000 directory
	  S_IFBLK: 24576,  // 060000 block special
	  S_IFREG: 32768,  // 0100000 regular
	  S_IFLNK: 40960,  // 0120000 symbolic link
	  S_IFSOCK: 49152, // 0140000 socket

	  // DOS file type flags
	  S_DOS_A: 32, // 040 Archive
	  S_DOS_D: 16, // 020 Directory
	  S_DOS_V: 8,  // 010 Volume
	  S_DOS_S: 4,  // 04 System
	  S_DOS_H: 2,  // 02 Hidden
	  S_DOS_R: 1   // 01 Read Only
	};
	return constants$5;
}

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var hasRequiredZipArchiveEntry;

function requireZipArchiveEntry () {
	if (hasRequiredZipArchiveEntry) return zipArchiveEntry.exports;
	hasRequiredZipArchiveEntry = 1;
	var inherits = require$$0$5.inherits;
	var normalizePath = requireNormalizePath();

	var ArchiveEntry = requireArchiveEntry();
	var GeneralPurposeBit = requireGeneralPurposeBit();
	var UnixStat = requireUnixStat();

	var constants = requireConstants$5();
	var zipUtil = requireUtil$1();

	var ZipArchiveEntry = zipArchiveEntry.exports = function(name) {
	  if (!(this instanceof ZipArchiveEntry)) {
	    return new ZipArchiveEntry(name);
	  }

	  ArchiveEntry.call(this);

	  this.platform = constants.PLATFORM_FAT;
	  this.method = -1;

	  this.name = null;
	  this.size = 0;
	  this.csize = 0;
	  this.gpb = new GeneralPurposeBit();
	  this.crc = 0;
	  this.time = -1;

	  this.minver = constants.MIN_VERSION_INITIAL;
	  this.mode = -1;
	  this.extra = null;
	  this.exattr = 0;
	  this.inattr = 0;
	  this.comment = null;

	  if (name) {
	    this.setName(name);
	  }
	};

	inherits(ZipArchiveEntry, ArchiveEntry);

	/**
	 * Returns the extra fields related to the entry.
	 *
	 * @returns {Buffer}
	 */
	ZipArchiveEntry.prototype.getCentralDirectoryExtra = function() {
	  return this.getExtra();
	};

	/**
	 * Returns the comment set for the entry.
	 *
	 * @returns {string}
	 */
	ZipArchiveEntry.prototype.getComment = function() {
	  return this.comment !== null ? this.comment : '';
	};

	/**
	 * Returns the compressed size of the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getCompressedSize = function() {
	  return this.csize;
	};

	/**
	 * Returns the CRC32 digest for the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getCrc = function() {
	  return this.crc;
	};

	/**
	 * Returns the external file attributes for the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getExternalAttributes = function() {
	  return this.exattr;
	};

	/**
	 * Returns the extra fields related to the entry.
	 *
	 * @returns {Buffer}
	 */
	ZipArchiveEntry.prototype.getExtra = function() {
	  return this.extra !== null ? this.extra : constants.EMPTY;
	};

	/**
	 * Returns the general purpose bits related to the entry.
	 *
	 * @returns {GeneralPurposeBit}
	 */
	ZipArchiveEntry.prototype.getGeneralPurposeBit = function() {
	  return this.gpb;
	};

	/**
	 * Returns the internal file attributes for the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getInternalAttributes = function() {
	  return this.inattr;
	};

	/**
	 * Returns the last modified date of the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getLastModifiedDate = function() {
	  return this.getTime();
	};

	/**
	 * Returns the extra fields related to the entry.
	 *
	 * @returns {Buffer}
	 */
	ZipArchiveEntry.prototype.getLocalFileDataExtra = function() {
	  return this.getExtra();
	};

	/**
	 * Returns the compression method used on the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getMethod = function() {
	  return this.method;
	};

	/**
	 * Returns the filename of the entry.
	 *
	 * @returns {string}
	 */
	ZipArchiveEntry.prototype.getName = function() {
	  return this.name;
	};

	/**
	 * Returns the platform on which the entry was made.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getPlatform = function() {
	  return this.platform;
	};

	/**
	 * Returns the size of the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getSize = function() {
	  return this.size;
	};

	/**
	 * Returns a date object representing the last modified date of the entry.
	 *
	 * @returns {number|Date}
	 */
	ZipArchiveEntry.prototype.getTime = function() {
	  return this.time !== -1 ? zipUtil.dosToDate(this.time) : -1;
	};

	/**
	 * Returns the DOS timestamp for the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getTimeDos = function() {
	  return this.time !== -1 ? this.time : 0;
	};

	/**
	 * Returns the UNIX file permissions for the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getUnixMode = function() {
	  return this.platform !== constants.PLATFORM_UNIX ? 0 : ((this.getExternalAttributes() >> constants.SHORT_SHIFT) & constants.SHORT_MASK);
	};

	/**
	 * Returns the version of ZIP needed to extract the entry.
	 *
	 * @returns {number}
	 */
	ZipArchiveEntry.prototype.getVersionNeededToExtract = function() {
	  return this.minver;
	};

	/**
	 * Sets the comment of the entry.
	 *
	 * @param comment
	 */
	ZipArchiveEntry.prototype.setComment = function(comment) {
	  if (Buffer.byteLength(comment) !== comment.length) {
	    this.getGeneralPurposeBit().useUTF8ForNames(true);
	  }

	  this.comment = comment;
	};

	/**
	 * Sets the compressed size of the entry.
	 *
	 * @param size
	 */
	ZipArchiveEntry.prototype.setCompressedSize = function(size) {
	  if (size < 0) {
	    throw new Error('invalid entry compressed size');
	  }

	  this.csize = size;
	};

	/**
	 * Sets the checksum of the entry.
	 *
	 * @param crc
	 */
	ZipArchiveEntry.prototype.setCrc = function(crc) {
	  if (crc < 0) {
	    throw new Error('invalid entry crc32');
	  }

	  this.crc = crc;
	};

	/**
	 * Sets the external file attributes of the entry.
	 *
	 * @param attr
	 */
	ZipArchiveEntry.prototype.setExternalAttributes = function(attr) {
	  this.exattr = attr >>> 0;
	};

	/**
	 * Sets the extra fields related to the entry.
	 *
	 * @param extra
	 */
	ZipArchiveEntry.prototype.setExtra = function(extra) {
	  this.extra = extra;
	};

	/**
	 * Sets the general purpose bits related to the entry.
	 *
	 * @param gpb
	 */
	ZipArchiveEntry.prototype.setGeneralPurposeBit = function(gpb) {
	  if (!(gpb instanceof GeneralPurposeBit)) {
	    throw new Error('invalid entry GeneralPurposeBit');
	  }

	  this.gpb = gpb;
	};

	/**
	 * Sets the internal file attributes of the entry.
	 *
	 * @param attr
	 */
	ZipArchiveEntry.prototype.setInternalAttributes = function(attr) {
	  this.inattr = attr;
	};

	/**
	 * Sets the compression method of the entry.
	 *
	 * @param method
	 */
	ZipArchiveEntry.prototype.setMethod = function(method) {
	  if (method < 0) {
	    throw new Error('invalid entry compression method');
	  }

	  this.method = method;
	};

	/**
	 * Sets the name of the entry.
	 *
	 * @param name
	 * @param prependSlash
	 */
	ZipArchiveEntry.prototype.setName = function(name, prependSlash = false) {
	  name = normalizePath(name, false)
	    .replace(/^\w+:/, '')
	    .replace(/^(\.\.\/|\/)+/, '');

	  if (prependSlash) {
	    name = `/${name}`;
	  }

	  if (Buffer.byteLength(name) !== name.length) {
	    this.getGeneralPurposeBit().useUTF8ForNames(true);
	  }

	  this.name = name;
	};

	/**
	 * Sets the platform on which the entry was made.
	 *
	 * @param platform
	 */
	ZipArchiveEntry.prototype.setPlatform = function(platform) {
	  this.platform = platform;
	};

	/**
	 * Sets the size of the entry.
	 *
	 * @param size
	 */
	ZipArchiveEntry.prototype.setSize = function(size) {
	  if (size < 0) {
	    throw new Error('invalid entry size');
	  }

	  this.size = size;
	};

	/**
	 * Sets the time of the entry.
	 *
	 * @param time
	 * @param forceLocalTime
	 */
	ZipArchiveEntry.prototype.setTime = function(time, forceLocalTime) {
	  if (!(time instanceof Date)) {
	    throw new Error('invalid entry time');
	  }

	  this.time = zipUtil.dateToDos(time, forceLocalTime);
	};

	/**
	 * Sets the UNIX file permissions for the entry.
	 *
	 * @param mode
	 */
	ZipArchiveEntry.prototype.setUnixMode = function(mode) {
	  mode |= this.isDirectory() ? constants.S_IFDIR : constants.S_IFREG;

	  var extattr = 0;
	  extattr |= (mode << constants.SHORT_SHIFT) | (this.isDirectory() ? constants.S_DOS_D : constants.S_DOS_A);

	  this.setExternalAttributes(extattr);
	  this.mode = mode & constants.MODE_MASK;
	  this.platform = constants.PLATFORM_UNIX;
	};

	/**
	 * Sets the version of ZIP needed to extract this entry.
	 *
	 * @param minver
	 */
	ZipArchiveEntry.prototype.setVersionNeededToExtract = function(minver) {
	  this.minver = minver;
	};

	/**
	 * Returns true if this entry represents a directory.
	 *
	 * @returns {boolean}
	 */
	ZipArchiveEntry.prototype.isDirectory = function() {
	  return this.getName().slice(-1) === '/';
	};

	/**
	 * Returns true if this entry represents a unix symlink,
	 * in which case the entry's content contains the target path
	 * for the symlink.
	 *
	 * @returns {boolean}
	 */
	ZipArchiveEntry.prototype.isUnixSymlink = function() {
	  return (this.getUnixMode() & UnixStat.FILE_TYPE_FLAG) === UnixStat.LINK_FLAG;
	};

	/**
	 * Returns true if this entry is using the ZIP64 extension of ZIP.
	 *
	 * @returns {boolean}
	 */
	ZipArchiveEntry.prototype.isZip64 = function() {
	  return this.csize > constants.ZIP64_MAGIC || this.size > constants.ZIP64_MAGIC;
	};
	return zipArchiveEntry.exports;
}

var archiveOutputStream = {exports: {}};

var util = {exports: {}};

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var hasRequiredUtil;

function requireUtil () {
	if (hasRequiredUtil) return util.exports;
	hasRequiredUtil = 1;
	var Stream = require$$0$4.Stream;
	var PassThrough = requireReadable().PassThrough;

	var util$1 = util.exports = {};

	util$1.isStream = function(source) {
	  return source instanceof Stream;
	};

	util$1.normalizeInputSource = function(source) {
	  if (source === null) {
	    return Buffer.alloc(0);
	  } else if (typeof source === 'string') {
	    return Buffer.from(source);
	  } else if (util$1.isStream(source) && !source._readableState) {
	    var normalized = new PassThrough();
	    source.pipe(normalized);

	    return normalized;
	  }

	  return source;
	};
	return util.exports;
}

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var hasRequiredArchiveOutputStream;

function requireArchiveOutputStream () {
	if (hasRequiredArchiveOutputStream) return archiveOutputStream.exports;
	hasRequiredArchiveOutputStream = 1;
	var inherits = require$$0$5.inherits;
	var Transform = requireReadable().Transform;

	var ArchiveEntry = requireArchiveEntry();
	var util = requireUtil();

	var ArchiveOutputStream = archiveOutputStream.exports = function(options) {
	  if (!(this instanceof ArchiveOutputStream)) {
	    return new ArchiveOutputStream(options);
	  }

	  Transform.call(this, options);

	  this.offset = 0;
	  this._archive = {
	    finish: false,
	    finished: false,
	    processing: false
	  };
	};

	inherits(ArchiveOutputStream, Transform);

	ArchiveOutputStream.prototype._appendBuffer = function(zae, source, callback) {
	  // scaffold only
	};

	ArchiveOutputStream.prototype._appendStream = function(zae, source, callback) {
	  // scaffold only
	};

	ArchiveOutputStream.prototype._emitErrorCallback = function(err) {
	  if (err) {
	    this.emit('error', err);
	  }
	};

	ArchiveOutputStream.prototype._finish = function(ae) {
	  // scaffold only
	};

	ArchiveOutputStream.prototype._normalizeEntry = function(ae) {
	  // scaffold only
	};

	ArchiveOutputStream.prototype._transform = function(chunk, encoding, callback) {
	  callback(null, chunk);
	};

	ArchiveOutputStream.prototype.entry = function(ae, source, callback) {
	  source = source || null;

	  if (typeof callback !== 'function') {
	    callback = this._emitErrorCallback.bind(this);
	  }

	  if (!(ae instanceof ArchiveEntry)) {
	    callback(new Error('not a valid instance of ArchiveEntry'));
	    return;
	  }

	  if (this._archive.finish || this._archive.finished) {
	    callback(new Error('unacceptable entry after finish'));
	    return;
	  }

	  if (this._archive.processing) {
	    callback(new Error('already processing an entry'));
	    return;
	  }

	  this._archive.processing = true;
	  this._normalizeEntry(ae);
	  this._entry = ae;

	  source = util.normalizeInputSource(source);

	  if (Buffer.isBuffer(source)) {
	    this._appendBuffer(ae, source, callback);
	  } else if (util.isStream(source)) {
	    this._appendStream(ae, source, callback);
	  } else {
	    this._archive.processing = false;
	    callback(new Error('input source must be valid Stream or Buffer instance'));
	    return;
	  }

	  return this;
	};

	ArchiveOutputStream.prototype.finish = function() {
	  if (this._archive.processing) {
	    this._archive.finish = true;
	    return;
	  }

	  this._finish();
	};

	ArchiveOutputStream.prototype.getBytesWritten = function() {
	  return this.offset;
	};

	ArchiveOutputStream.prototype.write = function(chunk, cb) {
	  if (chunk) {
	    this.offset += chunk.length;
	  }

	  return Transform.prototype.write.call(this, chunk, cb);
	};
	return archiveOutputStream.exports;
}

var zipArchiveOutputStream = {exports: {}};

var crc32 = {};

/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */

var hasRequiredCrc32;

function requireCrc32 () {
	if (hasRequiredCrc32) return crc32;
	hasRequiredCrc32 = 1;
	(function (exports) {
		(function (factory) {
			/*jshint ignore:start */
			/*eslint-disable */
			if(typeof DO_NOT_EXPORT_CRC === 'undefined') {
				{
					factory(exports);
				}
			} else {
				factory({});
			}
			/*eslint-enable */
			/*jshint ignore:end */
		}(function(CRC32) {
		CRC32.version = '1.2.2';
		/*global Int32Array */
		function signed_crc_table() {
			var c = 0, table = new Array(256);

			for(var n =0; n != 256; ++n){
				c = n;
				c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
				c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
				c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
				c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
				c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
				c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
				c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
				c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
				table[n] = c;
			}

			return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table;
		}

		var T0 = signed_crc_table();
		function slice_by_16_tables(T) {
			var c = 0, v = 0, n = 0, table = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ;

			for(n = 0; n != 256; ++n) table[n] = T[n];
			for(n = 0; n != 256; ++n) {
				v = T[n];
				for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF];
			}
			var out = [];
			for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256);
			return out;
		}
		var TT = slice_by_16_tables(T0);
		var T1 = TT[0],  T2 = TT[1],  T3 = TT[2],  T4 = TT[3],  T5 = TT[4];
		var T6 = TT[5],  T7 = TT[6],  T8 = TT[7],  T9 = TT[8],  Ta = TT[9];
		var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
		function crc32_bstr(bstr, seed) {
			var C = seed ^ -1;
			for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF];
			return ~C;
		}

		function crc32_buf(B, seed) {
			var C = seed ^ -1, L = B.length - 15, i = 0;
			for(; i < L;) C =
				Tf[B[i++] ^ (C & 255)] ^
				Te[B[i++] ^ ((C >> 8) & 255)] ^
				Td[B[i++] ^ ((C >> 16) & 255)] ^
				Tc[B[i++] ^ (C >>> 24)] ^
				Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^
				T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^
				T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]];
			L += 15;
			while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF];
			return ~C;
		}

		function crc32_str(str, seed) {
			var C = seed ^ -1;
			for(var i = 0, L = str.length, c = 0, d = 0; i < L;) {
				c = str.charCodeAt(i++);
				if(c < 0x80) {
					C = (C>>>8) ^ T0[(C^c)&0xFF];
				} else if(c < 0x800) {
					C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF];
					C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF];
				} else if(c >= 0xD800 && c < 0xE000) {
					c = (c&1023)+64; d = str.charCodeAt(i++)&1023;
					C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF];
					C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF];
					C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF];
					C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF];
				} else {
					C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF];
					C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF];
					C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF];
				}
			}
			return ~C;
		}
		CRC32.table = T0;
		// $FlowIgnore
		CRC32.bstr = crc32_bstr;
		// $FlowIgnore
		CRC32.buf = crc32_buf;
		// $FlowIgnore
		CRC32.str = crc32_str;
		})); 
	} (crc32));
	return crc32;
}

/**
 * node-crc32-stream
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-crc32-stream/blob/master/LICENSE-MIT
 */

var crc32Stream;
var hasRequiredCrc32Stream;

function requireCrc32Stream () {
	if (hasRequiredCrc32Stream) return crc32Stream;
	hasRequiredCrc32Stream = 1;

	const {Transform} = requireReadable();

	const crc32 = requireCrc32();

	class CRC32Stream extends Transform {
	  constructor(options) {
	    super(options);
	    this.checksum = Buffer.allocUnsafe(4);
	    this.checksum.writeInt32BE(0, 0);

	    this.rawSize = 0;
	  }

	  _transform(chunk, encoding, callback) {
	    if (chunk) {
	      this.checksum = crc32.buf(chunk, this.checksum) >>> 0;
	      this.rawSize += chunk.length;
	    }

	    callback(null, chunk);
	  }

	  digest(encoding) {
	    const checksum = Buffer.allocUnsafe(4);
	    checksum.writeUInt32BE(this.checksum >>> 0, 0);
	    return encoding ? checksum.toString(encoding) : checksum;
	  }

	  hex() {
	    return this.digest('hex').toUpperCase();
	  }

	  size() {
	    return this.rawSize;
	  }
	}

	crc32Stream = CRC32Stream;
	return crc32Stream;
}

/**
 * node-crc32-stream
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-crc32-stream/blob/master/LICENSE-MIT
 */

var deflateCrc32Stream;
var hasRequiredDeflateCrc32Stream;

function requireDeflateCrc32Stream () {
	if (hasRequiredDeflateCrc32Stream) return deflateCrc32Stream;
	hasRequiredDeflateCrc32Stream = 1;

	const {DeflateRaw} = require$$0$7;

	const crc32 = requireCrc32();

	class DeflateCRC32Stream extends DeflateRaw {
	  constructor(options) {
	    super(options);

	    this.checksum = Buffer.allocUnsafe(4);
	    this.checksum.writeInt32BE(0, 0);

	    this.rawSize = 0;
	    this.compressedSize = 0;
	  }

	  push(chunk, encoding) {
	    if (chunk) {
	      this.compressedSize += chunk.length;
	    }

	    return super.push(chunk, encoding);
	  }

	  _transform(chunk, encoding, callback) {
	    if (chunk) {
	      this.checksum = crc32.buf(chunk, this.checksum) >>> 0;
	      this.rawSize += chunk.length;
	    }

	    super._transform(chunk, encoding, callback);
	  }

	  digest(encoding) {
	    const checksum = Buffer.allocUnsafe(4);
	    checksum.writeUInt32BE(this.checksum >>> 0, 0);
	    return encoding ? checksum.toString(encoding) : checksum;
	  }

	  hex() {
	    return this.digest('hex').toUpperCase();
	  }

	  size(compressed = false) {
	    if (compressed) {
	      return this.compressedSize;
	    } else {
	      return this.rawSize;
	    }
	  }
	}

	deflateCrc32Stream = DeflateCRC32Stream;
	return deflateCrc32Stream;
}

/**
 * node-crc32-stream
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-crc32-stream/blob/master/LICENSE-MIT
 */

var lib;
var hasRequiredLib;

function requireLib () {
	if (hasRequiredLib) return lib;
	hasRequiredLib = 1;

	lib = {
	  CRC32Stream: requireCrc32Stream(),
	  DeflateCRC32Stream: requireDeflateCrc32Stream()
	};
	return lib;
}

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var hasRequiredZipArchiveOutputStream;

function requireZipArchiveOutputStream () {
	if (hasRequiredZipArchiveOutputStream) return zipArchiveOutputStream.exports;
	hasRequiredZipArchiveOutputStream = 1;
	var inherits = require$$0$5.inherits;
	var crc32 = requireCrc32();
	var {CRC32Stream} = requireLib();
	var {DeflateCRC32Stream} = requireLib();

	var ArchiveOutputStream = requireArchiveOutputStream();
	requireZipArchiveEntry();
	requireGeneralPurposeBit();

	var constants = requireConstants$5();
	requireUtil();
	var zipUtil = requireUtil$1();

	var ZipArchiveOutputStream = zipArchiveOutputStream.exports = function(options) {
	  if (!(this instanceof ZipArchiveOutputStream)) {
	    return new ZipArchiveOutputStream(options);
	  }

	  options = this.options = this._defaults(options);

	  ArchiveOutputStream.call(this, options);

	  this._entry = null;
	  this._entries = [];
	  this._archive = {
	    centralLength: 0,
	    centralOffset: 0,
	    comment: '',
	    finish: false,
	    finished: false,
	    processing: false,
	    forceZip64: options.forceZip64,
	    forceLocalTime: options.forceLocalTime
	  };
	};

	inherits(ZipArchiveOutputStream, ArchiveOutputStream);

	ZipArchiveOutputStream.prototype._afterAppend = function(ae) {
	  this._entries.push(ae);

	  if (ae.getGeneralPurposeBit().usesDataDescriptor()) {
	    this._writeDataDescriptor(ae);
	  }

	  this._archive.processing = false;
	  this._entry = null;

	  if (this._archive.finish && !this._archive.finished) {
	    this._finish();
	  }
	};

	ZipArchiveOutputStream.prototype._appendBuffer = function(ae, source, callback) {
	  if (source.length === 0) {
	    ae.setMethod(constants.METHOD_STORED);
	  }

	  var method = ae.getMethod();

	  if (method === constants.METHOD_STORED) {
	    ae.setSize(source.length);
	    ae.setCompressedSize(source.length);
	    ae.setCrc(crc32.buf(source) >>> 0);
	  }

	  this._writeLocalFileHeader(ae);

	  if (method === constants.METHOD_STORED) {
	    this.write(source);
	    this._afterAppend(ae);
	    callback(null, ae);
	    return;
	  } else if (method === constants.METHOD_DEFLATED) {
	    this._smartStream(ae, callback).end(source);
	    return;
	  } else {
	    callback(new Error('compression method ' + method + ' not implemented'));
	    return;
	  }
	};

	ZipArchiveOutputStream.prototype._appendStream = function(ae, source, callback) {
	  ae.getGeneralPurposeBit().useDataDescriptor(true);
	  ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);

	  this._writeLocalFileHeader(ae);

	  var smart = this._smartStream(ae, callback);
	  source.once('error', function(err) {
	    smart.emit('error', err);
	    smart.end();
	  });
	  source.pipe(smart);
	};

	ZipArchiveOutputStream.prototype._defaults = function(o) {
	  if (typeof o !== 'object') {
	    o = {};
	  }

	  if (typeof o.zlib !== 'object') {
	    o.zlib = {};
	  }

	  if (typeof o.zlib.level !== 'number') {
	    o.zlib.level = constants.ZLIB_BEST_SPEED;
	  }

	  o.forceZip64 = !!o.forceZip64;
	  o.forceLocalTime = !!o.forceLocalTime;

	  return o;
	};

	ZipArchiveOutputStream.prototype._finish = function() {
	  this._archive.centralOffset = this.offset;

	  this._entries.forEach(function(ae) {
	    this._writeCentralFileHeader(ae);
	  }.bind(this));

	  this._archive.centralLength = this.offset - this._archive.centralOffset;

	  if (this.isZip64()) {
	    this._writeCentralDirectoryZip64();
	  }

	  this._writeCentralDirectoryEnd();

	  this._archive.processing = false;
	  this._archive.finish = true;
	  this._archive.finished = true;
	  this.end();
	};

	ZipArchiveOutputStream.prototype._normalizeEntry = function(ae) {
	  if (ae.getMethod() === -1) {
	    ae.setMethod(constants.METHOD_DEFLATED);
	  }

	  if (ae.getMethod() === constants.METHOD_DEFLATED) {
	    ae.getGeneralPurposeBit().useDataDescriptor(true);
	    ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
	  }

	  if (ae.getTime() === -1) {
	    ae.setTime(new Date(), this._archive.forceLocalTime);
	  }

	  ae._offsets = {
	    file: 0,
	    data: 0,
	    contents: 0,
	  };
	};

	ZipArchiveOutputStream.prototype._smartStream = function(ae, callback) {
	  var deflate = ae.getMethod() === constants.METHOD_DEFLATED;
	  var process = deflate ? new DeflateCRC32Stream(this.options.zlib) : new CRC32Stream();
	  var error = null;

	  function handleStuff() {
	    var digest = process.digest().readUInt32BE(0);
	    ae.setCrc(digest);
	    ae.setSize(process.size());
	    ae.setCompressedSize(process.size(true));
	    this._afterAppend(ae);
	    callback(error, ae);
	  }

	  process.once('end', handleStuff.bind(this));
	  process.once('error', function(err) {
	    error = err;
	  });

	  process.pipe(this, { end: false });

	  return process;
	};

	ZipArchiveOutputStream.prototype._writeCentralDirectoryEnd = function() {
	  var records = this._entries.length;
	  var size = this._archive.centralLength;
	  var offset = this._archive.centralOffset;

	  if (this.isZip64()) {
	    records = constants.ZIP64_MAGIC_SHORT;
	    size = constants.ZIP64_MAGIC;
	    offset = constants.ZIP64_MAGIC;
	  }

	  // signature
	  this.write(zipUtil.getLongBytes(constants.SIG_EOCD));

	  // disk numbers
	  this.write(constants.SHORT_ZERO);
	  this.write(constants.SHORT_ZERO);

	  // number of entries
	  this.write(zipUtil.getShortBytes(records));
	  this.write(zipUtil.getShortBytes(records));

	  // length and location of CD
	  this.write(zipUtil.getLongBytes(size));
	  this.write(zipUtil.getLongBytes(offset));

	  // archive comment
	  var comment = this.getComment();
	  var commentLength = Buffer.byteLength(comment);
	  this.write(zipUtil.getShortBytes(commentLength));
	  this.write(comment);
	};

	ZipArchiveOutputStream.prototype._writeCentralDirectoryZip64 = function() {
	  // signature
	  this.write(zipUtil.getLongBytes(constants.SIG_ZIP64_EOCD));

	  // size of the ZIP64 EOCD record
	  this.write(zipUtil.getEightBytes(44));

	  // version made by
	  this.write(zipUtil.getShortBytes(constants.MIN_VERSION_ZIP64));

	  // version to extract
	  this.write(zipUtil.getShortBytes(constants.MIN_VERSION_ZIP64));

	  // disk numbers
	  this.write(constants.LONG_ZERO);
	  this.write(constants.LONG_ZERO);

	  // number of entries
	  this.write(zipUtil.getEightBytes(this._entries.length));
	  this.write(zipUtil.getEightBytes(this._entries.length));

	  // length and location of CD
	  this.write(zipUtil.getEightBytes(this._archive.centralLength));
	  this.write(zipUtil.getEightBytes(this._archive.centralOffset));

	  // extensible data sector
	  // not implemented at this time

	  // end of central directory locator
	  this.write(zipUtil.getLongBytes(constants.SIG_ZIP64_EOCD_LOC));

	  // disk number holding the ZIP64 EOCD record
	  this.write(constants.LONG_ZERO);

	  // relative offset of the ZIP64 EOCD record
	  this.write(zipUtil.getEightBytes(this._archive.centralOffset + this._archive.centralLength));

	  // total number of disks
	  this.write(zipUtil.getLongBytes(1));
	};

	ZipArchiveOutputStream.prototype._writeCentralFileHeader = function(ae) {
	  var gpb = ae.getGeneralPurposeBit();
	  var method = ae.getMethod();
	  var fileOffset = ae._offsets.file;

	  var size = ae.getSize();
	  var compressedSize = ae.getCompressedSize();

	  if (ae.isZip64() || fileOffset > constants.ZIP64_MAGIC) {
	    size = constants.ZIP64_MAGIC;
	    compressedSize = constants.ZIP64_MAGIC;
	    fileOffset = constants.ZIP64_MAGIC;

	    ae.setVersionNeededToExtract(constants.MIN_VERSION_ZIP64);

	    var extraBuf = Buffer.concat([
	      zipUtil.getShortBytes(constants.ZIP64_EXTRA_ID),
	      zipUtil.getShortBytes(24),
	      zipUtil.getEightBytes(ae.getSize()),
	      zipUtil.getEightBytes(ae.getCompressedSize()),
	      zipUtil.getEightBytes(ae._offsets.file)
	    ], 28);

	    ae.setExtra(extraBuf);
	  }

	  // signature
	  this.write(zipUtil.getLongBytes(constants.SIG_CFH));

	  // version made by
	  this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY));

	  // version to extract and general bit flag
	  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
	  this.write(gpb.encode());

	  // compression method
	  this.write(zipUtil.getShortBytes(method));

	  // datetime
	  this.write(zipUtil.getLongBytes(ae.getTimeDos()));

	  // crc32 checksum
	  this.write(zipUtil.getLongBytes(ae.getCrc()));

	  // sizes
	  this.write(zipUtil.getLongBytes(compressedSize));
	  this.write(zipUtil.getLongBytes(size));

	  var name = ae.getName();
	  var comment = ae.getComment();
	  var extra = ae.getCentralDirectoryExtra();

	  if (gpb.usesUTF8ForNames()) {
	    name = Buffer.from(name);
	    comment = Buffer.from(comment);
	  }

	  // name length
	  this.write(zipUtil.getShortBytes(name.length));

	  // extra length
	  this.write(zipUtil.getShortBytes(extra.length));

	  // comments length
	  this.write(zipUtil.getShortBytes(comment.length));

	  // disk number start
	  this.write(constants.SHORT_ZERO);

	  // internal attributes
	  this.write(zipUtil.getShortBytes(ae.getInternalAttributes()));

	  // external attributes
	  this.write(zipUtil.getLongBytes(ae.getExternalAttributes()));

	  // relative offset of LFH
	  this.write(zipUtil.getLongBytes(fileOffset));

	  // name
	  this.write(name);

	  // extra
	  this.write(extra);

	  // comment
	  this.write(comment);
	};

	ZipArchiveOutputStream.prototype._writeDataDescriptor = function(ae) {
	  // signature
	  this.write(zipUtil.getLongBytes(constants.SIG_DD));

	  // crc32 checksum
	  this.write(zipUtil.getLongBytes(ae.getCrc()));

	  // sizes
	  if (ae.isZip64()) {
	    this.write(zipUtil.getEightBytes(ae.getCompressedSize()));
	    this.write(zipUtil.getEightBytes(ae.getSize()));
	  } else {
	    this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
	    this.write(zipUtil.getLongBytes(ae.getSize()));
	  }
	};

	ZipArchiveOutputStream.prototype._writeLocalFileHeader = function(ae) {
	  var gpb = ae.getGeneralPurposeBit();
	  var method = ae.getMethod();
	  var name = ae.getName();
	  var extra = ae.getLocalFileDataExtra();

	  if (ae.isZip64()) {
	    gpb.useDataDescriptor(true);
	    ae.setVersionNeededToExtract(constants.MIN_VERSION_ZIP64);
	  }

	  if (gpb.usesUTF8ForNames()) {
	    name = Buffer.from(name);
	  }

	  ae._offsets.file = this.offset;

	  // signature
	  this.write(zipUtil.getLongBytes(constants.SIG_LFH));

	  // version to extract and general bit flag
	  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
	  this.write(gpb.encode());

	  // compression method
	  this.write(zipUtil.getShortBytes(method));

	  // datetime
	  this.write(zipUtil.getLongBytes(ae.getTimeDos()));

	  ae._offsets.data = this.offset;

	  // crc32 checksum and sizes
	  if (gpb.usesDataDescriptor()) {
	    this.write(constants.LONG_ZERO);
	    this.write(constants.LONG_ZERO);
	    this.write(constants.LONG_ZERO);
	  } else {
	    this.write(zipUtil.getLongBytes(ae.getCrc()));
	    this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
	    this.write(zipUtil.getLongBytes(ae.getSize()));
	  }

	  // name length
	  this.write(zipUtil.getShortBytes(name.length));

	  // extra length
	  this.write(zipUtil.getShortBytes(extra.length));

	  // name
	  this.write(name);

	  // extra
	  this.write(extra);

	  ae._offsets.contents = this.offset;
	};

	ZipArchiveOutputStream.prototype.getComment = function(comment) {
	  return this._archive.comment !== null ? this._archive.comment : '';
	};

	ZipArchiveOutputStream.prototype.isZip64 = function() {
	  return this._archive.forceZip64 || this._entries.length > constants.ZIP64_MAGIC_SHORT || this._archive.centralLength > constants.ZIP64_MAGIC || this._archive.centralOffset > constants.ZIP64_MAGIC;
	};

	ZipArchiveOutputStream.prototype.setComment = function(comment) {
	  this._archive.comment = comment;
	};
	return zipArchiveOutputStream.exports;
}

/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 */

var compressCommons;
var hasRequiredCompressCommons;

function requireCompressCommons () {
	if (hasRequiredCompressCommons) return compressCommons;
	hasRequiredCompressCommons = 1;
	compressCommons = {
	  ArchiveEntry: requireArchiveEntry(),
	  ZipArchiveEntry: requireZipArchiveEntry(),
	  ArchiveOutputStream: requireArchiveOutputStream(),
	  ZipArchiveOutputStream: requireZipArchiveOutputStream()
	};
	return compressCommons;
}

/**
 * ZipStream
 *
 * @ignore
 * @license [MIT]{@link https://github.com/archiverjs/node-zip-stream/blob/master/LICENSE}
 * @copyright (c) 2014 Chris Talkington, contributors.
 */

var hasRequiredZipStream;

function requireZipStream () {
	if (hasRequiredZipStream) return zipStream.exports;
	hasRequiredZipStream = 1;
	var inherits = require$$0$5.inherits;

	var ZipArchiveOutputStream = requireCompressCommons().ZipArchiveOutputStream;
	var ZipArchiveEntry = requireCompressCommons().ZipArchiveEntry;

	var util = requireArchiverUtils();

	/**
	 * @constructor
	 * @extends external:ZipArchiveOutputStream
	 * @param {Object} [options]
	 * @param {String} [options.comment] Sets the zip archive comment.
	 * @param {Boolean} [options.forceLocalTime=false] Forces the archive to contain local file times instead of UTC.
	 * @param {Boolean} [options.forceZip64=false] Forces the archive to contain ZIP64 headers.
	 * @param {Boolean} [options.store=false] Sets the compression method to STORE.
	 * @param {Object} [options.zlib] Passed to [zlib]{@link https://nodejs.org/api/zlib.html#zlib_class_options}
	 * to control compression.
	 */
	var ZipStream = zipStream.exports = function(options) {
	  if (!(this instanceof ZipStream)) {
	    return new ZipStream(options);
	  }

	  options = this.options = options || {};
	  options.zlib = options.zlib || {};

	  ZipArchiveOutputStream.call(this, options);

	  if (typeof options.level === 'number' && options.level >= 0) {
	    options.zlib.level = options.level;
	    delete options.level;
	  }

	  if (!options.forceZip64 && typeof options.zlib.level === 'number' && options.zlib.level === 0) {
	    options.store = true;
	  }

	  options.namePrependSlash = options.namePrependSlash || false;

	  if (options.comment && options.comment.length > 0) {
	    this.setComment(options.comment);
	  }
	};

	inherits(ZipStream, ZipArchiveOutputStream);

	/**
	 * Normalizes entry data with fallbacks for key properties.
	 *
	 * @private
	 * @param  {Object} data
	 * @return {Object}
	 */
	ZipStream.prototype._normalizeFileData = function(data) {
	  data = util.defaults(data, {
	    type: 'file',
	    name: null,
	    namePrependSlash: this.options.namePrependSlash,
	    linkname: null,
	    date: null,
	    mode: null,
	    store: this.options.store,
	    comment: ''
	  });

	  var isDir = data.type === 'directory';
	  var isSymlink = data.type === 'symlink';

	  if (data.name) {
	    data.name = util.sanitizePath(data.name);

	    if (!isSymlink && data.name.slice(-1) === '/') {
	      isDir = true;
	      data.type = 'directory';
	    } else if (isDir) {
	      data.name += '/';
	    }
	  }

	  if (isDir || isSymlink) {
	    data.store = true;
	  }

	  data.date = util.dateify(data.date);

	  return data;
	};

	/**
	 * Appends an entry given an input source (text string, buffer, or stream).
	 *
	 * @param  {(Buffer|Stream|String)} source The input source.
	 * @param  {Object} data
	 * @param  {String} data.name Sets the entry name including internal path.
	 * @param  {String} [data.comment] Sets the entry comment.
	 * @param  {(String|Date)} [data.date=NOW()] Sets the entry date.
	 * @param  {Number} [data.mode=D:0755/F:0644] Sets the entry permissions.
	 * @param  {Boolean} [data.store=options.store] Sets the compression method to STORE.
	 * @param  {String} [data.type=file] Sets the entry type. Defaults to `directory`
	 * if name ends with trailing slash.
	 * @param  {Function} callback
	 * @return this
	 */
	ZipStream.prototype.entry = function(source, data, callback) {
	  if (typeof callback !== 'function') {
	    callback = this._emitErrorCallback.bind(this);
	  }

	  data = this._normalizeFileData(data);

	  if (data.type !== 'file' && data.type !== 'directory' && data.type !== 'symlink') {
	    callback(new Error(data.type + ' entries not currently supported'));
	    return;
	  }

	  if (typeof data.name !== 'string' || data.name.length === 0) {
	    callback(new Error('entry name must be a non-empty string value'));
	    return;
	  }

	  if (data.type === 'symlink' && typeof data.linkname !== 'string') {
	    callback(new Error('entry linkname must be a non-empty string value when type equals symlink'));
	    return;
	  }

	  var entry = new ZipArchiveEntry(data.name);
	  entry.setTime(data.date, this.options.forceLocalTime);

	  if (data.namePrependSlash) {
	    entry.setName(data.name, true);
	  }

	  if (data.store) {
	    entry.setMethod(0);
	  }

	  if (data.comment.length > 0) {
	    entry.setComment(data.comment);
	  }

	  if (data.type === 'symlink' && typeof data.mode !== 'number') {
	    data.mode = 40960; // 0120000
	  }

	  if (typeof data.mode === 'number') {
	    if (data.type === 'symlink') {
	      data.mode |= 40960;
	    }

	    entry.setUnixMode(data.mode);
	  }

	  if (data.type === 'symlink' && typeof data.linkname === 'string') {
	    source = Buffer.from(data.linkname);
	  }

	  return ZipArchiveOutputStream.prototype.entry.call(this, entry, source, callback);
	};

	/**
	 * Finalizes the instance and prevents further appending to the archive
	 * structure (queue will continue til drained).
	 *
	 * @return void
	 */
	ZipStream.prototype.finalize = function() {
	  this.finish();
	};

	/**
	 * Returns the current number of bytes written to this stream.
	 * @function ZipStream#getBytesWritten
	 * @returns {Number}
	 */

	/**
	 * Compress Commons ZipArchiveOutputStream
	 * @external ZipArchiveOutputStream
	 * @see {@link https://github.com/archiverjs/node-compress-commons}
	 */
	return zipStream.exports;
}

/**
 * ZIP Format Plugin
 *
 * @module plugins/zip
 * @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
 * @copyright (c) 2012-2014 Chris Talkington, contributors.
 */

var zip;
var hasRequiredZip;

function requireZip () {
	if (hasRequiredZip) return zip;
	hasRequiredZip = 1;
	var engine = requireZipStream();
	var util = requireArchiverUtils();

	/**
	 * @constructor
	 * @param {ZipOptions} [options]
	 * @param {String} [options.comment] Sets the zip archive comment.
	 * @param {Boolean} [options.forceLocalTime=false] Forces the archive to contain local file times instead of UTC.
	 * @param {Boolean} [options.forceZip64=false] Forces the archive to contain ZIP64 headers.
	 * @param {Boolean} [options.namePrependSlash=false] Prepends a forward slash to archive file paths.
	 * @param {Boolean} [options.store=false] Sets the compression method to STORE.
	 * @param {Object} [options.zlib] Passed to [zlib]{@link https://nodejs.org/api/zlib.html#zlib_class_options}
	 */
	var Zip = function(options) {
	  if (!(this instanceof Zip)) {
	    return new Zip(options);
	  }

	  options = this.options = util.defaults(options, {
	    comment: '',
	    forceUTC: false,
	    namePrependSlash: false,
	    store: false
	  });

	  this.supports = {
	    directory: true,
	    symlink: true
	  };

	  this.engine = new engine(options);
	};

	/**
	 * @param  {(Buffer|Stream)} source
	 * @param  {ZipEntryData} data
	 * @param  {String} data.name Sets the entry name including internal path.
	 * @param  {(String|Date)} [data.date=NOW()] Sets the entry date.
	 * @param  {Number} [data.mode=D:0755/F:0644] Sets the entry permissions.
	 * @param  {String} [data.prefix] Sets a path prefix for the entry name. Useful
	 * when working with methods like `directory` or `glob`.
	 * @param  {fs.Stats} [data.stats] Sets the fs stat data for this entry allowing
	 * for reduction of fs stat calls when stat data is already known.
	 * @param  {Boolean} [data.store=ZipOptions.store] Sets the compression method to STORE.
	 * @param  {Function} callback
	 * @return void
	 */
	Zip.prototype.append = function(source, data, callback) {
	  this.engine.entry(source, data, callback);
	};

	/**
	 * @return void
	 */
	Zip.prototype.finalize = function() {
	  this.engine.finalize();
	};

	/**
	 * @return this.engine
	 */
	Zip.prototype.on = function() {
	  return this.engine.on.apply(this.engine, arguments);
	};

	/**
	 * @return this.engine
	 */
	Zip.prototype.pipe = function() {
	  return this.engine.pipe.apply(this.engine, arguments);
	};

	/**
	 * @return this.engine
	 */
	Zip.prototype.unpipe = function() {
	  return this.engine.unpipe.apply(this.engine, arguments);
	};

	zip = Zip;

	/**
	 * @typedef {Object} ZipOptions
	 * @global
	 * @property {String} [comment] Sets the zip archive comment.
	 * @property {Boolean} [forceLocalTime=false] Forces the archive to contain local file times instead of UTC.
	 * @property {Boolean} [forceZip64=false] Forces the archive to contain ZIP64 headers.
	 * @prpperty {Boolean} [namePrependSlash=false] Prepends a forward slash to archive file paths.
	 * @property {Boolean} [store=false] Sets the compression method to STORE.
	 * @property {Object} [zlib] Passed to [zlib]{@link https://nodejs.org/api/zlib.html#zlib_class_options}
	 * to control compression.
	 * @property {*} [*] See [zip-stream]{@link https://archiverjs.com/zip-stream/ZipStream.html} documentation for current list of properties.
	 */

	/**
	 * @typedef {Object} ZipEntryData
	 * @global
	 * @property {String} name Sets the entry name including internal path.
	 * @property {(String|Date)} [date=NOW()] Sets the entry date.
	 * @property {Number} [mode=D:0755/F:0644] Sets the entry permissions.
	 * @property {Boolean} [namePrependSlash=ZipOptions.namePrependSlash] Prepends a forward slash to archive file paths.
	 * @property {String} [prefix] Sets a path prefix for the entry name. Useful
	 * when working with methods like `directory` or `glob`.
	 * @property {fs.Stats} [stats] Sets the fs stat data for this entry allowing
	 * for reduction of fs stat calls when stat data is already known.
	 * @property {Boolean} [store=ZipOptions.store] Sets the compression method to STORE.
	 */

	/**
	 * ZipStream Module
	 * @external ZipStream
	 * @see {@link https://www.archiverjs.com/zip-stream/ZipStream.html}
	 */
	return zip;
}

var tarStream = {};

var fixedSize;
var hasRequiredFixedSize;

function requireFixedSize () {
	if (hasRequiredFixedSize) return fixedSize;
	hasRequiredFixedSize = 1;
	fixedSize = class FixedFIFO {
	  constructor (hwm) {
	    if (!(hwm > 0) || ((hwm - 1) & hwm) !== 0) throw new Error('Max size for a FixedFIFO should be a power of two')
	    this.buffer = new Array(hwm);
	    this.mask = hwm - 1;
	    this.top = 0;
	    this.btm = 0;
	    this.next = null;
	  }

	  clear () {
	    this.top = this.btm = 0;
	    this.next = null;
	    this.buffer.fill(undefined);
	  }

	  push (data) {
	    if (this.buffer[this.top] !== undefined) return false
	    this.buffer[this.top] = data;
	    this.top = (this.top + 1) & this.mask;
	    return true
	  }

	  shift () {
	    const last = this.buffer[this.btm];
	    if (last === undefined) return undefined
	    this.buffer[this.btm] = undefined;
	    this.btm = (this.btm + 1) & this.mask;
	    return last
	  }

	  peek () {
	    return this.buffer[this.btm]
	  }

	  isEmpty () {
	    return this.buffer[this.btm] === undefined
	  }
	};
	return fixedSize;
}

var fastFifo;
var hasRequiredFastFifo;

function requireFastFifo () {
	if (hasRequiredFastFifo) return fastFifo;
	hasRequiredFastFifo = 1;
	const FixedFIFO = requireFixedSize();

	fastFifo = class FastFIFO {
	  constructor (hwm) {
	    this.hwm = hwm || 16;
	    this.head = new FixedFIFO(this.hwm);
	    this.tail = this.head;
	    this.length = 0;
	  }

	  clear () {
	    this.head = this.tail;
	    this.head.clear();
	    this.length = 0;
	  }

	  push (val) {
	    this.length++;
	    if (!this.head.push(val)) {
	      const prev = this.head;
	      this.head = prev.next = new FixedFIFO(2 * this.head.buffer.length);
	      this.head.push(val);
	    }
	  }

	  shift () {
	    if (this.length !== 0) this.length--;
	    const val = this.tail.shift();
	    if (val === undefined && this.tail.next) {
	      const next = this.tail.next;
	      this.tail.next = null;
	      this.tail = next;
	      return this.tail.shift()
	    }

	    return val
	  }

	  peek () {
	    const val = this.tail.peek();
	    if (val === undefined && this.tail.next) return this.tail.next.peek()
	    return val
	  }

	  isEmpty () {
	    return this.length === 0
	  }
	};
	return fastFifo;
}

var b4a;
var hasRequiredB4a;

function requireB4a () {
	if (hasRequiredB4a) return b4a;
	hasRequiredB4a = 1;
	function isBuffer (value) {
	  return Buffer.isBuffer(value) || value instanceof Uint8Array
	}

	function isEncoding (encoding) {
	  return Buffer.isEncoding(encoding)
	}

	function alloc (size, fill, encoding) {
	  return Buffer.alloc(size, fill, encoding)
	}

	function allocUnsafe (size) {
	  return Buffer.allocUnsafe(size)
	}

	function allocUnsafeSlow (size) {
	  return Buffer.allocUnsafeSlow(size)
	}

	function byteLength (string, encoding) {
	  return Buffer.byteLength(string, encoding)
	}

	function compare (a, b) {
	  return Buffer.compare(a, b)
	}

	function concat (buffers, totalLength) {
	  return Buffer.concat(buffers, totalLength)
	}

	function copy (source, target, targetStart, start, end) {
	  return toBuffer(source).copy(target, targetStart, start, end)
	}

	function equals (a, b) {
	  return toBuffer(a).equals(b)
	}

	function fill (buffer, value, offset, end, encoding) {
	  return toBuffer(buffer).fill(value, offset, end, encoding)
	}

	function from (value, encodingOrOffset, length) {
	  return Buffer.from(value, encodingOrOffset, length)
	}

	function includes (buffer, value, byteOffset, encoding) {
	  return toBuffer(buffer).includes(value, byteOffset, encoding)
	}

	function indexOf (buffer, value, byfeOffset, encoding) {
	  return toBuffer(buffer).indexOf(value, byfeOffset, encoding)
	}

	function lastIndexOf (buffer, value, byteOffset, encoding) {
	  return toBuffer(buffer).lastIndexOf(value, byteOffset, encoding)
	}

	function swap16 (buffer) {
	  return toBuffer(buffer).swap16()
	}

	function swap32 (buffer) {
	  return toBuffer(buffer).swap32()
	}

	function swap64 (buffer) {
	  return toBuffer(buffer).swap64()
	}

	function toBuffer (buffer) {
	  if (Buffer.isBuffer(buffer)) return buffer
	  return Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength)
	}

	function toString (buffer, encoding, start, end) {
	  return toBuffer(buffer).toString(encoding, start, end)
	}

	function write (buffer, string, offset, length, encoding) {
	  return toBuffer(buffer).write(string, offset, length, encoding)
	}

	function writeDoubleLE (buffer, value, offset) {
	  return toBuffer(buffer).writeDoubleLE(value, offset)
	}

	function writeFloatLE (buffer, value, offset) {
	  return toBuffer(buffer).writeFloatLE(value, offset)
	}

	function writeUInt32LE (buffer, value, offset) {
	  return toBuffer(buffer).writeUInt32LE(value, offset)
	}

	function writeInt32LE (buffer, value, offset) {
	  return toBuffer(buffer).writeInt32LE(value, offset)
	}

	function readDoubleLE (buffer, offset) {
	  return toBuffer(buffer).readDoubleLE(offset)
	}

	function readFloatLE (buffer, offset) {
	  return toBuffer(buffer).readFloatLE(offset)
	}

	function readUInt32LE (buffer, offset) {
	  return toBuffer(buffer).readUInt32LE(offset)
	}

	function readInt32LE (buffer, offset) {
	  return toBuffer(buffer).readInt32LE(offset)
	}

	function writeDoubleBE (buffer, value, offset) {
	  return toBuffer(buffer).writeDoubleBE(value, offset)
	}

	function writeFloatBE (buffer, value, offset) {
	  return toBuffer(buffer).writeFloatBE(value, offset)
	}

	function writeUInt32BE (buffer, value, offset) {
	  return toBuffer(buffer).writeUInt32BE(value, offset)
	}

	function writeInt32BE (buffer, value, offset) {
	  return toBuffer(buffer).writeInt32BE(value, offset)
	}

	function readDoubleBE (buffer, offset) {
	  return toBuffer(buffer).readDoubleBE(offset)
	}

	function readFloatBE (buffer, offset) {
	  return toBuffer(buffer).readFloatBE(offset)
	}

	function readUInt32BE (buffer, offset) {
	  return toBuffer(buffer).readUInt32BE(offset)
	}

	function readInt32BE (buffer, offset) {
	  return toBuffer(buffer).readInt32BE(offset)
	}

	b4a = {
	  isBuffer,
	  isEncoding,
	  alloc,
	  allocUnsafe,
	  allocUnsafeSlow,
	  byteLength,
	  compare,
	  concat,
	  copy,
	  equals,
	  fill,
	  from,
	  includes,
	  indexOf,
	  lastIndexOf,
	  swap16,
	  swap32,
	  swap64,
	  toBuffer,
	  toString,
	  write,
	  writeDoubleLE,
	  writeFloatLE,
	  writeUInt32LE,
	  writeInt32LE,
	  readDoubleLE,
	  readFloatLE,
	  readUInt32LE,
	  readInt32LE,
	  writeDoubleBE,
	  writeFloatBE,
	  writeUInt32BE,
	  writeInt32BE,
	  readDoubleBE,
	  readFloatBE,
	  readUInt32BE,
	  readInt32BE

	};
	return b4a;
}

var passThroughDecoder;
var hasRequiredPassThroughDecoder;

function requirePassThroughDecoder () {
	if (hasRequiredPassThroughDecoder) return passThroughDecoder;
	hasRequiredPassThroughDecoder = 1;
	const b4a = requireB4a();

	passThroughDecoder = class PassThroughDecoder {
	  constructor (encoding) {
	    this.encoding = encoding;
	  }

	  get remaining () {
	    return 0
	  }

	  decode (tail) {
	    return b4a.toString(tail, this.encoding)
	  }

	  flush () {
	    return ''
	  }
	};
	return passThroughDecoder;
}

var utf8Decoder;
var hasRequiredUtf8Decoder;

function requireUtf8Decoder () {
	if (hasRequiredUtf8Decoder) return utf8Decoder;
	hasRequiredUtf8Decoder = 1;
	const b4a = requireB4a();

	/**
	 * https://encoding.spec.whatwg.org/#utf-8-decoder
	 */
	utf8Decoder = class UTF8Decoder {
	  constructor () {
	    this.codePoint = 0;
	    this.bytesSeen = 0;
	    this.bytesNeeded = 0;
	    this.lowerBoundary = 0x80;
	    this.upperBoundary = 0xbf;
	  }

	  get remaining () {
	    return this.bytesSeen
	  }

	  decode (data) {
	    // If we have a fast path, just sniff if the last part is a boundary
	    if (this.bytesNeeded === 0) {
	      let isBoundary = true;

	      for (let i = Math.max(0, data.byteLength - 4), n = data.byteLength; i < n && isBoundary; i++) {
	        isBoundary = data[i] <= 0x7f;
	      }

	      if (isBoundary) return b4a.toString(data, 'utf8')
	    }

	    let result = '';

	    for (let i = 0, n = data.byteLength; i < n; i++) {
	      const byte = data[i];

	      if (this.bytesNeeded === 0) {
	        if (byte <= 0x7f) {
	          result += String.fromCharCode(byte);
	        } else {
	          this.bytesSeen = 1;

	          if (byte >= 0xc2 && byte <= 0xdf) {
	            this.bytesNeeded = 2;
	            this.codePoint = byte & 0x1f;
	          } else if (byte >= 0xe0 && byte <= 0xef) {
	            if (byte === 0xe0) this.lowerBoundary = 0xa0;
	            else if (byte === 0xed) this.upperBoundary = 0x9f;
	            this.bytesNeeded = 3;
	            this.codePoint = byte & 0xf;
	          } else if (byte >= 0xf0 && byte <= 0xf4) {
	            if (byte === 0xf0) this.lowerBoundary = 0x90;
	            if (byte === 0xf4) this.upperBoundary = 0x8f;
	            this.bytesNeeded = 4;
	            this.codePoint = byte & 0x7;
	          } else {
	            result += '\ufffd';
	          }
	        }

	        continue
	      }

	      if (byte < this.lowerBoundary || byte > this.upperBoundary) {
	        this.codePoint = 0;
	        this.bytesNeeded = 0;
	        this.bytesSeen = 0;
	        this.lowerBoundary = 0x80;
	        this.upperBoundary = 0xbf;

	        result += '\ufffd';

	        continue
	      }

	      this.lowerBoundary = 0x80;
	      this.upperBoundary = 0xbf;

	      this.codePoint = (this.codePoint << 6) | (byte & 0x3f);
	      this.bytesSeen++;

	      if (this.bytesSeen !== this.bytesNeeded) continue

	      result += String.fromCodePoint(this.codePoint);

	      this.codePoint = 0;
	      this.bytesNeeded = 0;
	      this.bytesSeen = 0;
	    }

	    return result
	  }

	  flush () {
	    const result = this.bytesNeeded > 0 ? '\ufffd' : '';

	    this.codePoint = 0;
	    this.bytesNeeded = 0;
	    this.bytesSeen = 0;
	    this.lowerBoundary = 0x80;
	    this.upperBoundary = 0xbf;

	    return result
	  }
	};
	return utf8Decoder;
}

var textDecoder;
var hasRequiredTextDecoder;

function requireTextDecoder () {
	if (hasRequiredTextDecoder) return textDecoder;
	hasRequiredTextDecoder = 1;
	const PassThroughDecoder = requirePassThroughDecoder();
	const UTF8Decoder = requireUtf8Decoder();

	textDecoder = class TextDecoder {
	  constructor (encoding = 'utf8') {
	    this.encoding = normalizeEncoding(encoding);

	    switch (this.encoding) {
	      case 'utf8':
	        this.decoder = new UTF8Decoder();
	        break
	      case 'utf16le':
	      case 'base64':
	        throw new Error('Unsupported encoding: ' + this.encoding)
	      default:
	        this.decoder = new PassThroughDecoder(this.encoding);
	    }
	  }

	  get remaining () {
	    return this.decoder.remaining
	  }

	  push (data) {
	    if (typeof data === 'string') return data
	    return this.decoder.decode(data)
	  }

	  // For Node.js compatibility
	  write (data) {
	    return this.push(data)
	  }

	  end (data) {
	    let result = '';
	    if (data) result = this.push(data);
	    result += this.decoder.flush();
	    return result
	  }
	};

	function normalizeEncoding (encoding) {
	  encoding = encoding.toLowerCase();

	  switch (encoding) {
	    case 'utf8':
	    case 'utf-8':
	      return 'utf8'
	    case 'ucs2':
	    case 'ucs-2':
	    case 'utf16le':
	    case 'utf-16le':
	      return 'utf16le'
	    case 'latin1':
	    case 'binary':
	      return 'latin1'
	    case 'base64':
	    case 'ascii':
	    case 'hex':
	      return encoding
	    default:
	      throw new Error('Unknown encoding: ' + encoding)
	  }
	}	return textDecoder;
}

var streamx;
var hasRequiredStreamx;

function requireStreamx () {
	if (hasRequiredStreamx) return streamx;
	hasRequiredStreamx = 1;
	const { EventEmitter } = require$$0$1;
	const STREAM_DESTROYED = new Error('Stream was destroyed');
	const PREMATURE_CLOSE = new Error('Premature close');

	const FIFO = requireFastFifo();
	const TextDecoder = requireTextDecoder();

	// if we do a future major, expect queue microtask to be there always, for now a bit defensive
	const qmt = typeof queueMicrotask === 'undefined' ? fn => commonjsGlobal.process.nextTick(fn) : queueMicrotask;

	/* eslint-disable no-multi-spaces */

	// 29 bits used total (4 from shared, 14 from read, and 11 from write)
	const MAX = ((1 << 29) - 1);

	// Shared state
	const OPENING       = 0b0001;
	const PREDESTROYING = 0b0010;
	const DESTROYING    = 0b0100;
	const DESTROYED     = 0b1000;

	const NOT_OPENING = MAX ^ OPENING;
	const NOT_PREDESTROYING = MAX ^ PREDESTROYING;

	// Read state (4 bit offset from shared state)
	const READ_ACTIVE           = 0b00000000000001 << 4;
	const READ_UPDATING         = 0b00000000000010 << 4;
	const READ_PRIMARY          = 0b00000000000100 << 4;
	const READ_QUEUED           = 0b00000000001000 << 4;
	const READ_RESUMED          = 0b00000000010000 << 4;
	const READ_PIPE_DRAINED     = 0b00000000100000 << 4;
	const READ_ENDING           = 0b00000001000000 << 4;
	const READ_EMIT_DATA        = 0b00000010000000 << 4;
	const READ_EMIT_READABLE    = 0b00000100000000 << 4;
	const READ_EMITTED_READABLE = 0b00001000000000 << 4;
	const READ_DONE             = 0b00010000000000 << 4;
	const READ_NEXT_TICK        = 0b00100000000000 << 4;
	const READ_NEEDS_PUSH       = 0b01000000000000 << 4;
	const READ_READ_AHEAD       = 0b10000000000000 << 4;

	// Combined read state
	const READ_FLOWING = READ_RESUMED | READ_PIPE_DRAINED;
	const READ_ACTIVE_AND_NEEDS_PUSH = READ_ACTIVE | READ_NEEDS_PUSH;
	const READ_PRIMARY_AND_ACTIVE = READ_PRIMARY | READ_ACTIVE;
	const READ_EMIT_READABLE_AND_QUEUED = READ_EMIT_READABLE | READ_QUEUED;
	const READ_RESUMED_READ_AHEAD = READ_RESUMED | READ_READ_AHEAD;

	const READ_NOT_ACTIVE             = MAX ^ READ_ACTIVE;
	const READ_NON_PRIMARY            = MAX ^ READ_PRIMARY;
	const READ_NON_PRIMARY_AND_PUSHED = MAX ^ (READ_PRIMARY | READ_NEEDS_PUSH);
	const READ_PUSHED                 = MAX ^ READ_NEEDS_PUSH;
	const READ_PAUSED                 = MAX ^ READ_RESUMED;
	const READ_NOT_QUEUED             = MAX ^ (READ_QUEUED | READ_EMITTED_READABLE);
	const READ_NOT_ENDING             = MAX ^ READ_ENDING;
	const READ_PIPE_NOT_DRAINED       = MAX ^ READ_FLOWING;
	const READ_NOT_NEXT_TICK          = MAX ^ READ_NEXT_TICK;
	const READ_NOT_UPDATING           = MAX ^ READ_UPDATING;
	const READ_NO_READ_AHEAD          = MAX ^ READ_READ_AHEAD;
	const READ_PAUSED_NO_READ_AHEAD   = MAX ^ READ_RESUMED_READ_AHEAD;

	// Write state (18 bit offset, 4 bit offset from shared state and 14 from read state)
	const WRITE_ACTIVE     = 0b00000000001 << 18;
	const WRITE_UPDATING   = 0b00000000010 << 18;
	const WRITE_PRIMARY    = 0b00000000100 << 18;
	const WRITE_QUEUED     = 0b00000001000 << 18;
	const WRITE_UNDRAINED  = 0b00000010000 << 18;
	const WRITE_DONE       = 0b00000100000 << 18;
	const WRITE_EMIT_DRAIN = 0b00001000000 << 18;
	const WRITE_NEXT_TICK  = 0b00010000000 << 18;
	const WRITE_WRITING    = 0b00100000000 << 18;
	const WRITE_FINISHING  = 0b01000000000 << 18;
	const WRITE_CORKED     = 0b10000000000 << 18;

	const WRITE_NOT_ACTIVE    = MAX ^ (WRITE_ACTIVE | WRITE_WRITING);
	const WRITE_NON_PRIMARY   = MAX ^ WRITE_PRIMARY;
	const WRITE_NOT_FINISHING = MAX ^ (WRITE_ACTIVE | WRITE_FINISHING);
	const WRITE_DRAINED       = MAX ^ WRITE_UNDRAINED;
	const WRITE_NOT_QUEUED    = MAX ^ WRITE_QUEUED;
	const WRITE_NOT_NEXT_TICK = MAX ^ WRITE_NEXT_TICK;
	const WRITE_NOT_UPDATING  = MAX ^ WRITE_UPDATING;
	const WRITE_NOT_CORKED    = MAX ^ WRITE_CORKED;

	// Combined shared state
	const ACTIVE = READ_ACTIVE | WRITE_ACTIVE;
	const NOT_ACTIVE = MAX ^ ACTIVE;
	const DONE = READ_DONE | WRITE_DONE;
	const DESTROY_STATUS = DESTROYING | DESTROYED | PREDESTROYING;
	const OPEN_STATUS = DESTROY_STATUS | OPENING;
	const AUTO_DESTROY = DESTROY_STATUS | DONE;
	const NON_PRIMARY = WRITE_NON_PRIMARY & READ_NON_PRIMARY;
	const ACTIVE_OR_TICKING = WRITE_NEXT_TICK | READ_NEXT_TICK;
	const TICKING = ACTIVE_OR_TICKING & NOT_ACTIVE;
	const IS_OPENING = OPEN_STATUS | TICKING;

	// Combined shared state and read state
	const READ_PRIMARY_STATUS = OPEN_STATUS | READ_ENDING | READ_DONE;
	const READ_STATUS = OPEN_STATUS | READ_DONE | READ_QUEUED;
	const READ_ENDING_STATUS = OPEN_STATUS | READ_ENDING | READ_QUEUED;
	const READ_READABLE_STATUS = OPEN_STATUS | READ_EMIT_READABLE | READ_QUEUED | READ_EMITTED_READABLE;
	const SHOULD_NOT_READ = OPEN_STATUS | READ_ACTIVE | READ_ENDING | READ_DONE | READ_NEEDS_PUSH | READ_READ_AHEAD;
	const READ_BACKPRESSURE_STATUS = DESTROY_STATUS | READ_ENDING | READ_DONE;
	const READ_UPDATE_SYNC_STATUS = READ_UPDATING | OPEN_STATUS | READ_NEXT_TICK | READ_PRIMARY;
	const READ_NEXT_TICK_OR_OPENING = READ_NEXT_TICK | OPENING;

	// Combined write state
	const WRITE_PRIMARY_STATUS = OPEN_STATUS | WRITE_FINISHING | WRITE_DONE;
	const WRITE_QUEUED_AND_UNDRAINED = WRITE_QUEUED | WRITE_UNDRAINED;
	const WRITE_QUEUED_AND_ACTIVE = WRITE_QUEUED | WRITE_ACTIVE;
	const WRITE_DRAIN_STATUS = WRITE_QUEUED | WRITE_UNDRAINED | OPEN_STATUS | WRITE_ACTIVE;
	const WRITE_STATUS = OPEN_STATUS | WRITE_ACTIVE | WRITE_QUEUED | WRITE_CORKED;
	const WRITE_PRIMARY_AND_ACTIVE = WRITE_PRIMARY | WRITE_ACTIVE;
	const WRITE_ACTIVE_AND_WRITING = WRITE_ACTIVE | WRITE_WRITING;
	const WRITE_FINISHING_STATUS = OPEN_STATUS | WRITE_FINISHING | WRITE_QUEUED_AND_ACTIVE | WRITE_DONE;
	const WRITE_BACKPRESSURE_STATUS = WRITE_UNDRAINED | DESTROY_STATUS | WRITE_FINISHING | WRITE_DONE;
	const WRITE_UPDATE_SYNC_STATUS = WRITE_UPDATING | OPEN_STATUS | WRITE_NEXT_TICK | WRITE_PRIMARY;
	const WRITE_DROP_DATA = WRITE_FINISHING | WRITE_DONE | DESTROY_STATUS;

	const asyncIterator = Symbol.asyncIterator || Symbol('asyncIterator');

	class WritableState {
	  constructor (stream, { highWaterMark = 16384, map = null, mapWritable, byteLength, byteLengthWritable } = {}) {
	    this.stream = stream;
	    this.queue = new FIFO();
	    this.highWaterMark = highWaterMark;
	    this.buffered = 0;
	    this.error = null;
	    this.pipeline = null;
	    this.drains = null; // if we add more seldomly used helpers we might them into a subobject so its a single ptr
	    this.byteLength = byteLengthWritable || byteLength || defaultByteLength;
	    this.map = mapWritable || map;
	    this.afterWrite = afterWrite.bind(this);
	    this.afterUpdateNextTick = updateWriteNT.bind(this);
	  }

	  get ended () {
	    return (this.stream._duplexState & WRITE_DONE) !== 0
	  }

	  push (data) {
	    if ((this.stream._duplexState & WRITE_DROP_DATA) !== 0) return false
	    if (this.map !== null) data = this.map(data);

	    this.buffered += this.byteLength(data);
	    this.queue.push(data);

	    if (this.buffered < this.highWaterMark) {
	      this.stream._duplexState |= WRITE_QUEUED;
	      return true
	    }

	    this.stream._duplexState |= WRITE_QUEUED_AND_UNDRAINED;
	    return false
	  }

	  shift () {
	    const data = this.queue.shift();

	    this.buffered -= this.byteLength(data);
	    if (this.buffered === 0) this.stream._duplexState &= WRITE_NOT_QUEUED;

	    return data
	  }

	  end (data) {
	    if (typeof data === 'function') this.stream.once('finish', data);
	    else if (data !== undefined && data !== null) this.push(data);
	    this.stream._duplexState = (this.stream._duplexState | WRITE_FINISHING) & WRITE_NON_PRIMARY;
	  }

	  autoBatch (data, cb) {
	    const buffer = [];
	    const stream = this.stream;

	    buffer.push(data);
	    while ((stream._duplexState & WRITE_STATUS) === WRITE_QUEUED_AND_ACTIVE) {
	      buffer.push(stream._writableState.shift());
	    }

	    if ((stream._duplexState & OPEN_STATUS) !== 0) return cb(null)
	    stream._writev(buffer, cb);
	  }

	  update () {
	    const stream = this.stream;

	    stream._duplexState |= WRITE_UPDATING;

	    do {
	      while ((stream._duplexState & WRITE_STATUS) === WRITE_QUEUED) {
	        const data = this.shift();
	        stream._duplexState |= WRITE_ACTIVE_AND_WRITING;
	        stream._write(data, this.afterWrite);
	      }

	      if ((stream._duplexState & WRITE_PRIMARY_AND_ACTIVE) === 0) this.updateNonPrimary();
	    } while (this.continueUpdate() === true)

	    stream._duplexState &= WRITE_NOT_UPDATING;
	  }

	  updateNonPrimary () {
	    const stream = this.stream;

	    if ((stream._duplexState & WRITE_FINISHING_STATUS) === WRITE_FINISHING) {
	      stream._duplexState = stream._duplexState | WRITE_ACTIVE;
	      stream._final(afterFinal.bind(this));
	      return
	    }

	    if ((stream._duplexState & DESTROY_STATUS) === DESTROYING) {
	      if ((stream._duplexState & ACTIVE_OR_TICKING) === 0) {
	        stream._duplexState |= ACTIVE;
	        stream._destroy(afterDestroy.bind(this));
	      }
	      return
	    }

	    if ((stream._duplexState & IS_OPENING) === OPENING) {
	      stream._duplexState = (stream._duplexState | ACTIVE) & NOT_OPENING;
	      stream._open(afterOpen.bind(this));
	    }
	  }

	  continueUpdate () {
	    if ((this.stream._duplexState & WRITE_NEXT_TICK) === 0) return false
	    this.stream._duplexState &= WRITE_NOT_NEXT_TICK;
	    return true
	  }

	  updateCallback () {
	    if ((this.stream._duplexState & WRITE_UPDATE_SYNC_STATUS) === WRITE_PRIMARY) this.update();
	    else this.updateNextTick();
	  }

	  updateNextTick () {
	    if ((this.stream._duplexState & WRITE_NEXT_TICK) !== 0) return
	    this.stream._duplexState |= WRITE_NEXT_TICK;
	    if ((this.stream._duplexState & WRITE_UPDATING) === 0) qmt(this.afterUpdateNextTick);
	  }
	}

	class ReadableState {
	  constructor (stream, { highWaterMark = 16384, map = null, mapReadable, byteLength, byteLengthReadable } = {}) {
	    this.stream = stream;
	    this.queue = new FIFO();
	    this.highWaterMark = highWaterMark === 0 ? 1 : highWaterMark;
	    this.buffered = 0;
	    this.readAhead = highWaterMark > 0;
	    this.error = null;
	    this.pipeline = null;
	    this.byteLength = byteLengthReadable || byteLength || defaultByteLength;
	    this.map = mapReadable || map;
	    this.pipeTo = null;
	    this.afterRead = afterRead.bind(this);
	    this.afterUpdateNextTick = updateReadNT.bind(this);
	  }

	  get ended () {
	    return (this.stream._duplexState & READ_DONE) !== 0
	  }

	  pipe (pipeTo, cb) {
	    if (this.pipeTo !== null) throw new Error('Can only pipe to one destination')
	    if (typeof cb !== 'function') cb = null;

	    this.stream._duplexState |= READ_PIPE_DRAINED;
	    this.pipeTo = pipeTo;
	    this.pipeline = new Pipeline(this.stream, pipeTo, cb);

	    if (cb) this.stream.on('error', noop); // We already error handle this so supress crashes

	    if (isStreamx(pipeTo)) {
	      pipeTo._writableState.pipeline = this.pipeline;
	      if (cb) pipeTo.on('error', noop); // We already error handle this so supress crashes
	      pipeTo.on('finish', this.pipeline.finished.bind(this.pipeline)); // TODO: just call finished from pipeTo itself
	    } else {
	      const onerror = this.pipeline.done.bind(this.pipeline, pipeTo);
	      const onclose = this.pipeline.done.bind(this.pipeline, pipeTo, null); // onclose has a weird bool arg
	      pipeTo.on('error', onerror);
	      pipeTo.on('close', onclose);
	      pipeTo.on('finish', this.pipeline.finished.bind(this.pipeline));
	    }

	    pipeTo.on('drain', afterDrain.bind(this));
	    this.stream.emit('piping', pipeTo);
	    pipeTo.emit('pipe', this.stream);
	  }

	  push (data) {
	    const stream = this.stream;

	    if (data === null) {
	      this.highWaterMark = 0;
	      stream._duplexState = (stream._duplexState | READ_ENDING) & READ_NON_PRIMARY_AND_PUSHED;
	      return false
	    }

	    if (this.map !== null) {
	      data = this.map(data);
	      if (data === null) {
	        stream._duplexState &= READ_PUSHED;
	        return this.buffered < this.highWaterMark
	      }
	    }

	    this.buffered += this.byteLength(data);
	    this.queue.push(data);

	    stream._duplexState = (stream._duplexState | READ_QUEUED) & READ_PUSHED;

	    return this.buffered < this.highWaterMark
	  }

	  shift () {
	    const data = this.queue.shift();

	    this.buffered -= this.byteLength(data);
	    if (this.buffered === 0) this.stream._duplexState &= READ_NOT_QUEUED;
	    return data
	  }

	  unshift (data) {
	    const pending = [this.map !== null ? this.map(data) : data];
	    while (this.buffered > 0) pending.push(this.shift());

	    for (let i = 0; i < pending.length - 1; i++) {
	      const data = pending[i];
	      this.buffered += this.byteLength(data);
	      this.queue.push(data);
	    }

	    this.push(pending[pending.length - 1]);
	  }

	  read () {
	    const stream = this.stream;

	    if ((stream._duplexState & READ_STATUS) === READ_QUEUED) {
	      const data = this.shift();
	      if (this.pipeTo !== null && this.pipeTo.write(data) === false) stream._duplexState &= READ_PIPE_NOT_DRAINED;
	      if ((stream._duplexState & READ_EMIT_DATA) !== 0) stream.emit('data', data);
	      return data
	    }

	    if (this.readAhead === false) {
	      stream._duplexState |= READ_READ_AHEAD;
	      this.updateNextTick();
	    }

	    return null
	  }

	  drain () {
	    const stream = this.stream;

	    while ((stream._duplexState & READ_STATUS) === READ_QUEUED && (stream._duplexState & READ_FLOWING) !== 0) {
	      const data = this.shift();
	      if (this.pipeTo !== null && this.pipeTo.write(data) === false) stream._duplexState &= READ_PIPE_NOT_DRAINED;
	      if ((stream._duplexState & READ_EMIT_DATA) !== 0) stream.emit('data', data);
	    }
	  }

	  update () {
	    const stream = this.stream;

	    stream._duplexState |= READ_UPDATING;

	    do {
	      this.drain();

	      while (this.buffered < this.highWaterMark && (stream._duplexState & SHOULD_NOT_READ) === READ_READ_AHEAD) {
	        stream._duplexState |= READ_ACTIVE_AND_NEEDS_PUSH;
	        stream._read(this.afterRead);
	        this.drain();
	      }

	      if ((stream._duplexState & READ_READABLE_STATUS) === READ_EMIT_READABLE_AND_QUEUED) {
	        stream._duplexState |= READ_EMITTED_READABLE;
	        stream.emit('readable');
	      }

	      if ((stream._duplexState & READ_PRIMARY_AND_ACTIVE) === 0) this.updateNonPrimary();
	    } while (this.continueUpdate() === true)

	    stream._duplexState &= READ_NOT_UPDATING;
	  }

	  updateNonPrimary () {
	    const stream = this.stream;

	    if ((stream._duplexState & READ_ENDING_STATUS) === READ_ENDING) {
	      stream._duplexState = (stream._duplexState | READ_DONE) & READ_NOT_ENDING;
	      stream.emit('end');
	      if ((stream._duplexState & AUTO_DESTROY) === DONE) stream._duplexState |= DESTROYING;
	      if (this.pipeTo !== null) this.pipeTo.end();
	    }

	    if ((stream._duplexState & DESTROY_STATUS) === DESTROYING) {
	      if ((stream._duplexState & ACTIVE_OR_TICKING) === 0) {
	        stream._duplexState |= ACTIVE;
	        stream._destroy(afterDestroy.bind(this));
	      }
	      return
	    }

	    if ((stream._duplexState & IS_OPENING) === OPENING) {
	      stream._duplexState = (stream._duplexState | ACTIVE) & NOT_OPENING;
	      stream._open(afterOpen.bind(this));
	    }
	  }

	  continueUpdate () {
	    if ((this.stream._duplexState & READ_NEXT_TICK) === 0) return false
	    this.stream._duplexState &= READ_NOT_NEXT_TICK;
	    return true
	  }

	  updateCallback () {
	    if ((this.stream._duplexState & READ_UPDATE_SYNC_STATUS) === READ_PRIMARY) this.update();
	    else this.updateNextTick();
	  }

	  updateNextTickIfOpen () {
	    if ((this.stream._duplexState & READ_NEXT_TICK_OR_OPENING) !== 0) return
	    this.stream._duplexState |= READ_NEXT_TICK;
	    if ((this.stream._duplexState & READ_UPDATING) === 0) qmt(this.afterUpdateNextTick);
	  }

	  updateNextTick () {
	    if ((this.stream._duplexState & READ_NEXT_TICK) !== 0) return
	    this.stream._duplexState |= READ_NEXT_TICK;
	    if ((this.stream._duplexState & READ_UPDATING) === 0) qmt(this.afterUpdateNextTick);
	  }
	}

	class TransformState {
	  constructor (stream) {
	    this.data = null;
	    this.afterTransform = afterTransform.bind(stream);
	    this.afterFinal = null;
	  }
	}

	class Pipeline {
	  constructor (src, dst, cb) {
	    this.from = src;
	    this.to = dst;
	    this.afterPipe = cb;
	    this.error = null;
	    this.pipeToFinished = false;
	  }

	  finished () {
	    this.pipeToFinished = true;
	  }

	  done (stream, err) {
	    if (err) this.error = err;

	    if (stream === this.to) {
	      this.to = null;

	      if (this.from !== null) {
	        if ((this.from._duplexState & READ_DONE) === 0 || !this.pipeToFinished) {
	          this.from.destroy(this.error || new Error('Writable stream closed prematurely'));
	        }
	        return
	      }
	    }

	    if (stream === this.from) {
	      this.from = null;

	      if (this.to !== null) {
	        if ((stream._duplexState & READ_DONE) === 0) {
	          this.to.destroy(this.error || new Error('Readable stream closed before ending'));
	        }
	        return
	      }
	    }

	    if (this.afterPipe !== null) this.afterPipe(this.error);
	    this.to = this.from = this.afterPipe = null;
	  }
	}

	function afterDrain () {
	  this.stream._duplexState |= READ_PIPE_DRAINED;
	  this.updateCallback();
	}

	function afterFinal (err) {
	  const stream = this.stream;
	  if (err) stream.destroy(err);
	  if ((stream._duplexState & DESTROY_STATUS) === 0) {
	    stream._duplexState |= WRITE_DONE;
	    stream.emit('finish');
	  }
	  if ((stream._duplexState & AUTO_DESTROY) === DONE) {
	    stream._duplexState |= DESTROYING;
	  }

	  stream._duplexState &= WRITE_NOT_FINISHING;

	  // no need to wait the extra tick here, so we short circuit that
	  if ((stream._duplexState & WRITE_UPDATING) === 0) this.update();
	  else this.updateNextTick();
	}

	function afterDestroy (err) {
	  const stream = this.stream;

	  if (!err && this.error !== STREAM_DESTROYED) err = this.error;
	  if (err) stream.emit('error', err);
	  stream._duplexState |= DESTROYED;
	  stream.emit('close');

	  const rs = stream._readableState;
	  const ws = stream._writableState;

	  if (rs !== null && rs.pipeline !== null) rs.pipeline.done(stream, err);

	  if (ws !== null) {
	    while (ws.drains !== null && ws.drains.length > 0) ws.drains.shift().resolve(false);
	    if (ws.pipeline !== null) ws.pipeline.done(stream, err);
	  }
	}

	function afterWrite (err) {
	  const stream = this.stream;

	  if (err) stream.destroy(err);
	  stream._duplexState &= WRITE_NOT_ACTIVE;

	  if (this.drains !== null) tickDrains(this.drains);

	  if ((stream._duplexState & WRITE_DRAIN_STATUS) === WRITE_UNDRAINED) {
	    stream._duplexState &= WRITE_DRAINED;
	    if ((stream._duplexState & WRITE_EMIT_DRAIN) === WRITE_EMIT_DRAIN) {
	      stream.emit('drain');
	    }
	  }

	  this.updateCallback();
	}

	function afterRead (err) {
	  if (err) this.stream.destroy(err);
	  this.stream._duplexState &= READ_NOT_ACTIVE;
	  if (this.readAhead === false && (this.stream._duplexState & READ_RESUMED) === 0) this.stream._duplexState &= READ_NO_READ_AHEAD;
	  this.updateCallback();
	}

	function updateReadNT () {
	  if ((this.stream._duplexState & READ_UPDATING) === 0) {
	    this.stream._duplexState &= READ_NOT_NEXT_TICK;
	    this.update();
	  }
	}

	function updateWriteNT () {
	  if ((this.stream._duplexState & WRITE_UPDATING) === 0) {
	    this.stream._duplexState &= WRITE_NOT_NEXT_TICK;
	    this.update();
	  }
	}

	function tickDrains (drains) {
	  for (let i = 0; i < drains.length; i++) {
	    // drains.writes are monotonic, so if one is 0 its always the first one
	    if (--drains[i].writes === 0) {
	      drains.shift().resolve(true);
	      i--;
	    }
	  }
	}

	function afterOpen (err) {
	  const stream = this.stream;

	  if (err) stream.destroy(err);

	  if ((stream._duplexState & DESTROYING) === 0) {
	    if ((stream._duplexState & READ_PRIMARY_STATUS) === 0) stream._duplexState |= READ_PRIMARY;
	    if ((stream._duplexState & WRITE_PRIMARY_STATUS) === 0) stream._duplexState |= WRITE_PRIMARY;
	    stream.emit('open');
	  }

	  stream._duplexState &= NOT_ACTIVE;

	  if (stream._writableState !== null) {
	    stream._writableState.updateCallback();
	  }

	  if (stream._readableState !== null) {
	    stream._readableState.updateCallback();
	  }
	}

	function afterTransform (err, data) {
	  if (data !== undefined && data !== null) this.push(data);
	  this._writableState.afterWrite(err);
	}

	function newListener (name) {
	  if (this._readableState !== null) {
	    if (name === 'data') {
	      this._duplexState |= (READ_EMIT_DATA | READ_RESUMED_READ_AHEAD);
	      this._readableState.updateNextTick();
	    }
	    if (name === 'readable') {
	      this._duplexState |= READ_EMIT_READABLE;
	      this._readableState.updateNextTick();
	    }
	  }

	  if (this._writableState !== null) {
	    if (name === 'drain') {
	      this._duplexState |= WRITE_EMIT_DRAIN;
	      this._writableState.updateNextTick();
	    }
	  }
	}

	class Stream extends EventEmitter {
	  constructor (opts) {
	    super();

	    this._duplexState = 0;
	    this._readableState = null;
	    this._writableState = null;

	    if (opts) {
	      if (opts.open) this._open = opts.open;
	      if (opts.destroy) this._destroy = opts.destroy;
	      if (opts.predestroy) this._predestroy = opts.predestroy;
	      if (opts.signal) {
	        opts.signal.addEventListener('abort', abort.bind(this));
	      }
	    }

	    this.on('newListener', newListener);
	  }

	  _open (cb) {
	    cb(null);
	  }

	  _destroy (cb) {
	    cb(null);
	  }

	  _predestroy () {
	    // does nothing
	  }

	  get readable () {
	    return this._readableState !== null ? true : undefined
	  }

	  get writable () {
	    return this._writableState !== null ? true : undefined
	  }

	  get destroyed () {
	    return (this._duplexState & DESTROYED) !== 0
	  }

	  get destroying () {
	    return (this._duplexState & DESTROY_STATUS) !== 0
	  }

	  destroy (err) {
	    if ((this._duplexState & DESTROY_STATUS) === 0) {
	      if (!err) err = STREAM_DESTROYED;
	      this._duplexState = (this._duplexState | DESTROYING) & NON_PRIMARY;

	      if (this._readableState !== null) {
	        this._readableState.highWaterMark = 0;
	        this._readableState.error = err;
	      }
	      if (this._writableState !== null) {
	        this._writableState.highWaterMark = 0;
	        this._writableState.error = err;
	      }

	      this._duplexState |= PREDESTROYING;
	      this._predestroy();
	      this._duplexState &= NOT_PREDESTROYING;

	      if (this._readableState !== null) this._readableState.updateNextTick();
	      if (this._writableState !== null) this._writableState.updateNextTick();
	    }
	  }
	}

	class Readable extends Stream {
	  constructor (opts) {
	    super(opts);

	    this._duplexState |= OPENING | WRITE_DONE | READ_READ_AHEAD;
	    this._readableState = new ReadableState(this, opts);

	    if (opts) {
	      if (this._readableState.readAhead === false) this._duplexState &= READ_NO_READ_AHEAD;
	      if (opts.read) this._read = opts.read;
	      if (opts.eagerOpen) this._readableState.updateNextTick();
	      if (opts.encoding) this.setEncoding(opts.encoding);
	    }
	  }

	  setEncoding (encoding) {
	    const dec = new TextDecoder(encoding);
	    const map = this._readableState.map || echo;
	    this._readableState.map = mapOrSkip;
	    return this

	    function mapOrSkip (data) {
	      const next = dec.push(data);
	      return next === '' && (data.byteLength !== 0 || dec.remaining > 0) ? null : map(next)
	    }
	  }

	  _read (cb) {
	    cb(null);
	  }

	  pipe (dest, cb) {
	    this._readableState.updateNextTick();
	    this._readableState.pipe(dest, cb);
	    return dest
	  }

	  read () {
	    this._readableState.updateNextTick();
	    return this._readableState.read()
	  }

	  push (data) {
	    this._readableState.updateNextTickIfOpen();
	    return this._readableState.push(data)
	  }

	  unshift (data) {
	    this._readableState.updateNextTickIfOpen();
	    return this._readableState.unshift(data)
	  }

	  resume () {
	    this._duplexState |= READ_RESUMED_READ_AHEAD;
	    this._readableState.updateNextTick();
	    return this
	  }

	  pause () {
	    this._duplexState &= (this._readableState.readAhead === false ? READ_PAUSED_NO_READ_AHEAD : READ_PAUSED);
	    return this
	  }

	  static _fromAsyncIterator (ite, opts) {
	    let destroy;

	    const rs = new Readable({
	      ...opts,
	      read (cb) {
	        ite.next().then(push).then(cb.bind(null, null)).catch(cb);
	      },
	      predestroy () {
	        destroy = ite.return();
	      },
	      destroy (cb) {
	        if (!destroy) return cb(null)
	        destroy.then(cb.bind(null, null)).catch(cb);
	      }
	    });

	    return rs

	    function push (data) {
	      if (data.done) rs.push(null);
	      else rs.push(data.value);
	    }
	  }

	  static from (data, opts) {
	    if (isReadStreamx(data)) return data
	    if (data[asyncIterator]) return this._fromAsyncIterator(data[asyncIterator](), opts)
	    if (!Array.isArray(data)) data = data === undefined ? [] : [data];

	    let i = 0;
	    return new Readable({
	      ...opts,
	      read (cb) {
	        this.push(i === data.length ? null : data[i++]);
	        cb(null);
	      }
	    })
	  }

	  static isBackpressured (rs) {
	    return (rs._duplexState & READ_BACKPRESSURE_STATUS) !== 0 || rs._readableState.buffered >= rs._readableState.highWaterMark
	  }

	  static isPaused (rs) {
	    return (rs._duplexState & READ_RESUMED) === 0
	  }

	  [asyncIterator] () {
	    const stream = this;

	    let error = null;
	    let promiseResolve = null;
	    let promiseReject = null;

	    this.on('error', (err) => { error = err; });
	    this.on('readable', onreadable);
	    this.on('close', onclose);

	    return {
	      [asyncIterator] () {
	        return this
	      },
	      next () {
	        return new Promise(function (resolve, reject) {
	          promiseResolve = resolve;
	          promiseReject = reject;
	          const data = stream.read();
	          if (data !== null) ondata(data);
	          else if ((stream._duplexState & DESTROYED) !== 0) ondata(null);
	        })
	      },
	      return () {
	        return destroy(null)
	      },
	      throw (err) {
	        return destroy(err)
	      }
	    }

	    function onreadable () {
	      if (promiseResolve !== null) ondata(stream.read());
	    }

	    function onclose () {
	      if (promiseResolve !== null) ondata(null);
	    }

	    function ondata (data) {
	      if (promiseReject === null) return
	      if (error) promiseReject(error);
	      else if (data === null && (stream._duplexState & READ_DONE) === 0) promiseReject(STREAM_DESTROYED);
	      else promiseResolve({ value: data, done: data === null });
	      promiseReject = promiseResolve = null;
	    }

	    function destroy (err) {
	      stream.destroy(err);
	      return new Promise((resolve, reject) => {
	        if (stream._duplexState & DESTROYED) return resolve({ value: undefined, done: true })
	        stream.once('close', function () {
	          if (err) reject(err);
	          else resolve({ value: undefined, done: true });
	        });
	      })
	    }
	  }
	}

	class Writable extends Stream {
	  constructor (opts) {
	    super(opts);

	    this._duplexState |= OPENING | READ_DONE;
	    this._writableState = new WritableState(this, opts);

	    if (opts) {
	      if (opts.writev) this._writev = opts.writev;
	      if (opts.write) this._write = opts.write;
	      if (opts.final) this._final = opts.final;
	      if (opts.eagerOpen) this._writableState.updateNextTick();
	    }
	  }

	  cork () {
	    this._duplexState |= WRITE_CORKED;
	  }

	  uncork () {
	    this._duplexState &= WRITE_NOT_CORKED;
	    this._writableState.updateNextTick();
	  }

	  _writev (batch, cb) {
	    cb(null);
	  }

	  _write (data, cb) {
	    this._writableState.autoBatch(data, cb);
	  }

	  _final (cb) {
	    cb(null);
	  }

	  static isBackpressured (ws) {
	    return (ws._duplexState & WRITE_BACKPRESSURE_STATUS) !== 0
	  }

	  static drained (ws) {
	    if (ws.destroyed) return Promise.resolve(false)
	    const state = ws._writableState;
	    const pending = (isWritev(ws) ? Math.min(1, state.queue.length) : state.queue.length);
	    const writes = pending + ((ws._duplexState & WRITE_WRITING) ? 1 : 0);
	    if (writes === 0) return Promise.resolve(true)
	    if (state.drains === null) state.drains = [];
	    return new Promise((resolve) => {
	      state.drains.push({ writes, resolve });
	    })
	  }

	  write (data) {
	    this._writableState.updateNextTick();
	    return this._writableState.push(data)
	  }

	  end (data) {
	    this._writableState.updateNextTick();
	    this._writableState.end(data);
	    return this
	  }
	}

	class Duplex extends Readable { // and Writable
	  constructor (opts) {
	    super(opts);

	    this._duplexState = OPENING | (this._duplexState & READ_READ_AHEAD);
	    this._writableState = new WritableState(this, opts);

	    if (opts) {
	      if (opts.writev) this._writev = opts.writev;
	      if (opts.write) this._write = opts.write;
	      if (opts.final) this._final = opts.final;
	    }
	  }

	  cork () {
	    this._duplexState |= WRITE_CORKED;
	  }

	  uncork () {
	    this._duplexState &= WRITE_NOT_CORKED;
	    this._writableState.updateNextTick();
	  }

	  _writev (batch, cb) {
	    cb(null);
	  }

	  _write (data, cb) {
	    this._writableState.autoBatch(data, cb);
	  }

	  _final (cb) {
	    cb(null);
	  }

	  write (data) {
	    this._writableState.updateNextTick();
	    return this._writableState.push(data)
	  }

	  end (data) {
	    this._writableState.updateNextTick();
	    this._writableState.end(data);
	    return this
	  }
	}

	class Transform extends Duplex {
	  constructor (opts) {
	    super(opts);
	    this._transformState = new TransformState(this);

	    if (opts) {
	      if (opts.transform) this._transform = opts.transform;
	      if (opts.flush) this._flush = opts.flush;
	    }
	  }

	  _write (data, cb) {
	    if (this._readableState.buffered >= this._readableState.highWaterMark) {
	      this._transformState.data = data;
	    } else {
	      this._transform(data, this._transformState.afterTransform);
	    }
	  }

	  _read (cb) {
	    if (this._transformState.data !== null) {
	      const data = this._transformState.data;
	      this._transformState.data = null;
	      cb(null);
	      this._transform(data, this._transformState.afterTransform);
	    } else {
	      cb(null);
	    }
	  }

	  destroy (err) {
	    super.destroy(err);
	    if (this._transformState.data !== null) {
	      this._transformState.data = null;
	      this._transformState.afterTransform();
	    }
	  }

	  _transform (data, cb) {
	    cb(null, data);
	  }

	  _flush (cb) {
	    cb(null);
	  }

	  _final (cb) {
	    this._transformState.afterFinal = cb;
	    this._flush(transformAfterFlush.bind(this));
	  }
	}

	class PassThrough extends Transform {}

	function transformAfterFlush (err, data) {
	  const cb = this._transformState.afterFinal;
	  if (err) return cb(err)
	  if (data !== null && data !== undefined) this.push(data);
	  this.push(null);
	  cb(null);
	}

	function pipelinePromise (...streams) {
	  return new Promise((resolve, reject) => {
	    return pipeline(...streams, (err) => {
	      if (err) return reject(err)
	      resolve();
	    })
	  })
	}

	function pipeline (stream, ...streams) {
	  const all = Array.isArray(stream) ? [...stream, ...streams] : [stream, ...streams];
	  const done = (all.length && typeof all[all.length - 1] === 'function') ? all.pop() : null;

	  if (all.length < 2) throw new Error('Pipeline requires at least 2 streams')

	  let src = all[0];
	  let dest = null;
	  let error = null;

	  for (let i = 1; i < all.length; i++) {
	    dest = all[i];

	    if (isStreamx(src)) {
	      src.pipe(dest, onerror);
	    } else {
	      errorHandle(src, true, i > 1, onerror);
	      src.pipe(dest);
	    }

	    src = dest;
	  }

	  if (done) {
	    let fin = false;

	    const autoDestroy = isStreamx(dest) || !!(dest._writableState && dest._writableState.autoDestroy);

	    dest.on('error', (err) => {
	      if (error === null) error = err;
	    });

	    dest.on('finish', () => {
	      fin = true;
	      if (!autoDestroy) done(error);
	    });

	    if (autoDestroy) {
	      dest.on('close', () => done(error || (fin ? null : PREMATURE_CLOSE)));
	    }
	  }

	  return dest

	  function errorHandle (s, rd, wr, onerror) {
	    s.on('error', onerror);
	    s.on('close', onclose);

	    function onclose () {
	      if (s._readableState && !s._readableState.ended) return onerror(PREMATURE_CLOSE)
	      if (wr && s._writableState && !s._writableState.ended) return onerror(PREMATURE_CLOSE)
	    }
	  }

	  function onerror (err) {
	    if (!err || error) return
	    error = err;

	    for (const s of all) {
	      s.destroy(err);
	    }
	  }
	}

	function echo (s) {
	  return s
	}

	function isStream (stream) {
	  return !!stream._readableState || !!stream._writableState
	}

	function isStreamx (stream) {
	  return typeof stream._duplexState === 'number' && isStream(stream)
	}

	function isEnded (stream) {
	  return !!stream._readableState && stream._readableState.ended
	}

	function isFinished (stream) {
	  return !!stream._writableState && stream._writableState.ended
	}

	function getStreamError (stream, opts = {}) {
	  const err = (stream._readableState && stream._readableState.error) || (stream._writableState && stream._writableState.error);

	  // avoid implicit errors by default
	  return (!opts.all && err === STREAM_DESTROYED) ? null : err
	}

	function isReadStreamx (stream) {
	  return isStreamx(stream) && stream.readable
	}

	function isDisturbed (stream) {
	  return (stream._duplexState & OPENING) !== OPENING || (stream._duplexState & ACTIVE_OR_TICKING) !== 0
	}

	function isTypedArray (data) {
	  return typeof data === 'object' && data !== null && typeof data.byteLength === 'number'
	}

	function defaultByteLength (data) {
	  return isTypedArray(data) ? data.byteLength : 1024
	}

	function noop () {}

	function abort () {
	  this.destroy(new Error('Stream aborted.'));
	}

	function isWritev (s) {
	  return s._writev !== Writable.prototype._writev && s._writev !== Duplex.prototype._writev
	}

	streamx = {
	  pipeline,
	  pipelinePromise,
	  isStream,
	  isStreamx,
	  isEnded,
	  isFinished,
	  isDisturbed,
	  getStreamError,
	  Stream,
	  Writable,
	  Readable,
	  Duplex,
	  Transform,
	  // Export PassThrough for compatibility with Node.js core's stream module
	  PassThrough
	};
	return streamx;
}

var headers = {};

var hasRequiredHeaders;

function requireHeaders () {
	if (hasRequiredHeaders) return headers;
	hasRequiredHeaders = 1;
	const b4a = requireB4a();

	const ZEROS = '0000000000000000000';
	const SEVENS = '7777777777777777777';
	const ZERO_OFFSET = '0'.charCodeAt(0);
	const USTAR_MAGIC = b4a.from([0x75, 0x73, 0x74, 0x61, 0x72, 0x00]); // ustar\x00
	const USTAR_VER = b4a.from([ZERO_OFFSET, ZERO_OFFSET]);
	const GNU_MAGIC = b4a.from([0x75, 0x73, 0x74, 0x61, 0x72, 0x20]); // ustar\x20
	const GNU_VER = b4a.from([0x20, 0x00]);
	const MASK = 0o7777;
	const MAGIC_OFFSET = 257;
	const VERSION_OFFSET = 263;

	headers.decodeLongPath = function decodeLongPath (buf, encoding) {
	  return decodeStr(buf, 0, buf.length, encoding)
	};

	headers.encodePax = function encodePax (opts) { // TODO: encode more stuff in pax
	  let result = '';
	  if (opts.name) result += addLength(' path=' + opts.name + '\n');
	  if (opts.linkname) result += addLength(' linkpath=' + opts.linkname + '\n');
	  const pax = opts.pax;
	  if (pax) {
	    for (const key in pax) {
	      result += addLength(' ' + key + '=' + pax[key] + '\n');
	    }
	  }
	  return b4a.from(result)
	};

	headers.decodePax = function decodePax (buf) {
	  const result = {};

	  while (buf.length) {
	    let i = 0;
	    while (i < buf.length && buf[i] !== 32) i++;
	    const len = parseInt(b4a.toString(buf.subarray(0, i)), 10);
	    if (!len) return result

	    const b = b4a.toString(buf.subarray(i + 1, len - 1));
	    const keyIndex = b.indexOf('=');
	    if (keyIndex === -1) return result
	    result[b.slice(0, keyIndex)] = b.slice(keyIndex + 1);

	    buf = buf.subarray(len);
	  }

	  return result
	};

	headers.encode = function encode (opts) {
	  const buf = b4a.alloc(512);
	  let name = opts.name;
	  let prefix = '';

	  if (opts.typeflag === 5 && name[name.length - 1] !== '/') name += '/';
	  if (b4a.byteLength(name) !== name.length) return null // utf-8

	  while (b4a.byteLength(name) > 100) {
	    const i = name.indexOf('/');
	    if (i === -1) return null
	    prefix += prefix ? '/' + name.slice(0, i) : name.slice(0, i);
	    name = name.slice(i + 1);
	  }

	  if (b4a.byteLength(name) > 100 || b4a.byteLength(prefix) > 155) return null
	  if (opts.linkname && b4a.byteLength(opts.linkname) > 100) return null

	  b4a.write(buf, name);
	  b4a.write(buf, encodeOct(opts.mode & MASK, 6), 100);
	  b4a.write(buf, encodeOct(opts.uid, 6), 108);
	  b4a.write(buf, encodeOct(opts.gid, 6), 116);
	  encodeSize(opts.size, buf, 124);
	  b4a.write(buf, encodeOct((opts.mtime.getTime() / 1000) | 0, 11), 136);

	  buf[156] = ZERO_OFFSET + toTypeflag(opts.type);

	  if (opts.linkname) b4a.write(buf, opts.linkname, 157);

	  b4a.copy(USTAR_MAGIC, buf, MAGIC_OFFSET);
	  b4a.copy(USTAR_VER, buf, VERSION_OFFSET);
	  if (opts.uname) b4a.write(buf, opts.uname, 265);
	  if (opts.gname) b4a.write(buf, opts.gname, 297);
	  b4a.write(buf, encodeOct(opts.devmajor || 0, 6), 329);
	  b4a.write(buf, encodeOct(opts.devminor || 0, 6), 337);

	  if (prefix) b4a.write(buf, prefix, 345);

	  b4a.write(buf, encodeOct(cksum(buf), 6), 148);

	  return buf
	};

	headers.decode = function decode (buf, filenameEncoding, allowUnknownFormat) {
	  let typeflag = buf[156] === 0 ? 0 : buf[156] - ZERO_OFFSET;

	  let name = decodeStr(buf, 0, 100, filenameEncoding);
	  const mode = decodeOct(buf, 100, 8);
	  const uid = decodeOct(buf, 108, 8);
	  const gid = decodeOct(buf, 116, 8);
	  const size = decodeOct(buf, 124, 12);
	  const mtime = decodeOct(buf, 136, 12);
	  const type = toType(typeflag);
	  const linkname = buf[157] === 0 ? null : decodeStr(buf, 157, 100, filenameEncoding);
	  const uname = decodeStr(buf, 265, 32);
	  const gname = decodeStr(buf, 297, 32);
	  const devmajor = decodeOct(buf, 329, 8);
	  const devminor = decodeOct(buf, 337, 8);

	  const c = cksum(buf);

	  // checksum is still initial value if header was null.
	  if (c === 8 * 32) return null

	  // valid checksum
	  if (c !== decodeOct(buf, 148, 8)) throw new Error('Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?')

	  if (isUSTAR(buf)) {
	    // ustar (posix) format.
	    // prepend prefix, if present.
	    if (buf[345]) name = decodeStr(buf, 345, 155, filenameEncoding) + '/' + name;
	  } else if (isGNU(buf)) ; else {
	    if (!allowUnknownFormat) {
	      throw new Error('Invalid tar header: unknown format.')
	    }
	  }

	  // to support old tar versions that use trailing / to indicate dirs
	  if (typeflag === 0 && name && name[name.length - 1] === '/') typeflag = 5;

	  return {
	    name,
	    mode,
	    uid,
	    gid,
	    size,
	    mtime: new Date(1000 * mtime),
	    type,
	    linkname,
	    uname,
	    gname,
	    devmajor,
	    devminor,
	    pax: null
	  }
	};

	function isUSTAR (buf) {
	  return b4a.equals(USTAR_MAGIC, buf.subarray(MAGIC_OFFSET, MAGIC_OFFSET + 6))
	}

	function isGNU (buf) {
	  return b4a.equals(GNU_MAGIC, buf.subarray(MAGIC_OFFSET, MAGIC_OFFSET + 6)) &&
	    b4a.equals(GNU_VER, buf.subarray(VERSION_OFFSET, VERSION_OFFSET + 2))
	}

	function clamp (index, len, defaultValue) {
	  if (typeof index !== 'number') return defaultValue
	  index = ~~index; // Coerce to integer.
	  if (index >= len) return len
	  if (index >= 0) return index
	  index += len;
	  if (index >= 0) return index
	  return 0
	}

	function toType (flag) {
	  switch (flag) {
	    case 0:
	      return 'file'
	    case 1:
	      return 'link'
	    case 2:
	      return 'symlink'
	    case 3:
	      return 'character-device'
	    case 4:
	      return 'block-device'
	    case 5:
	      return 'directory'
	    case 6:
	      return 'fifo'
	    case 7:
	      return 'contiguous-file'
	    case 72:
	      return 'pax-header'
	    case 55:
	      return 'pax-global-header'
	    case 27:
	      return 'gnu-long-link-path'
	    case 28:
	    case 30:
	      return 'gnu-long-path'
	  }

	  return null
	}

	function toTypeflag (flag) {
	  switch (flag) {
	    case 'file':
	      return 0
	    case 'link':
	      return 1
	    case 'symlink':
	      return 2
	    case 'character-device':
	      return 3
	    case 'block-device':
	      return 4
	    case 'directory':
	      return 5
	    case 'fifo':
	      return 6
	    case 'contiguous-file':
	      return 7
	    case 'pax-header':
	      return 72
	  }

	  return 0
	}

	function indexOf (block, num, offset, end) {
	  for (; offset < end; offset++) {
	    if (block[offset] === num) return offset
	  }
	  return end
	}

	function cksum (block) {
	  let sum = 8 * 32;
	  for (let i = 0; i < 148; i++) sum += block[i];
	  for (let j = 156; j < 512; j++) sum += block[j];
	  return sum
	}

	function encodeOct (val, n) {
	  val = val.toString(8);
	  if (val.length > n) return SEVENS.slice(0, n) + ' '
	  return ZEROS.slice(0, n - val.length) + val + ' '
	}

	function encodeSizeBin (num, buf, off) {
	  buf[off] = 0x80;
	  for (let i = 11; i > 0; i--) {
	    buf[off + i] = num & 0xff;
	    num = Math.floor(num / 0x100);
	  }
	}

	function encodeSize (num, buf, off) {
	  if (num.toString(8).length > 11) {
	    encodeSizeBin(num, buf, off);
	  } else {
	    b4a.write(buf, encodeOct(num, 11), off);
	  }
	}

	/* Copied from the node-tar repo and modified to meet
	 * tar-stream coding standard.
	 *
	 * Source: https://github.com/npm/node-tar/blob/51b6627a1f357d2eb433e7378e5f05e83b7aa6cd/lib/header.js#L349
	 */
	function parse256 (buf) {
	  // first byte MUST be either 80 or FF
	  // 80 for positive, FF for 2's comp
	  let positive;
	  if (buf[0] === 0x80) positive = true;
	  else if (buf[0] === 0xFF) positive = false;
	  else return null

	  // build up a base-256 tuple from the least sig to the highest
	  const tuple = [];
	  let i;
	  for (i = buf.length - 1; i > 0; i--) {
	    const byte = buf[i];
	    if (positive) tuple.push(byte);
	    else tuple.push(0xFF - byte);
	  }

	  let sum = 0;
	  const l = tuple.length;
	  for (i = 0; i < l; i++) {
	    sum += tuple[i] * Math.pow(256, i);
	  }

	  return positive ? sum : -1 * sum
	}

	function decodeOct (val, offset, length) {
	  val = val.subarray(offset, offset + length);
	  offset = 0;

	  // If prefixed with 0x80 then parse as a base-256 integer
	  if (val[offset] & 0x80) {
	    return parse256(val)
	  } else {
	    // Older versions of tar can prefix with spaces
	    while (offset < val.length && val[offset] === 32) offset++;
	    const end = clamp(indexOf(val, 32, offset, val.length), val.length, val.length);
	    while (offset < end && val[offset] === 0) offset++;
	    if (end === offset) return 0
	    return parseInt(b4a.toString(val.subarray(offset, end)), 8)
	  }
	}

	function decodeStr (val, offset, length, encoding) {
	  return b4a.toString(val.subarray(offset, indexOf(val, 0, offset, offset + length)), encoding)
	}

	function addLength (str) {
	  const len = b4a.byteLength(str);
	  let digits = Math.floor(Math.log(len) / Math.log(10)) + 1;
	  if (len + digits >= Math.pow(10, digits)) digits++;

	  return (len + digits) + str
	}
	return headers;
}

var extract;
var hasRequiredExtract$1;

function requireExtract$1 () {
	if (hasRequiredExtract$1) return extract;
	hasRequiredExtract$1 = 1;
	const { Writable, Readable, getStreamError } = requireStreamx();
	const FIFO = requireFastFifo();
	const b4a = requireB4a();
	const headers = requireHeaders();

	const EMPTY = b4a.alloc(0);

	class BufferList {
	  constructor () {
	    this.buffered = 0;
	    this.shifted = 0;
	    this.queue = new FIFO();

	    this._offset = 0;
	  }

	  push (buffer) {
	    this.buffered += buffer.byteLength;
	    this.queue.push(buffer);
	  }

	  shiftFirst (size) {
	    return this._buffered === 0 ? null : this._next(size)
	  }

	  shift (size) {
	    if (size > this.buffered) return null
	    if (size === 0) return EMPTY

	    let chunk = this._next(size);

	    if (size === chunk.byteLength) return chunk // likely case

	    const chunks = [chunk];

	    while ((size -= chunk.byteLength) > 0) {
	      chunk = this._next(size);
	      chunks.push(chunk);
	    }

	    return b4a.concat(chunks)
	  }

	  _next (size) {
	    const buf = this.queue.peek();
	    const rem = buf.byteLength - this._offset;

	    if (size >= rem) {
	      const sub = this._offset ? buf.subarray(this._offset, buf.byteLength) : buf;
	      this.queue.shift();
	      this._offset = 0;
	      this.buffered -= rem;
	      this.shifted += rem;
	      return sub
	    }

	    this.buffered -= size;
	    this.shifted += size;

	    return buf.subarray(this._offset, (this._offset += size))
	  }
	}

	class Source extends Readable {
	  constructor (self, header, offset) {
	    super();

	    this.header = header;
	    this.offset = offset;

	    this._parent = self;
	  }

	  _read (cb) {
	    if (this.header.size === 0) {
	      this.push(null);
	    }
	    if (this._parent._stream === this) {
	      this._parent._update();
	    }
	    cb(null);
	  }

	  _predestroy () {
	    this._parent.destroy(getStreamError(this));
	  }

	  _detach () {
	    if (this._parent._stream === this) {
	      this._parent._stream = null;
	      this._parent._missing = overflow(this.header.size);
	      this._parent._update();
	    }
	  }

	  _destroy (cb) {
	    this._detach();
	    cb(null);
	  }
	}

	class Extract extends Writable {
	  constructor (opts) {
	    super(opts);

	    if (!opts) opts = {};

	    this._buffer = new BufferList();
	    this._offset = 0;
	    this._header = null;
	    this._stream = null;
	    this._missing = 0;
	    this._longHeader = false;
	    this._callback = noop;
	    this._locked = false;
	    this._finished = false;
	    this._pax = null;
	    this._paxGlobal = null;
	    this._gnuLongPath = null;
	    this._gnuLongLinkPath = null;
	    this._filenameEncoding = opts.filenameEncoding || 'utf-8';
	    this._allowUnknownFormat = !!opts.allowUnknownFormat;
	    this._unlockBound = this._unlock.bind(this);
	  }

	  _unlock (err) {
	    this._locked = false;

	    if (err) {
	      this.destroy(err);
	      this._continueWrite(err);
	      return
	    }

	    this._update();
	  }

	  _consumeHeader () {
	    if (this._locked) return false

	    this._offset = this._buffer.shifted;

	    try {
	      this._header = headers.decode(this._buffer.shift(512), this._filenameEncoding, this._allowUnknownFormat);
	    } catch (err) {
	      this._continueWrite(err);
	      return false
	    }

	    if (!this._header) return true

	    switch (this._header.type) {
	      case 'gnu-long-path':
	      case 'gnu-long-link-path':
	      case 'pax-global-header':
	      case 'pax-header':
	        this._longHeader = true;
	        this._missing = this._header.size;
	        return true
	    }

	    this._locked = true;
	    this._applyLongHeaders();

	    if (this._header.size === 0 || this._header.type === 'directory') {
	      this.emit('entry', this._header, this._createStream(), this._unlockBound);
	      return true
	    }

	    this._stream = this._createStream();
	    this._missing = this._header.size;

	    this.emit('entry', this._header, this._stream, this._unlockBound);
	    return true
	  }

	  _applyLongHeaders () {
	    if (this._gnuLongPath) {
	      this._header.name = this._gnuLongPath;
	      this._gnuLongPath = null;
	    }

	    if (this._gnuLongLinkPath) {
	      this._header.linkname = this._gnuLongLinkPath;
	      this._gnuLongLinkPath = null;
	    }

	    if (this._pax) {
	      if (this._pax.path) this._header.name = this._pax.path;
	      if (this._pax.linkpath) this._header.linkname = this._pax.linkpath;
	      if (this._pax.size) this._header.size = parseInt(this._pax.size, 10);
	      this._header.pax = this._pax;
	      this._pax = null;
	    }
	  }

	  _decodeLongHeader (buf) {
	    switch (this._header.type) {
	      case 'gnu-long-path':
	        this._gnuLongPath = headers.decodeLongPath(buf, this._filenameEncoding);
	        break
	      case 'gnu-long-link-path':
	        this._gnuLongLinkPath = headers.decodeLongPath(buf, this._filenameEncoding);
	        break
	      case 'pax-global-header':
	        this._paxGlobal = headers.decodePax(buf);
	        break
	      case 'pax-header':
	        this._pax = this._paxGlobal === null
	          ? headers.decodePax(buf)
	          : Object.assign({}, this._paxGlobal, headers.decodePax(buf));
	        break
	    }
	  }

	  _consumeLongHeader () {
	    this._longHeader = false;
	    this._missing = overflow(this._header.size);

	    const buf = this._buffer.shift(this._header.size);

	    try {
	      this._decodeLongHeader(buf);
	    } catch (err) {
	      this._continueWrite(err);
	      return false
	    }

	    return true
	  }

	  _consumeStream () {
	    const buf = this._buffer.shiftFirst(this._missing);
	    if (buf === null) return false

	    this._missing -= buf.byteLength;
	    const drained = this._stream.push(buf);

	    if (this._missing === 0) {
	      this._stream.push(null);
	      if (drained) this._stream._detach();
	      return drained && this._locked === false
	    }

	    return drained
	  }

	  _createStream () {
	    return new Source(this, this._header, this._offset)
	  }

	  _update () {
	    while (this._buffer.buffered > 0 && !this.destroying) {
	      if (this._missing > 0) {
	        if (this._stream !== null) {
	          if (this._consumeStream() === false) return
	          continue
	        }

	        if (this._longHeader === true) {
	          if (this._missing > this._buffer.buffered) break
	          if (this._consumeLongHeader() === false) return false
	          continue
	        }

	        const ignore = this._buffer.shiftFirst(this._missing);
	        if (ignore !== null) this._missing -= ignore.byteLength;
	        continue
	      }

	      if (this._buffer.buffered < 512) break
	      if (this._stream !== null || this._consumeHeader() === false) return
	    }

	    this._continueWrite(null);
	  }

	  _continueWrite (err) {
	    const cb = this._callback;
	    this._callback = noop;
	    cb(err);
	  }

	  _write (data, cb) {
	    this._callback = cb;
	    this._buffer.push(data);
	    this._update();
	  }

	  _final (cb) {
	    this._finished = this._missing === 0 && this._buffer.buffered === 0;
	    cb(this._finished ? null : new Error('Unexpected end of data'));
	  }

	  _predestroy () {
	    this._continueWrite(null);
	  }

	  _destroy (cb) {
	    if (this._stream) this._stream.destroy(getStreamError(this));
	    cb(null);
	  }

	  [Symbol.asyncIterator] () {
	    let error = null;

	    let promiseResolve = null;
	    let promiseReject = null;

	    let entryStream = null;
	    let entryCallback = null;

	    const extract = this;

	    this.on('entry', onentry);
	    this.on('error', (err) => { error = err; });
	    this.on('close', onclose);

	    return {
	      [Symbol.asyncIterator] () {
	        return this
	      },
	      next () {
	        return new Promise(onnext)
	      },
	      return () {
	        return destroy(null)
	      },
	      throw (err) {
	        return destroy(err)
	      }
	    }

	    function consumeCallback (err) {
	      if (!entryCallback) return
	      const cb = entryCallback;
	      entryCallback = null;
	      cb(err);
	    }

	    function onnext (resolve, reject) {
	      if (error) {
	        return reject(error)
	      }

	      if (entryStream) {
	        resolve({ value: entryStream, done: false });
	        entryStream = null;
	        return
	      }

	      promiseResolve = resolve;
	      promiseReject = reject;

	      consumeCallback(null);

	      if (extract._finished && promiseResolve) {
	        promiseResolve({ value: undefined, done: true });
	        promiseResolve = promiseReject = null;
	      }
	    }

	    function onentry (header, stream, callback) {
	      entryCallback = callback;
	      stream.on('error', noop); // no way around this due to tick sillyness

	      if (promiseResolve) {
	        promiseResolve({ value: stream, done: false });
	        promiseResolve = promiseReject = null;
	      } else {
	        entryStream = stream;
	      }
	    }

	    function onclose () {
	      consumeCallback(error);
	      if (!promiseResolve) return
	      if (error) promiseReject(error);
	      else promiseResolve({ value: undefined, done: true });
	      promiseResolve = promiseReject = null;
	    }

	    function destroy (err) {
	      extract.destroy(err);
	      consumeCallback(err);
	      return new Promise((resolve, reject) => {
	        if (extract.destroyed) return resolve({ value: undefined, done: true })
	        extract.once('close', function () {
	          if (err) reject(err);
	          else resolve({ value: undefined, done: true });
	        });
	      })
	    }
	  }
	}

	extract = function extract (opts) {
	  return new Extract(opts)
	};

	function noop () {}

	function overflow (size) {
	  size &= 511;
	  return size && 512 - size
	}
	return extract;
}

var constants$4 = {exports: {}};

var hasRequiredConstants$4;

function requireConstants$4 () {
	if (hasRequiredConstants$4) return constants$4.exports;
	hasRequiredConstants$4 = 1;
	const constants = { // just for envs without fs
	  S_IFMT: 61440,
	  S_IFDIR: 16384,
	  S_IFCHR: 8192,
	  S_IFBLK: 24576,
	  S_IFIFO: 4096,
	  S_IFLNK: 40960
	};

	try {
	  constants$4.exports = require('fs').constants || constants;
	} catch {
	  constants$4.exports = constants;
	}
	return constants$4.exports;
}

var pack$1;
var hasRequiredPack$1;

function requirePack$1 () {
	if (hasRequiredPack$1) return pack$1;
	hasRequiredPack$1 = 1;
	const { Readable, Writable, getStreamError } = requireStreamx();
	const b4a = requireB4a();

	const constants = requireConstants$4();
	const headers = requireHeaders();

	const DMODE = 0o755;
	const FMODE = 0o644;

	const END_OF_TAR = b4a.alloc(1024);

	class Sink extends Writable {
	  constructor (pack, header, callback) {
	    super({ mapWritable, eagerOpen: true });

	    this.written = 0;
	    this.header = header;

	    this._callback = callback;
	    this._linkname = null;
	    this._isLinkname = header.type === 'symlink' && !header.linkname;
	    this._isVoid = header.type !== 'file' && header.type !== 'contiguous-file';
	    this._finished = false;
	    this._pack = pack;
	    this._openCallback = null;

	    if (this._pack._stream === null) this._pack._stream = this;
	    else this._pack._pending.push(this);
	  }

	  _open (cb) {
	    this._openCallback = cb;
	    if (this._pack._stream === this) this._continueOpen();
	  }

	  _continuePack (err) {
	    if (this._callback === null) return

	    const callback = this._callback;
	    this._callback = null;

	    callback(err);
	  }

	  _continueOpen () {
	    if (this._pack._stream === null) this._pack._stream = this;

	    const cb = this._openCallback;
	    this._openCallback = null;
	    if (cb === null) return

	    if (this._pack.destroying) return cb(new Error('pack stream destroyed'))
	    if (this._pack._finalized) return cb(new Error('pack stream is already finalized'))

	    this._pack._stream = this;

	    if (!this._isLinkname) {
	      this._pack._encode(this.header);
	    }

	    if (this._isVoid) {
	      this._finish();
	      this._continuePack(null);
	    }

	    cb(null);
	  }

	  _write (data, cb) {
	    if (this._isLinkname) {
	      this._linkname = this._linkname ? b4a.concat([this._linkname, data]) : data;
	      return cb(null)
	    }

	    if (this._isVoid) {
	      if (data.byteLength > 0) {
	        return cb(new Error('No body allowed for this entry'))
	      }
	      return cb()
	    }

	    this.written += data.byteLength;
	    if (this._pack.push(data)) return cb()
	    this._pack._drain = cb;
	  }

	  _finish () {
	    if (this._finished) return
	    this._finished = true;

	    if (this._isLinkname) {
	      this.header.linkname = this._linkname ? b4a.toString(this._linkname, 'utf-8') : '';
	      this._pack._encode(this.header);
	    }

	    overflow(this._pack, this.header.size);

	    this._pack._done(this);
	  }

	  _final (cb) {
	    if (this.written !== this.header.size) { // corrupting tar
	      return cb(new Error('Size mismatch'))
	    }

	    this._finish();
	    cb(null);
	  }

	  _getError () {
	    return getStreamError(this) || new Error('tar entry destroyed')
	  }

	  _predestroy () {
	    this._pack.destroy(this._getError());
	  }

	  _destroy (cb) {
	    this._pack._done(this);

	    this._continuePack(this._finished ? null : this._getError());

	    cb();
	  }
	}

	class Pack extends Readable {
	  constructor (opts) {
	    super(opts);
	    this._drain = noop;
	    this._finalized = false;
	    this._finalizing = false;
	    this._pending = [];
	    this._stream = null;
	  }

	  entry (header, buffer, callback) {
	    if (this._finalized || this.destroying) throw new Error('already finalized or destroyed')

	    if (typeof buffer === 'function') {
	      callback = buffer;
	      buffer = null;
	    }

	    if (!callback) callback = noop;

	    if (!header.size || header.type === 'symlink') header.size = 0;
	    if (!header.type) header.type = modeToType(header.mode);
	    if (!header.mode) header.mode = header.type === 'directory' ? DMODE : FMODE;
	    if (!header.uid) header.uid = 0;
	    if (!header.gid) header.gid = 0;
	    if (!header.mtime) header.mtime = new Date();

	    if (typeof buffer === 'string') buffer = b4a.from(buffer);

	    const sink = new Sink(this, header, callback);

	    if (b4a.isBuffer(buffer)) {
	      header.size = buffer.byteLength;
	      sink.write(buffer);
	      sink.end();
	      return sink
	    }

	    if (sink._isVoid) {
	      return sink
	    }

	    return sink
	  }

	  finalize () {
	    if (this._stream || this._pending.length > 0) {
	      this._finalizing = true;
	      return
	    }

	    if (this._finalized) return
	    this._finalized = true;

	    this.push(END_OF_TAR);
	    this.push(null);
	  }

	  _done (stream) {
	    if (stream !== this._stream) return

	    this._stream = null;

	    if (this._finalizing) this.finalize();
	    if (this._pending.length) this._pending.shift()._continueOpen();
	  }

	  _encode (header) {
	    if (!header.pax) {
	      const buf = headers.encode(header);
	      if (buf) {
	        this.push(buf);
	        return
	      }
	    }
	    this._encodePax(header);
	  }

	  _encodePax (header) {
	    const paxHeader = headers.encodePax({
	      name: header.name,
	      linkname: header.linkname,
	      pax: header.pax
	    });

	    const newHeader = {
	      name: 'PaxHeader',
	      mode: header.mode,
	      uid: header.uid,
	      gid: header.gid,
	      size: paxHeader.byteLength,
	      mtime: header.mtime,
	      type: 'pax-header',
	      linkname: header.linkname && 'PaxHeader',
	      uname: header.uname,
	      gname: header.gname,
	      devmajor: header.devmajor,
	      devminor: header.devminor
	    };

	    this.push(headers.encode(newHeader));
	    this.push(paxHeader);
	    overflow(this, paxHeader.byteLength);

	    newHeader.size = header.size;
	    newHeader.type = header.type;
	    this.push(headers.encode(newHeader));
	  }

	  _doDrain () {
	    const drain = this._drain;
	    this._drain = noop;
	    drain();
	  }

	  _predestroy () {
	    const err = getStreamError(this);

	    if (this._stream) this._stream.destroy(err);

	    while (this._pending.length) {
	      const stream = this._pending.shift();
	      stream.destroy(err);
	      stream._continueOpen();
	    }

	    this._doDrain();
	  }

	  _read (cb) {
	    this._doDrain();
	    cb();
	  }
	}

	pack$1 = function pack (opts) {
	  return new Pack(opts)
	};

	function modeToType (mode) {
	  switch (mode & constants.S_IFMT) {
	    case constants.S_IFBLK: return 'block-device'
	    case constants.S_IFCHR: return 'character-device'
	    case constants.S_IFDIR: return 'directory'
	    case constants.S_IFIFO: return 'fifo'
	    case constants.S_IFLNK: return 'symlink'
	  }

	  return 'file'
	}

	function noop () {}

	function overflow (self, size) {
	  size &= 511;
	  if (size) self.push(END_OF_TAR.subarray(0, 512 - size));
	}

	function mapWritable (buf) {
	  return b4a.isBuffer(buf) ? buf : b4a.from(buf)
	}
	return pack$1;
}

var hasRequiredTarStream;

function requireTarStream () {
	if (hasRequiredTarStream) return tarStream;
	hasRequiredTarStream = 1;
	tarStream.extract = requireExtract$1();
	tarStream.pack = requirePack$1();
	return tarStream;
}

/**
 * TAR Format Plugin
 *
 * @module plugins/tar
 * @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
 * @copyright (c) 2012-2014 Chris Talkington, contributors.
 */

var tar$1;
var hasRequiredTar$1;

function requireTar$1 () {
	if (hasRequiredTar$1) return tar$1;
	hasRequiredTar$1 = 1;
	var zlib = require$$0$7;

	var engine = requireTarStream();
	var util = requireArchiverUtils();

	/**
	 * @constructor
	 * @param {TarOptions} options
	 */
	var Tar = function(options) {
	  if (!(this instanceof Tar)) {
	    return new Tar(options);
	  }

	  options = this.options = util.defaults(options, {
	    gzip: false
	  });

	  if (typeof options.gzipOptions !== 'object') {
	    options.gzipOptions = {};
	  }

	  this.supports = {
	    directory: true,
	    symlink: true
	  };

	  this.engine = engine.pack(options);
	  this.compressor = false;

	  if (options.gzip) {
	    this.compressor = zlib.createGzip(options.gzipOptions);
	    this.compressor.on('error', this._onCompressorError.bind(this));
	  }
	};

	/**
	 * [_onCompressorError description]
	 *
	 * @private
	 * @param  {Error} err
	 * @return void
	 */
	Tar.prototype._onCompressorError = function(err) {
	  this.engine.emit('error', err);
	};

	/**
	 * [append description]
	 *
	 * @param  {(Buffer|Stream)} source
	 * @param  {TarEntryData} data
	 * @param  {Function} callback
	 * @return void
	 */
	Tar.prototype.append = function(source, data, callback) {
	  var self = this;

	  data.mtime = data.date;

	  function append(err, sourceBuffer) {
	    if (err) {
	      callback(err);
	      return;
	    }

	    self.engine.entry(data, sourceBuffer, function(err) {
	      callback(err, data);
	    });
	  }

	  if (data.sourceType === 'buffer') {
	    append(null, source);
	  } else if (data.sourceType === 'stream' && data.stats) {
	    data.size = data.stats.size;

	    var entry = self.engine.entry(data, function(err) {
	      callback(err, data);
	    });

	    source.pipe(entry);
	  } else if (data.sourceType === 'stream') {
	    util.collectStream(source, append);
	  }
	};

	/**
	 * [finalize description]
	 *
	 * @return void
	 */
	Tar.prototype.finalize = function() {
	  this.engine.finalize();
	};

	/**
	 * [on description]
	 *
	 * @return this.engine
	 */
	Tar.prototype.on = function() {
	  return this.engine.on.apply(this.engine, arguments);
	};

	/**
	 * [pipe description]
	 *
	 * @param  {String} destination
	 * @param  {Object} options
	 * @return this.engine
	 */
	Tar.prototype.pipe = function(destination, options) {
	  if (this.compressor) {
	    return this.engine.pipe.apply(this.engine, [this.compressor]).pipe(destination, options);
	  } else {
	    return this.engine.pipe.apply(this.engine, arguments);
	  }
	};

	/**
	 * [unpipe description]
	 *
	 * @return this.engine
	 */
	Tar.prototype.unpipe = function() {
	  if (this.compressor) {
	    return this.compressor.unpipe.apply(this.compressor, arguments);
	  } else {
	    return this.engine.unpipe.apply(this.engine, arguments);
	  }
	};

	tar$1 = Tar;

	/**
	 * @typedef {Object} TarOptions
	 * @global
	 * @property {Boolean} [gzip=false] Compress the tar archive using gzip.
	 * @property {Object} [gzipOptions] Passed to [zlib]{@link https://nodejs.org/api/zlib.html#zlib_class_options}
	 * to control compression.
	 * @property {*} [*] See [tar-stream]{@link https://github.com/mafintosh/tar-stream} documentation for additional properties.
	 */

	/**
	 * @typedef {Object} TarEntryData
	 * @global
	 * @property {String} name Sets the entry name including internal path.
	 * @property {(String|Date)} [date=NOW()] Sets the entry date.
	 * @property {Number} [mode=D:0755/F:0644] Sets the entry permissions.
	 * @property {String} [prefix] Sets a path prefix for the entry name. Useful
	 * when working with methods like `directory` or `glob`.
	 * @property {fs.Stats} [stats] Sets the fs stat data for this entry allowing
	 * for reduction of fs stat calls when stat data is already known.
	 */

	/**
	 * TarStream Module
	 * @external TarStream
	 * @see {@link https://github.com/mafintosh/tar-stream}
	 */
	return tar$1;
}

var bufferCrc32;
var hasRequiredBufferCrc32;

function requireBufferCrc32 () {
	if (hasRequiredBufferCrc32) return bufferCrc32;
	hasRequiredBufferCrc32 = 1;
	var Buffer = require$$0$6.Buffer;

	var CRC_TABLE = [
	  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
	  0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
	  0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
	  0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
	  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
	  0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
	  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
	  0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
	  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
	  0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
	  0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
	  0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
	  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
	  0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
	  0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
	  0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
	  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
	  0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
	  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
	  0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
	  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
	  0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
	  0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
	  0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
	  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
	  0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
	  0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
	  0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
	  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
	  0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
	  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
	  0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
	  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
	  0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
	  0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
	  0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
	  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
	  0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
	  0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
	  0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
	  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
	  0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
	  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
	  0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
	  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
	  0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
	  0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
	  0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
	  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
	  0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
	  0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
	  0x2d02ef8d
	];

	if (typeof Int32Array !== 'undefined') {
	  CRC_TABLE = new Int32Array(CRC_TABLE);
	}

	function ensureBuffer(input) {
	  if (Buffer.isBuffer(input)) {
	    return input;
	  }

	  var hasNewBufferAPI =
	      typeof Buffer.alloc === "function" &&
	      typeof Buffer.from === "function";

	  if (typeof input === "number") {
	    return hasNewBufferAPI ? Buffer.alloc(input) : new Buffer(input);
	  }
	  else if (typeof input === "string") {
	    return hasNewBufferAPI ? Buffer.from(input) : new Buffer(input);
	  }
	  else {
	    throw new Error("input must be buffer, number, or string, received " +
	                    typeof input);
	  }
	}

	function bufferizeInt(num) {
	  var tmp = ensureBuffer(4);
	  tmp.writeInt32BE(num, 0);
	  return tmp;
	}

	function _crc32(buf, previous) {
	  buf = ensureBuffer(buf);
	  if (Buffer.isBuffer(previous)) {
	    previous = previous.readUInt32BE(0);
	  }
	  var crc = ~~previous ^ -1;
	  for (var n = 0; n < buf.length; n++) {
	    crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8);
	  }
	  return (crc ^ -1);
	}

	function crc32() {
	  return bufferizeInt(_crc32.apply(null, arguments));
	}
	crc32.signed = function () {
	  return _crc32.apply(null, arguments);
	};
	crc32.unsigned = function () {
	  return _crc32.apply(null, arguments) >>> 0;
	};

	bufferCrc32 = crc32;
	return bufferCrc32;
}

/**
 * JSON Format Plugin
 *
 * @module plugins/json
 * @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
 * @copyright (c) 2012-2014 Chris Talkington, contributors.
 */

var json;
var hasRequiredJson;

function requireJson () {
	if (hasRequiredJson) return json;
	hasRequiredJson = 1;
	var inherits = require$$0$5.inherits;
	var Transform = requireReadable().Transform;

	var crc32 = requireBufferCrc32();
	var util = requireArchiverUtils();

	/**
	 * @constructor
	 * @param {(JsonOptions|TransformOptions)} options
	 */
	var Json = function(options) {
	  if (!(this instanceof Json)) {
	    return new Json(options);
	  }

	  options = this.options = util.defaults(options, {});

	  Transform.call(this, options);

	  this.supports = {
	    directory: true,
	    symlink: true
	  };

	  this.files = [];
	};

	inherits(Json, Transform);

	/**
	 * [_transform description]
	 *
	 * @private
	 * @param  {Buffer}   chunk
	 * @param  {String}   encoding
	 * @param  {Function} callback
	 * @return void
	 */
	Json.prototype._transform = function(chunk, encoding, callback) {
	  callback(null, chunk);
	};

	/**
	 * [_writeStringified description]
	 *
	 * @private
	 * @return void
	 */
	Json.prototype._writeStringified = function() {
	  var fileString = JSON.stringify(this.files);
	  this.write(fileString);
	};

	/**
	 * [append description]
	 *
	 * @param  {(Buffer|Stream)}   source
	 * @param  {EntryData}   data
	 * @param  {Function} callback
	 * @return void
	 */
	Json.prototype.append = function(source, data, callback) {
	  var self = this;

	  data.crc32 = 0;

	  function onend(err, sourceBuffer) {
	    if (err) {
	      callback(err);
	      return;
	    }

	    data.size = sourceBuffer.length || 0;
	    data.crc32 = crc32.unsigned(sourceBuffer);

	    self.files.push(data);

	    callback(null, data);
	  }

	  if (data.sourceType === 'buffer') {
	    onend(null, source);
	  } else if (data.sourceType === 'stream') {
	    util.collectStream(source, onend);
	  }
	};

	/**
	 * [finalize description]
	 *
	 * @return void
	 */
	Json.prototype.finalize = function() {
	  this._writeStringified();
	  this.end();
	};

	json = Json;

	/**
	 * @typedef {Object} JsonOptions
	 * @global
	 */
	return json;
}

/**
 * Archiver Vending
 *
 * @ignore
 * @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
 * @copyright (c) 2012-2014 Chris Talkington, contributors.
 */

var archiver;
var hasRequiredArchiver;

function requireArchiver () {
	if (hasRequiredArchiver) return archiver;
	hasRequiredArchiver = 1;
	var Archiver = requireCore();

	var formats = {};

	/**
	 * Dispenses a new Archiver instance.
	 *
	 * @constructor
	 * @param  {String} format The archive format to use.
	 * @param  {Object} options See [Archiver]{@link Archiver}
	 * @return {Archiver}
	 */
	var vending = function(format, options) {
	  return vending.create(format, options);
	};

	/**
	 * Creates a new Archiver instance.
	 *
	 * @param  {String} format The archive format to use.
	 * @param  {Object} options See [Archiver]{@link Archiver}
	 * @return {Archiver}
	 */
	vending.create = function(format, options) {
	  if (formats[format]) {
	    var instance = new Archiver(format, options);
	    instance.setFormat(format);
	    instance.setModule(new formats[format](options));

	    return instance;
	  } else {
	    throw new Error('create(' + format + '): format not registered');
	  }
	};

	/**
	 * Registers a format for use with archiver.
	 *
	 * @param  {String} format The name of the format.
	 * @param  {Function} module The function for archiver to interact with.
	 * @return void
	 */
	vending.registerFormat = function(format, module) {
	  if (formats[format]) {
	    throw new Error('register(' + format + '): format already registered');
	  }

	  if (typeof module !== 'function') {
	    throw new Error('register(' + format + '): format module invalid');
	  }

	  if (typeof module.prototype.append !== 'function' || typeof module.prototype.finalize !== 'function') {
	    throw new Error('register(' + format + '): format module missing methods');
	  }

	  formats[format] = module;
	};

	/**
	 * Check if the format is already registered.
	 * 
	 * @param {String} format the name of the format.
	 * @return boolean
	 */
	vending.isRegisteredFormat = function (format) {
	  if (formats[format]) {
	    return true;
	  }
	  
	  return false;
	};

	vending.registerFormat('zip', requireZip());
	vending.registerFormat('tar', requireTar$1());
	vending.registerFormat('json', requireJson());

	archiver = vending;
	return archiver;
}

var tar = {};

var highLevelOpt;
var hasRequiredHighLevelOpt;

function requireHighLevelOpt () {
	if (hasRequiredHighLevelOpt) return highLevelOpt;
	hasRequiredHighLevelOpt = 1;

	// turn tar(1) style args like `C` into the more verbose things like `cwd`

	const argmap = new Map([
	  ['C', 'cwd'],
	  ['f', 'file'],
	  ['z', 'gzip'],
	  ['P', 'preservePaths'],
	  ['U', 'unlink'],
	  ['strip-components', 'strip'],
	  ['stripComponents', 'strip'],
	  ['keep-newer', 'newer'],
	  ['keepNewer', 'newer'],
	  ['keep-newer-files', 'newer'],
	  ['keepNewerFiles', 'newer'],
	  ['k', 'keep'],
	  ['keep-existing', 'keep'],
	  ['keepExisting', 'keep'],
	  ['m', 'noMtime'],
	  ['no-mtime', 'noMtime'],
	  ['p', 'preserveOwner'],
	  ['L', 'follow'],
	  ['h', 'follow'],
	]);

	highLevelOpt = opt => opt ? Object.keys(opt).map(k => [
	  argmap.has(k) ? argmap.get(k) : k, opt[k],
	]).reduce((set, kv) => (set[kv[0]] = kv[1], set), Object.create(null)) : {};
	return highLevelOpt;
}

var minipass$1 = {};

var hasRequiredMinipass$1;

function requireMinipass$1 () {
	if (hasRequiredMinipass$1) return minipass$1;
	hasRequiredMinipass$1 = 1;
	const proc =
	  typeof process === 'object' && process
	    ? process
	    : {
	        stdout: null,
	        stderr: null,
	      };
	const EE = require$$0$1;
	const Stream = require$$0$4;
	const stringdecoder = require$$2$1;
	const SD = stringdecoder.StringDecoder;

	const EOF = Symbol('EOF');
	const MAYBE_EMIT_END = Symbol('maybeEmitEnd');
	const EMITTED_END = Symbol('emittedEnd');
	const EMITTING_END = Symbol('emittingEnd');
	const EMITTED_ERROR = Symbol('emittedError');
	const CLOSED = Symbol('closed');
	const READ = Symbol('read');
	const FLUSH = Symbol('flush');
	const FLUSHCHUNK = Symbol('flushChunk');
	const ENCODING = Symbol('encoding');
	const DECODER = Symbol('decoder');
	const FLOWING = Symbol('flowing');
	const PAUSED = Symbol('paused');
	const RESUME = Symbol('resume');
	const BUFFER = Symbol('buffer');
	const PIPES = Symbol('pipes');
	const BUFFERLENGTH = Symbol('bufferLength');
	const BUFFERPUSH = Symbol('bufferPush');
	const BUFFERSHIFT = Symbol('bufferShift');
	const OBJECTMODE = Symbol('objectMode');
	// internal event when stream is destroyed
	const DESTROYED = Symbol('destroyed');
	// internal event when stream has an error
	const ERROR = Symbol('error');
	const EMITDATA = Symbol('emitData');
	const EMITEND = Symbol('emitEnd');
	const EMITEND2 = Symbol('emitEnd2');
	const ASYNC = Symbol('async');
	const ABORT = Symbol('abort');
	const ABORTED = Symbol('aborted');
	const SIGNAL = Symbol('signal');

	const defer = fn => Promise.resolve().then(fn);

	// TODO remove when Node v8 support drops
	const doIter = commonjsGlobal._MP_NO_ITERATOR_SYMBOLS_ !== '1';
	const ASYNCITERATOR =
	  (doIter && Symbol.asyncIterator) || Symbol('asyncIterator not implemented');
	const ITERATOR =
	  (doIter && Symbol.iterator) || Symbol('iterator not implemented');

	// events that mean 'the stream is over'
	// these are treated specially, and re-emitted
	// if they are listened for after emitting.
	const isEndish = ev => ev === 'end' || ev === 'finish' || ev === 'prefinish';

	const isArrayBuffer = b =>
	  b instanceof ArrayBuffer ||
	  (typeof b === 'object' &&
	    b.constructor &&
	    b.constructor.name === 'ArrayBuffer' &&
	    b.byteLength >= 0);

	const isArrayBufferView = b => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);

	class Pipe {
	  constructor(src, dest, opts) {
	    this.src = src;
	    this.dest = dest;
	    this.opts = opts;
	    this.ondrain = () => src[RESUME]();
	    dest.on('drain', this.ondrain);
	  }
	  unpipe() {
	    this.dest.removeListener('drain', this.ondrain);
	  }
	  // istanbul ignore next - only here for the prototype
	  proxyErrors() {}
	  end() {
	    this.unpipe();
	    if (this.opts.end) this.dest.end();
	  }
	}

	class PipeProxyErrors extends Pipe {
	  unpipe() {
	    this.src.removeListener('error', this.proxyErrors);
	    super.unpipe();
	  }
	  constructor(src, dest, opts) {
	    super(src, dest, opts);
	    this.proxyErrors = er => dest.emit('error', er);
	    src.on('error', this.proxyErrors);
	  }
	}

	class Minipass extends Stream {
	  constructor(options) {
	    super();
	    this[FLOWING] = false;
	    // whether we're explicitly paused
	    this[PAUSED] = false;
	    this[PIPES] = [];
	    this[BUFFER] = [];
	    this[OBJECTMODE] = (options && options.objectMode) || false;
	    if (this[OBJECTMODE]) this[ENCODING] = null;
	    else this[ENCODING] = (options && options.encoding) || null;
	    if (this[ENCODING] === 'buffer') this[ENCODING] = null;
	    this[ASYNC] = (options && !!options.async) || false;
	    this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null;
	    this[EOF] = false;
	    this[EMITTED_END] = false;
	    this[EMITTING_END] = false;
	    this[CLOSED] = false;
	    this[EMITTED_ERROR] = null;
	    this.writable = true;
	    this.readable = true;
	    this[BUFFERLENGTH] = 0;
	    this[DESTROYED] = false;
	    if (options && options.debugExposeBuffer === true) {
	      Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] });
	    }
	    if (options && options.debugExposePipes === true) {
	      Object.defineProperty(this, 'pipes', { get: () => this[PIPES] });
	    }
	    this[SIGNAL] = options && options.signal;
	    this[ABORTED] = false;
	    if (this[SIGNAL]) {
	      this[SIGNAL].addEventListener('abort', () => this[ABORT]());
	      if (this[SIGNAL].aborted) {
	        this[ABORT]();
	      }
	    }
	  }

	  get bufferLength() {
	    return this[BUFFERLENGTH]
	  }

	  get encoding() {
	    return this[ENCODING]
	  }
	  set encoding(enc) {
	    if (this[OBJECTMODE]) throw new Error('cannot set encoding in objectMode')

	    if (
	      this[ENCODING] &&
	      enc !== this[ENCODING] &&
	      ((this[DECODER] && this[DECODER].lastNeed) || this[BUFFERLENGTH])
	    )
	      throw new Error('cannot change encoding')

	    if (this[ENCODING] !== enc) {
	      this[DECODER] = enc ? new SD(enc) : null;
	      if (this[BUFFER].length)
	        this[BUFFER] = this[BUFFER].map(chunk => this[DECODER].write(chunk));
	    }

	    this[ENCODING] = enc;
	  }

	  setEncoding(enc) {
	    this.encoding = enc;
	  }

	  get objectMode() {
	    return this[OBJECTMODE]
	  }
	  set objectMode(om) {
	    this[OBJECTMODE] = this[OBJECTMODE] || !!om;
	  }

	  get ['async']() {
	    return this[ASYNC]
	  }
	  set ['async'](a) {
	    this[ASYNC] = this[ASYNC] || !!a;
	  }

	  // drop everything and get out of the flow completely
	  [ABORT]() {
	    this[ABORTED] = true;
	    this.emit('abort', this[SIGNAL].reason);
	    this.destroy(this[SIGNAL].reason);
	  }

	  get aborted() {
	    return this[ABORTED]
	  }
	  set aborted(_) {}

	  write(chunk, encoding, cb) {
	    if (this[ABORTED]) return false
	    if (this[EOF]) throw new Error('write after end')

	    if (this[DESTROYED]) {
	      this.emit(
	        'error',
	        Object.assign(
	          new Error('Cannot call write after a stream was destroyed'),
	          { code: 'ERR_STREAM_DESTROYED' }
	        )
	      );
	      return true
	    }

	    if (typeof encoding === 'function') (cb = encoding), (encoding = 'utf8');

	    if (!encoding) encoding = 'utf8';

	    const fn = this[ASYNC] ? defer : f => f();

	    // convert array buffers and typed array views into buffers
	    // at some point in the future, we may want to do the opposite!
	    // leave strings and buffers as-is
	    // anything else switches us into object mode
	    if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
	      if (isArrayBufferView(chunk))
	        chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
	      else if (isArrayBuffer(chunk)) chunk = Buffer.from(chunk);
	      else if (typeof chunk !== 'string')
	        // use the setter so we throw if we have encoding set
	        this.objectMode = true;
	    }

	    // handle object mode up front, since it's simpler
	    // this yields better performance, fewer checks later.
	    if (this[OBJECTMODE]) {
	      /* istanbul ignore if - maybe impossible? */
	      if (this.flowing && this[BUFFERLENGTH] !== 0) this[FLUSH](true);

	      if (this.flowing) this.emit('data', chunk);
	      else this[BUFFERPUSH](chunk);

	      if (this[BUFFERLENGTH] !== 0) this.emit('readable');

	      if (cb) fn(cb);

	      return this.flowing
	    }

	    // at this point the chunk is a buffer or string
	    // don't buffer it up or send it to the decoder
	    if (!chunk.length) {
	      if (this[BUFFERLENGTH] !== 0) this.emit('readable');
	      if (cb) fn(cb);
	      return this.flowing
	    }

	    // fast-path writing strings of same encoding to a stream with
	    // an empty buffer, skipping the buffer/decoder dance
	    if (
	      typeof chunk === 'string' &&
	      // unless it is a string already ready for us to use
	      !(encoding === this[ENCODING] && !this[DECODER].lastNeed)
	    ) {
	      chunk = Buffer.from(chunk, encoding);
	    }

	    if (Buffer.isBuffer(chunk) && this[ENCODING])
	      chunk = this[DECODER].write(chunk);

	    // Note: flushing CAN potentially switch us into not-flowing mode
	    if (this.flowing && this[BUFFERLENGTH] !== 0) this[FLUSH](true);

	    if (this.flowing) this.emit('data', chunk);
	    else this[BUFFERPUSH](chunk);

	    if (this[BUFFERLENGTH] !== 0) this.emit('readable');

	    if (cb) fn(cb);

	    return this.flowing
	  }

	  read(n) {
	    if (this[DESTROYED]) return null

	    if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) {
	      this[MAYBE_EMIT_END]();
	      return null
	    }

	    if (this[OBJECTMODE]) n = null;

	    if (this[BUFFER].length > 1 && !this[OBJECTMODE]) {
	      if (this.encoding) this[BUFFER] = [this[BUFFER].join('')];
	      else this[BUFFER] = [Buffer.concat(this[BUFFER], this[BUFFERLENGTH])];
	    }

	    const ret = this[READ](n || null, this[BUFFER][0]);
	    this[MAYBE_EMIT_END]();
	    return ret
	  }

	  [READ](n, chunk) {
	    if (n === chunk.length || n === null) this[BUFFERSHIFT]();
	    else {
	      this[BUFFER][0] = chunk.slice(n);
	      chunk = chunk.slice(0, n);
	      this[BUFFERLENGTH] -= n;
	    }

	    this.emit('data', chunk);

	    if (!this[BUFFER].length && !this[EOF]) this.emit('drain');

	    return chunk
	  }

	  end(chunk, encoding, cb) {
	    if (typeof chunk === 'function') (cb = chunk), (chunk = null);
	    if (typeof encoding === 'function') (cb = encoding), (encoding = 'utf8');
	    if (chunk) this.write(chunk, encoding);
	    if (cb) this.once('end', cb);
	    this[EOF] = true;
	    this.writable = false;

	    // if we haven't written anything, then go ahead and emit,
	    // even if we're not reading.
	    // we'll re-emit if a new 'end' listener is added anyway.
	    // This makes MP more suitable to write-only use cases.
	    if (this.flowing || !this[PAUSED]) this[MAYBE_EMIT_END]();
	    return this
	  }

	  // don't let the internal resume be overwritten
	  [RESUME]() {
	    if (this[DESTROYED]) return

	    this[PAUSED] = false;
	    this[FLOWING] = true;
	    this.emit('resume');
	    if (this[BUFFER].length) this[FLUSH]();
	    else if (this[EOF]) this[MAYBE_EMIT_END]();
	    else this.emit('drain');
	  }

	  resume() {
	    return this[RESUME]()
	  }

	  pause() {
	    this[FLOWING] = false;
	    this[PAUSED] = true;
	  }

	  get destroyed() {
	    return this[DESTROYED]
	  }

	  get flowing() {
	    return this[FLOWING]
	  }

	  get paused() {
	    return this[PAUSED]
	  }

	  [BUFFERPUSH](chunk) {
	    if (this[OBJECTMODE]) this[BUFFERLENGTH] += 1;
	    else this[BUFFERLENGTH] += chunk.length;
	    this[BUFFER].push(chunk);
	  }

	  [BUFFERSHIFT]() {
	    if (this[OBJECTMODE]) this[BUFFERLENGTH] -= 1;
	    else this[BUFFERLENGTH] -= this[BUFFER][0].length;
	    return this[BUFFER].shift()
	  }

	  [FLUSH](noDrain) {
	    do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && this[BUFFER].length)

	    if (!noDrain && !this[BUFFER].length && !this[EOF]) this.emit('drain');
	  }

	  [FLUSHCHUNK](chunk) {
	    this.emit('data', chunk);
	    return this.flowing
	  }

	  pipe(dest, opts) {
	    if (this[DESTROYED]) return

	    const ended = this[EMITTED_END];
	    opts = opts || {};
	    if (dest === proc.stdout || dest === proc.stderr) opts.end = false;
	    else opts.end = opts.end !== false;
	    opts.proxyErrors = !!opts.proxyErrors;

	    // piping an ended stream ends immediately
	    if (ended) {
	      if (opts.end) dest.end();
	    } else {
	      this[PIPES].push(
	        !opts.proxyErrors
	          ? new Pipe(this, dest, opts)
	          : new PipeProxyErrors(this, dest, opts)
	      );
	      if (this[ASYNC]) defer(() => this[RESUME]());
	      else this[RESUME]();
	    }

	    return dest
	  }

	  unpipe(dest) {
	    const p = this[PIPES].find(p => p.dest === dest);
	    if (p) {
	      this[PIPES].splice(this[PIPES].indexOf(p), 1);
	      p.unpipe();
	    }
	  }

	  addListener(ev, fn) {
	    return this.on(ev, fn)
	  }

	  on(ev, fn) {
	    const ret = super.on(ev, fn);
	    if (ev === 'data' && !this[PIPES].length && !this.flowing) this[RESUME]();
	    else if (ev === 'readable' && this[BUFFERLENGTH] !== 0)
	      super.emit('readable');
	    else if (isEndish(ev) && this[EMITTED_END]) {
	      super.emit(ev);
	      this.removeAllListeners(ev);
	    } else if (ev === 'error' && this[EMITTED_ERROR]) {
	      if (this[ASYNC]) defer(() => fn.call(this, this[EMITTED_ERROR]));
	      else fn.call(this, this[EMITTED_ERROR]);
	    }
	    return ret
	  }

	  get emittedEnd() {
	    return this[EMITTED_END]
	  }

	  [MAYBE_EMIT_END]() {
	    if (
	      !this[EMITTING_END] &&
	      !this[EMITTED_END] &&
	      !this[DESTROYED] &&
	      this[BUFFER].length === 0 &&
	      this[EOF]
	    ) {
	      this[EMITTING_END] = true;
	      this.emit('end');
	      this.emit('prefinish');
	      this.emit('finish');
	      if (this[CLOSED]) this.emit('close');
	      this[EMITTING_END] = false;
	    }
	  }

	  emit(ev, data, ...extra) {
	    // error and close are only events allowed after calling destroy()
	    if (ev !== 'error' && ev !== 'close' && ev !== DESTROYED && this[DESTROYED])
	      return
	    else if (ev === 'data') {
	      return !this[OBJECTMODE] && !data
	        ? false
	        : this[ASYNC]
	        ? defer(() => this[EMITDATA](data))
	        : this[EMITDATA](data)
	    } else if (ev === 'end') {
	      return this[EMITEND]()
	    } else if (ev === 'close') {
	      this[CLOSED] = true;
	      // don't emit close before 'end' and 'finish'
	      if (!this[EMITTED_END] && !this[DESTROYED]) return
	      const ret = super.emit('close');
	      this.removeAllListeners('close');
	      return ret
	    } else if (ev === 'error') {
	      this[EMITTED_ERROR] = data;
	      super.emit(ERROR, data);
	      const ret =
	        !this[SIGNAL] || this.listeners('error').length
	          ? super.emit('error', data)
	          : false;
	      this[MAYBE_EMIT_END]();
	      return ret
	    } else if (ev === 'resume') {
	      const ret = super.emit('resume');
	      this[MAYBE_EMIT_END]();
	      return ret
	    } else if (ev === 'finish' || ev === 'prefinish') {
	      const ret = super.emit(ev);
	      this.removeAllListeners(ev);
	      return ret
	    }

	    // Some other unknown event
	    const ret = super.emit(ev, data, ...extra);
	    this[MAYBE_EMIT_END]();
	    return ret
	  }

	  [EMITDATA](data) {
	    for (const p of this[PIPES]) {
	      if (p.dest.write(data) === false) this.pause();
	    }
	    const ret = super.emit('data', data);
	    this[MAYBE_EMIT_END]();
	    return ret
	  }

	  [EMITEND]() {
	    if (this[EMITTED_END]) return

	    this[EMITTED_END] = true;
	    this.readable = false;
	    if (this[ASYNC]) defer(() => this[EMITEND2]());
	    else this[EMITEND2]();
	  }

	  [EMITEND2]() {
	    if (this[DECODER]) {
	      const data = this[DECODER].end();
	      if (data) {
	        for (const p of this[PIPES]) {
	          p.dest.write(data);
	        }
	        super.emit('data', data);
	      }
	    }

	    for (const p of this[PIPES]) {
	      p.end();
	    }
	    const ret = super.emit('end');
	    this.removeAllListeners('end');
	    return ret
	  }

	  // const all = await stream.collect()
	  collect() {
	    const buf = [];
	    if (!this[OBJECTMODE]) buf.dataLength = 0;
	    // set the promise first, in case an error is raised
	    // by triggering the flow here.
	    const p = this.promise();
	    this.on('data', c => {
	      buf.push(c);
	      if (!this[OBJECTMODE]) buf.dataLength += c.length;
	    });
	    return p.then(() => buf)
	  }

	  // const data = await stream.concat()
	  concat() {
	    return this[OBJECTMODE]
	      ? Promise.reject(new Error('cannot concat in objectMode'))
	      : this.collect().then(buf =>
	          this[OBJECTMODE]
	            ? Promise.reject(new Error('cannot concat in objectMode'))
	            : this[ENCODING]
	            ? buf.join('')
	            : Buffer.concat(buf, buf.dataLength)
	        )
	  }

	  // stream.promise().then(() => done, er => emitted error)
	  promise() {
	    return new Promise((resolve, reject) => {
	      this.on(DESTROYED, () => reject(new Error('stream destroyed')));
	      this.on('error', er => reject(er));
	      this.on('end', () => resolve());
	    })
	  }

	  // for await (let chunk of stream)
	  [ASYNCITERATOR]() {
	    let stopped = false;
	    const stop = () => {
	      this.pause();
	      stopped = true;
	      return Promise.resolve({ done: true })
	    };
	    const next = () => {
	      if (stopped) return stop()
	      const res = this.read();
	      if (res !== null) return Promise.resolve({ done: false, value: res })

	      if (this[EOF]) return stop()

	      let resolve = null;
	      let reject = null;
	      const onerr = er => {
	        this.removeListener('data', ondata);
	        this.removeListener('end', onend);
	        this.removeListener(DESTROYED, ondestroy);
	        stop();
	        reject(er);
	      };
	      const ondata = value => {
	        this.removeListener('error', onerr);
	        this.removeListener('end', onend);
	        this.removeListener(DESTROYED, ondestroy);
	        this.pause();
	        resolve({ value: value, done: !!this[EOF] });
	      };
	      const onend = () => {
	        this.removeListener('error', onerr);
	        this.removeListener('data', ondata);
	        this.removeListener(DESTROYED, ondestroy);
	        stop();
	        resolve({ done: true });
	      };
	      const ondestroy = () => onerr(new Error('stream destroyed'));
	      return new Promise((res, rej) => {
	        reject = rej;
	        resolve = res;
	        this.once(DESTROYED, ondestroy);
	        this.once('error', onerr);
	        this.once('end', onend);
	        this.once('data', ondata);
	      })
	    };

	    return {
	      next,
	      throw: stop,
	      return: stop,
	      [ASYNCITERATOR]() {
	        return this
	      },
	    }
	  }

	  // for (let chunk of stream)
	  [ITERATOR]() {
	    let stopped = false;
	    const stop = () => {
	      this.pause();
	      this.removeListener(ERROR, stop);
	      this.removeListener(DESTROYED, stop);
	      this.removeListener('end', stop);
	      stopped = true;
	      return { done: true }
	    };

	    const next = () => {
	      if (stopped) return stop()
	      const value = this.read();
	      return value === null ? stop() : { value }
	    };
	    this.once('end', stop);
	    this.once(ERROR, stop);
	    this.once(DESTROYED, stop);

	    return {
	      next,
	      throw: stop,
	      return: stop,
	      [ITERATOR]() {
	        return this
	      },
	    }
	  }

	  destroy(er) {
	    if (this[DESTROYED]) {
	      if (er) this.emit('error', er);
	      else this.emit(DESTROYED);
	      return this
	    }

	    this[DESTROYED] = true;

	    // throw away all buffered data, it's never coming out
	    this[BUFFER].length = 0;
	    this[BUFFERLENGTH] = 0;

	    if (typeof this.close === 'function' && !this[CLOSED]) this.close();

	    if (er) this.emit('error', er);
	    // if no error to emit, still reject pending promises
	    else this.emit(DESTROYED);

	    return this
	  }

	  static isStream(s) {
	    return (
	      !!s &&
	      (s instanceof Minipass ||
	        s instanceof Stream ||
	        (s instanceof EE &&
	          // readable
	          (typeof s.pipe === 'function' ||
	            // writable
	            (typeof s.write === 'function' && typeof s.end === 'function'))))
	    )
	  }
	}

	minipass$1.Minipass = Minipass;
	return minipass$1;
}

var minizlib = {};

var constants$3;
var hasRequiredConstants$3;

function requireConstants$3 () {
	if (hasRequiredConstants$3) return constants$3;
	hasRequiredConstants$3 = 1;
	// Update with any zlib constants that are added or changed in the future.
	// Node v6 didn't export this, so we just hard code the version and rely
	// on all the other hard-coded values from zlib v4736.  When node v6
	// support drops, we can just export the realZlibConstants object.
	const realZlibConstants = require$$0$7.constants ||
	  /* istanbul ignore next */ { ZLIB_VERNUM: 4736 };

	constants$3 = Object.freeze(Object.assign(Object.create(null), {
	  Z_NO_FLUSH: 0,
	  Z_PARTIAL_FLUSH: 1,
	  Z_SYNC_FLUSH: 2,
	  Z_FULL_FLUSH: 3,
	  Z_FINISH: 4,
	  Z_BLOCK: 5,
	  Z_OK: 0,
	  Z_STREAM_END: 1,
	  Z_NEED_DICT: 2,
	  Z_ERRNO: -1,
	  Z_STREAM_ERROR: -2,
	  Z_DATA_ERROR: -3,
	  Z_MEM_ERROR: -4,
	  Z_BUF_ERROR: -5,
	  Z_VERSION_ERROR: -6,
	  Z_NO_COMPRESSION: 0,
	  Z_BEST_SPEED: 1,
	  Z_BEST_COMPRESSION: 9,
	  Z_DEFAULT_COMPRESSION: -1,
	  Z_FILTERED: 1,
	  Z_HUFFMAN_ONLY: 2,
	  Z_RLE: 3,
	  Z_FIXED: 4,
	  Z_DEFAULT_STRATEGY: 0,
	  DEFLATE: 1,
	  INFLATE: 2,
	  GZIP: 3,
	  GUNZIP: 4,
	  DEFLATERAW: 5,
	  INFLATERAW: 6,
	  UNZIP: 7,
	  BROTLI_DECODE: 8,
	  BROTLI_ENCODE: 9,
	  Z_MIN_WINDOWBITS: 8,
	  Z_MAX_WINDOWBITS: 15,
	  Z_DEFAULT_WINDOWBITS: 15,
	  Z_MIN_CHUNK: 64,
	  Z_MAX_CHUNK: Infinity,
	  Z_DEFAULT_CHUNK: 16384,
	  Z_MIN_MEMLEVEL: 1,
	  Z_MAX_MEMLEVEL: 9,
	  Z_DEFAULT_MEMLEVEL: 8,
	  Z_MIN_LEVEL: -1,
	  Z_MAX_LEVEL: 9,
	  Z_DEFAULT_LEVEL: -1,
	  BROTLI_OPERATION_PROCESS: 0,
	  BROTLI_OPERATION_FLUSH: 1,
	  BROTLI_OPERATION_FINISH: 2,
	  BROTLI_OPERATION_EMIT_METADATA: 3,
	  BROTLI_MODE_GENERIC: 0,
	  BROTLI_MODE_TEXT: 1,
	  BROTLI_MODE_FONT: 2,
	  BROTLI_DEFAULT_MODE: 0,
	  BROTLI_MIN_QUALITY: 0,
	  BROTLI_MAX_QUALITY: 11,
	  BROTLI_DEFAULT_QUALITY: 11,
	  BROTLI_MIN_WINDOW_BITS: 10,
	  BROTLI_MAX_WINDOW_BITS: 24,
	  BROTLI_LARGE_MAX_WINDOW_BITS: 30,
	  BROTLI_DEFAULT_WINDOW: 22,
	  BROTLI_MIN_INPUT_BLOCK_BITS: 16,
	  BROTLI_MAX_INPUT_BLOCK_BITS: 24,
	  BROTLI_PARAM_MODE: 0,
	  BROTLI_PARAM_QUALITY: 1,
	  BROTLI_PARAM_LGWIN: 2,
	  BROTLI_PARAM_LGBLOCK: 3,
	  BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: 4,
	  BROTLI_PARAM_SIZE_HINT: 5,
	  BROTLI_PARAM_LARGE_WINDOW: 6,
	  BROTLI_PARAM_NPOSTFIX: 7,
	  BROTLI_PARAM_NDIRECT: 8,
	  BROTLI_DECODER_RESULT_ERROR: 0,
	  BROTLI_DECODER_RESULT_SUCCESS: 1,
	  BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: 2,
	  BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: 3,
	  BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: 0,
	  BROTLI_DECODER_PARAM_LARGE_WINDOW: 1,
	  BROTLI_DECODER_NO_ERROR: 0,
	  BROTLI_DECODER_SUCCESS: 1,
	  BROTLI_DECODER_NEEDS_MORE_INPUT: 2,
	  BROTLI_DECODER_NEEDS_MORE_OUTPUT: 3,
	  BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: -1,
	  BROTLI_DECODER_ERROR_FORMAT_RESERVED: -2,
	  BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: -3,
	  BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: -4,
	  BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: -5,
	  BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: -6,
	  BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: -7,
	  BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: -8,
	  BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: -9,
	  BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: -10,
	  BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: -11,
	  BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: -12,
	  BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: -13,
	  BROTLI_DECODER_ERROR_FORMAT_PADDING_1: -14,
	  BROTLI_DECODER_ERROR_FORMAT_PADDING_2: -15,
	  BROTLI_DECODER_ERROR_FORMAT_DISTANCE: -16,
	  BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: -19,
	  BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: -20,
	  BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: -21,
	  BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: -22,
	  BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: -25,
	  BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: -26,
	  BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: -27,
	  BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: -30,
	  BROTLI_DECODER_ERROR_UNREACHABLE: -31,
	}, realZlibConstants));
	return constants$3;
}

var minipass;
var hasRequiredMinipass;

function requireMinipass () {
	if (hasRequiredMinipass) return minipass;
	hasRequiredMinipass = 1;
	const proc = typeof process === 'object' && process ? process : {
	  stdout: null,
	  stderr: null,
	};
	const EE = require$$0$1;
	const Stream = require$$0$4;
	const SD = require$$2$1.StringDecoder;

	const EOF = Symbol('EOF');
	const MAYBE_EMIT_END = Symbol('maybeEmitEnd');
	const EMITTED_END = Symbol('emittedEnd');
	const EMITTING_END = Symbol('emittingEnd');
	const EMITTED_ERROR = Symbol('emittedError');
	const CLOSED = Symbol('closed');
	const READ = Symbol('read');
	const FLUSH = Symbol('flush');
	const FLUSHCHUNK = Symbol('flushChunk');
	const ENCODING = Symbol('encoding');
	const DECODER = Symbol('decoder');
	const FLOWING = Symbol('flowing');
	const PAUSED = Symbol('paused');
	const RESUME = Symbol('resume');
	const BUFFERLENGTH = Symbol('bufferLength');
	const BUFFERPUSH = Symbol('bufferPush');
	const BUFFERSHIFT = Symbol('bufferShift');
	const OBJECTMODE = Symbol('objectMode');
	const DESTROYED = Symbol('destroyed');
	const EMITDATA = Symbol('emitData');
	const EMITEND = Symbol('emitEnd');
	const EMITEND2 = Symbol('emitEnd2');
	const ASYNC = Symbol('async');

	const defer = fn => Promise.resolve().then(fn);

	// TODO remove when Node v8 support drops
	const doIter = commonjsGlobal._MP_NO_ITERATOR_SYMBOLS_  !== '1';
	const ASYNCITERATOR = doIter && Symbol.asyncIterator
	  || Symbol('asyncIterator not implemented');
	const ITERATOR = doIter && Symbol.iterator
	  || Symbol('iterator not implemented');

	// events that mean 'the stream is over'
	// these are treated specially, and re-emitted
	// if they are listened for after emitting.
	const isEndish = ev =>
	  ev === 'end' ||
	  ev === 'finish' ||
	  ev === 'prefinish';

	const isArrayBuffer = b => b instanceof ArrayBuffer ||
	  typeof b === 'object' &&
	  b.constructor &&
	  b.constructor.name === 'ArrayBuffer' &&
	  b.byteLength >= 0;

	const isArrayBufferView = b => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);

	class Pipe {
	  constructor (src, dest, opts) {
	    this.src = src;
	    this.dest = dest;
	    this.opts = opts;
	    this.ondrain = () => src[RESUME]();
	    dest.on('drain', this.ondrain);
	  }
	  unpipe () {
	    this.dest.removeListener('drain', this.ondrain);
	  }
	  // istanbul ignore next - only here for the prototype
	  proxyErrors () {}
	  end () {
	    this.unpipe();
	    if (this.opts.end)
	      this.dest.end();
	  }
	}

	class PipeProxyErrors extends Pipe {
	  unpipe () {
	    this.src.removeListener('error', this.proxyErrors);
	    super.unpipe();
	  }
	  constructor (src, dest, opts) {
	    super(src, dest, opts);
	    this.proxyErrors = er => dest.emit('error', er);
	    src.on('error', this.proxyErrors);
	  }
	}

	minipass = class Minipass extends Stream {
	  constructor (options) {
	    super();
	    this[FLOWING] = false;
	    // whether we're explicitly paused
	    this[PAUSED] = false;
	    this.pipes = [];
	    this.buffer = [];
	    this[OBJECTMODE] = options && options.objectMode || false;
	    if (this[OBJECTMODE])
	      this[ENCODING] = null;
	    else
	      this[ENCODING] = options && options.encoding || null;
	    if (this[ENCODING] === 'buffer')
	      this[ENCODING] = null;
	    this[ASYNC] = options && !!options.async || false;
	    this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null;
	    this[EOF] = false;
	    this[EMITTED_END] = false;
	    this[EMITTING_END] = false;
	    this[CLOSED] = false;
	    this[EMITTED_ERROR] = null;
	    this.writable = true;
	    this.readable = true;
	    this[BUFFERLENGTH] = 0;
	    this[DESTROYED] = false;
	  }

	  get bufferLength () { return this[BUFFERLENGTH] }

	  get encoding () { return this[ENCODING] }
	  set encoding (enc) {
	    if (this[OBJECTMODE])
	      throw new Error('cannot set encoding in objectMode')

	    if (this[ENCODING] && enc !== this[ENCODING] &&
	        (this[DECODER] && this[DECODER].lastNeed || this[BUFFERLENGTH]))
	      throw new Error('cannot change encoding')

	    if (this[ENCODING] !== enc) {
	      this[DECODER] = enc ? new SD(enc) : null;
	      if (this.buffer.length)
	        this.buffer = this.buffer.map(chunk => this[DECODER].write(chunk));
	    }

	    this[ENCODING] = enc;
	  }

	  setEncoding (enc) {
	    this.encoding = enc;
	  }

	  get objectMode () { return this[OBJECTMODE] }
	  set objectMode (om) { this[OBJECTMODE] = this[OBJECTMODE] || !!om; }

	  get ['async'] () { return this[ASYNC] }
	  set ['async'] (a) { this[ASYNC] = this[ASYNC] || !!a; }

	  write (chunk, encoding, cb) {
	    if (this[EOF])
	      throw new Error('write after end')

	    if (this[DESTROYED]) {
	      this.emit('error', Object.assign(
	        new Error('Cannot call write after a stream was destroyed'),
	        { code: 'ERR_STREAM_DESTROYED' }
	      ));
	      return true
	    }

	    if (typeof encoding === 'function')
	      cb = encoding, encoding = 'utf8';

	    if (!encoding)
	      encoding = 'utf8';

	    const fn = this[ASYNC] ? defer : f => f();

	    // convert array buffers and typed array views into buffers
	    // at some point in the future, we may want to do the opposite!
	    // leave strings and buffers as-is
	    // anything else switches us into object mode
	    if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
	      if (isArrayBufferView(chunk))
	        chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
	      else if (isArrayBuffer(chunk))
	        chunk = Buffer.from(chunk);
	      else if (typeof chunk !== 'string')
	        // use the setter so we throw if we have encoding set
	        this.objectMode = true;
	    }

	    // handle object mode up front, since it's simpler
	    // this yields better performance, fewer checks later.
	    if (this[OBJECTMODE]) {
	      /* istanbul ignore if - maybe impossible? */
	      if (this.flowing && this[BUFFERLENGTH] !== 0)
	        this[FLUSH](true);

	      if (this.flowing)
	        this.emit('data', chunk);
	      else
	        this[BUFFERPUSH](chunk);

	      if (this[BUFFERLENGTH] !== 0)
	        this.emit('readable');

	      if (cb)
	        fn(cb);

	      return this.flowing
	    }

	    // at this point the chunk is a buffer or string
	    // don't buffer it up or send it to the decoder
	    if (!chunk.length) {
	      if (this[BUFFERLENGTH] !== 0)
	        this.emit('readable');
	      if (cb)
	        fn(cb);
	      return this.flowing
	    }

	    // fast-path writing strings of same encoding to a stream with
	    // an empty buffer, skipping the buffer/decoder dance
	    if (typeof chunk === 'string' &&
	        // unless it is a string already ready for us to use
	        !(encoding === this[ENCODING] && !this[DECODER].lastNeed)) {
	      chunk = Buffer.from(chunk, encoding);
	    }

	    if (Buffer.isBuffer(chunk) && this[ENCODING])
	      chunk = this[DECODER].write(chunk);

	    // Note: flushing CAN potentially switch us into not-flowing mode
	    if (this.flowing && this[BUFFERLENGTH] !== 0)
	      this[FLUSH](true);

	    if (this.flowing)
	      this.emit('data', chunk);
	    else
	      this[BUFFERPUSH](chunk);

	    if (this[BUFFERLENGTH] !== 0)
	      this.emit('readable');

	    if (cb)
	      fn(cb);

	    return this.flowing
	  }

	  read (n) {
	    if (this[DESTROYED])
	      return null

	    if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) {
	      this[MAYBE_EMIT_END]();
	      return null
	    }

	    if (this[OBJECTMODE])
	      n = null;

	    if (this.buffer.length > 1 && !this[OBJECTMODE]) {
	      if (this.encoding)
	        this.buffer = [this.buffer.join('')];
	      else
	        this.buffer = [Buffer.concat(this.buffer, this[BUFFERLENGTH])];
	    }

	    const ret = this[READ](n || null, this.buffer[0]);
	    this[MAYBE_EMIT_END]();
	    return ret
	  }

	  [READ] (n, chunk) {
	    if (n === chunk.length || n === null)
	      this[BUFFERSHIFT]();
	    else {
	      this.buffer[0] = chunk.slice(n);
	      chunk = chunk.slice(0, n);
	      this[BUFFERLENGTH] -= n;
	    }

	    this.emit('data', chunk);

	    if (!this.buffer.length && !this[EOF])
	      this.emit('drain');

	    return chunk
	  }

	  end (chunk, encoding, cb) {
	    if (typeof chunk === 'function')
	      cb = chunk, chunk = null;
	    if (typeof encoding === 'function')
	      cb = encoding, encoding = 'utf8';
	    if (chunk)
	      this.write(chunk, encoding);
	    if (cb)
	      this.once('end', cb);
	    this[EOF] = true;
	    this.writable = false;

	    // if we haven't written anything, then go ahead and emit,
	    // even if we're not reading.
	    // we'll re-emit if a new 'end' listener is added anyway.
	    // This makes MP more suitable to write-only use cases.
	    if (this.flowing || !this[PAUSED])
	      this[MAYBE_EMIT_END]();
	    return this
	  }

	  // don't let the internal resume be overwritten
	  [RESUME] () {
	    if (this[DESTROYED])
	      return

	    this[PAUSED] = false;
	    this[FLOWING] = true;
	    this.emit('resume');
	    if (this.buffer.length)
	      this[FLUSH]();
	    else if (this[EOF])
	      this[MAYBE_EMIT_END]();
	    else
	      this.emit('drain');
	  }

	  resume () {
	    return this[RESUME]()
	  }

	  pause () {
	    this[FLOWING] = false;
	    this[PAUSED] = true;
	  }

	  get destroyed () {
	    return this[DESTROYED]
	  }

	  get flowing () {
	    return this[FLOWING]
	  }

	  get paused () {
	    return this[PAUSED]
	  }

	  [BUFFERPUSH] (chunk) {
	    if (this[OBJECTMODE])
	      this[BUFFERLENGTH] += 1;
	    else
	      this[BUFFERLENGTH] += chunk.length;
	    this.buffer.push(chunk);
	  }

	  [BUFFERSHIFT] () {
	    if (this.buffer.length) {
	      if (this[OBJECTMODE])
	        this[BUFFERLENGTH] -= 1;
	      else
	        this[BUFFERLENGTH] -= this.buffer[0].length;
	    }
	    return this.buffer.shift()
	  }

	  [FLUSH] (noDrain) {
	    do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]()))

	    if (!noDrain && !this.buffer.length && !this[EOF])
	      this.emit('drain');
	  }

	  [FLUSHCHUNK] (chunk) {
	    return chunk ? (this.emit('data', chunk), this.flowing) : false
	  }

	  pipe (dest, opts) {
	    if (this[DESTROYED])
	      return

	    const ended = this[EMITTED_END];
	    opts = opts || {};
	    if (dest === proc.stdout || dest === proc.stderr)
	      opts.end = false;
	    else
	      opts.end = opts.end !== false;
	    opts.proxyErrors = !!opts.proxyErrors;

	    // piping an ended stream ends immediately
	    if (ended) {
	      if (opts.end)
	        dest.end();
	    } else {
	      this.pipes.push(!opts.proxyErrors ? new Pipe(this, dest, opts)
	        : new PipeProxyErrors(this, dest, opts));
	      if (this[ASYNC])
	        defer(() => this[RESUME]());
	      else
	        this[RESUME]();
	    }

	    return dest
	  }

	  unpipe (dest) {
	    const p = this.pipes.find(p => p.dest === dest);
	    if (p) {
	      this.pipes.splice(this.pipes.indexOf(p), 1);
	      p.unpipe();
	    }
	  }

	  addListener (ev, fn) {
	    return this.on(ev, fn)
	  }

	  on (ev, fn) {
	    const ret = super.on(ev, fn);
	    if (ev === 'data' && !this.pipes.length && !this.flowing)
	      this[RESUME]();
	    else if (ev === 'readable' && this[BUFFERLENGTH] !== 0)
	      super.emit('readable');
	    else if (isEndish(ev) && this[EMITTED_END]) {
	      super.emit(ev);
	      this.removeAllListeners(ev);
	    } else if (ev === 'error' && this[EMITTED_ERROR]) {
	      if (this[ASYNC])
	        defer(() => fn.call(this, this[EMITTED_ERROR]));
	      else
	        fn.call(this, this[EMITTED_ERROR]);
	    }
	    return ret
	  }

	  get emittedEnd () {
	    return this[EMITTED_END]
	  }

	  [MAYBE_EMIT_END] () {
	    if (!this[EMITTING_END] &&
	        !this[EMITTED_END] &&
	        !this[DESTROYED] &&
	        this.buffer.length === 0 &&
	        this[EOF]) {
	      this[EMITTING_END] = true;
	      this.emit('end');
	      this.emit('prefinish');
	      this.emit('finish');
	      if (this[CLOSED])
	        this.emit('close');
	      this[EMITTING_END] = false;
	    }
	  }

	  emit (ev, data, ...extra) {
	    // error and close are only events allowed after calling destroy()
	    if (ev !== 'error' && ev !== 'close' && ev !== DESTROYED && this[DESTROYED])
	      return
	    else if (ev === 'data') {
	      return !data ? false
	        : this[ASYNC] ? defer(() => this[EMITDATA](data))
	        : this[EMITDATA](data)
	    } else if (ev === 'end') {
	      return this[EMITEND]()
	    } else if (ev === 'close') {
	      this[CLOSED] = true;
	      // don't emit close before 'end' and 'finish'
	      if (!this[EMITTED_END] && !this[DESTROYED])
	        return
	      const ret = super.emit('close');
	      this.removeAllListeners('close');
	      return ret
	    } else if (ev === 'error') {
	      this[EMITTED_ERROR] = data;
	      const ret = super.emit('error', data);
	      this[MAYBE_EMIT_END]();
	      return ret
	    } else if (ev === 'resume') {
	      const ret = super.emit('resume');
	      this[MAYBE_EMIT_END]();
	      return ret
	    } else if (ev === 'finish' || ev === 'prefinish') {
	      const ret = super.emit(ev);
	      this.removeAllListeners(ev);
	      return ret
	    }

	    // Some other unknown event
	    const ret = super.emit(ev, data, ...extra);
	    this[MAYBE_EMIT_END]();
	    return ret
	  }

	  [EMITDATA] (data) {
	    for (const p of this.pipes) {
	      if (p.dest.write(data) === false)
	        this.pause();
	    }
	    const ret = super.emit('data', data);
	    this[MAYBE_EMIT_END]();
	    return ret
	  }

	  [EMITEND] () {
	    if (this[EMITTED_END])
	      return

	    this[EMITTED_END] = true;
	    this.readable = false;
	    if (this[ASYNC])
	      defer(() => this[EMITEND2]());
	    else
	      this[EMITEND2]();
	  }

	  [EMITEND2] () {
	    if (this[DECODER]) {
	      const data = this[DECODER].end();
	      if (data) {
	        for (const p of this.pipes) {
	          p.dest.write(data);
	        }
	        super.emit('data', data);
	      }
	    }

	    for (const p of this.pipes) {
	      p.end();
	    }
	    const ret = super.emit('end');
	    this.removeAllListeners('end');
	    return ret
	  }

	  // const all = await stream.collect()
	  collect () {
	    const buf = [];
	    if (!this[OBJECTMODE])
	      buf.dataLength = 0;
	    // set the promise first, in case an error is raised
	    // by triggering the flow here.
	    const p = this.promise();
	    this.on('data', c => {
	      buf.push(c);
	      if (!this[OBJECTMODE])
	        buf.dataLength += c.length;
	    });
	    return p.then(() => buf)
	  }

	  // const data = await stream.concat()
	  concat () {
	    return this[OBJECTMODE]
	      ? Promise.reject(new Error('cannot concat in objectMode'))
	      : this.collect().then(buf =>
	          this[OBJECTMODE]
	            ? Promise.reject(new Error('cannot concat in objectMode'))
	            : this[ENCODING] ? buf.join('') : Buffer.concat(buf, buf.dataLength))
	  }

	  // stream.promise().then(() => done, er => emitted error)
	  promise () {
	    return new Promise((resolve, reject) => {
	      this.on(DESTROYED, () => reject(new Error('stream destroyed')));
	      this.on('error', er => reject(er));
	      this.on('end', () => resolve());
	    })
	  }

	  // for await (let chunk of stream)
	  [ASYNCITERATOR] () {
	    const next = () => {
	      const res = this.read();
	      if (res !== null)
	        return Promise.resolve({ done: false, value: res })

	      if (this[EOF])
	        return Promise.resolve({ done: true })

	      let resolve = null;
	      let reject = null;
	      const onerr = er => {
	        this.removeListener('data', ondata);
	        this.removeListener('end', onend);
	        reject(er);
	      };
	      const ondata = value => {
	        this.removeListener('error', onerr);
	        this.removeListener('end', onend);
	        this.pause();
	        resolve({ value: value, done: !!this[EOF] });
	      };
	      const onend = () => {
	        this.removeListener('error', onerr);
	        this.removeListener('data', ondata);
	        resolve({ done: true });
	      };
	      const ondestroy = () => onerr(new Error('stream destroyed'));
	      return new Promise((res, rej) => {
	        reject = rej;
	        resolve = res;
	        this.once(DESTROYED, ondestroy);
	        this.once('error', onerr);
	        this.once('end', onend);
	        this.once('data', ondata);
	      })
	    };

	    return { next }
	  }

	  // for (let chunk of stream)
	  [ITERATOR] () {
	    const next = () => {
	      const value = this.read();
	      const done = value === null;
	      return { value, done }
	    };
	    return { next }
	  }

	  destroy (er) {
	    if (this[DESTROYED]) {
	      if (er)
	        this.emit('error', er);
	      else
	        this.emit(DESTROYED);
	      return this
	    }

	    this[DESTROYED] = true;

	    // throw away all buffered data, it's never coming out
	    this.buffer.length = 0;
	    this[BUFFERLENGTH] = 0;

	    if (typeof this.close === 'function' && !this[CLOSED])
	      this.close();

	    if (er)
	      this.emit('error', er);
	    else // if no error to emit, still reject pending promises
	      this.emit(DESTROYED);

	    return this
	  }

	  static isStream (s) {
	    return !!s && (s instanceof Minipass || s instanceof Stream ||
	      s instanceof EE && (
	        typeof s.pipe === 'function' || // readable
	        (typeof s.write === 'function' && typeof s.end === 'function') // writable
	      ))
	  }
	};
	return minipass;
}

var hasRequiredMinizlib;

function requireMinizlib () {
	if (hasRequiredMinizlib) return minizlib;
	hasRequiredMinizlib = 1;

	const assert = require$$5;
	const Buffer = require$$0$6.Buffer;
	const realZlib = require$$0$7;

	const constants = minizlib.constants = requireConstants$3();
	const Minipass = requireMinipass();

	const OriginalBufferConcat = Buffer.concat;

	const _superWrite = Symbol('_superWrite');
	class ZlibError extends Error {
	  constructor (err) {
	    super('zlib: ' + err.message);
	    this.code = err.code;
	    this.errno = err.errno;
	    /* istanbul ignore if */
	    if (!this.code)
	      this.code = 'ZLIB_ERROR';

	    this.message = 'zlib: ' + err.message;
	    Error.captureStackTrace(this, this.constructor);
	  }

	  get name () {
	    return 'ZlibError'
	  }
	}

	// the Zlib class they all inherit from
	// This thing manages the queue of requests, and returns
	// true or false if there is anything in the queue when
	// you call the .write() method.
	const _opts = Symbol('opts');
	const _flushFlag = Symbol('flushFlag');
	const _finishFlushFlag = Symbol('finishFlushFlag');
	const _fullFlushFlag = Symbol('fullFlushFlag');
	const _handle = Symbol('handle');
	const _onError = Symbol('onError');
	const _sawError = Symbol('sawError');
	const _level = Symbol('level');
	const _strategy = Symbol('strategy');
	const _ended = Symbol('ended');

	class ZlibBase extends Minipass {
	  constructor (opts, mode) {
	    if (!opts || typeof opts !== 'object')
	      throw new TypeError('invalid options for ZlibBase constructor')

	    super(opts);
	    this[_sawError] = false;
	    this[_ended] = false;
	    this[_opts] = opts;

	    this[_flushFlag] = opts.flush;
	    this[_finishFlushFlag] = opts.finishFlush;
	    // this will throw if any options are invalid for the class selected
	    try {
	      this[_handle] = new realZlib[mode](opts);
	    } catch (er) {
	      // make sure that all errors get decorated properly
	      throw new ZlibError(er)
	    }

	    this[_onError] = (err) => {
	      // no sense raising multiple errors, since we abort on the first one.
	      if (this[_sawError])
	        return

	      this[_sawError] = true;

	      // there is no way to cleanly recover.
	      // continuing only obscures problems.
	      this.close();
	      this.emit('error', err);
	    };

	    this[_handle].on('error', er => this[_onError](new ZlibError(er)));
	    this.once('end', () => this.close);
	  }

	  close () {
	    if (this[_handle]) {
	      this[_handle].close();
	      this[_handle] = null;
	      this.emit('close');
	    }
	  }

	  reset () {
	    if (!this[_sawError]) {
	      assert(this[_handle], 'zlib binding closed');
	      return this[_handle].reset()
	    }
	  }

	  flush (flushFlag) {
	    if (this.ended)
	      return

	    if (typeof flushFlag !== 'number')
	      flushFlag = this[_fullFlushFlag];
	    this.write(Object.assign(Buffer.alloc(0), { [_flushFlag]: flushFlag }));
	  }

	  end (chunk, encoding, cb) {
	    if (chunk)
	      this.write(chunk, encoding);
	    this.flush(this[_finishFlushFlag]);
	    this[_ended] = true;
	    return super.end(null, null, cb)
	  }

	  get ended () {
	    return this[_ended]
	  }

	  write (chunk, encoding, cb) {
	    // process the chunk using the sync process
	    // then super.write() all the outputted chunks
	    if (typeof encoding === 'function')
	      cb = encoding, encoding = 'utf8';

	    if (typeof chunk === 'string')
	      chunk = Buffer.from(chunk, encoding);

	    if (this[_sawError])
	      return
	    assert(this[_handle], 'zlib binding closed');

	    // _processChunk tries to .close() the native handle after it's done, so we
	    // intercept that by temporarily making it a no-op.
	    const nativeHandle = this[_handle]._handle;
	    const originalNativeClose = nativeHandle.close;
	    nativeHandle.close = () => {};
	    const originalClose = this[_handle].close;
	    this[_handle].close = () => {};
	    // It also calls `Buffer.concat()` at the end, which may be convenient
	    // for some, but which we are not interested in as it slows us down.
	    Buffer.concat = (args) => args;
	    let result;
	    try {
	      const flushFlag = typeof chunk[_flushFlag] === 'number'
	        ? chunk[_flushFlag] : this[_flushFlag];
	      result = this[_handle]._processChunk(chunk, flushFlag);
	      // if we don't throw, reset it back how it was
	      Buffer.concat = OriginalBufferConcat;
	    } catch (err) {
	      // or if we do, put Buffer.concat() back before we emit error
	      // Error events call into user code, which may call Buffer.concat()
	      Buffer.concat = OriginalBufferConcat;
	      this[_onError](new ZlibError(err));
	    } finally {
	      if (this[_handle]) {
	        // Core zlib resets `_handle` to null after attempting to close the
	        // native handle. Our no-op handler prevented actual closure, but we
	        // need to restore the `._handle` property.
	        this[_handle]._handle = nativeHandle;
	        nativeHandle.close = originalNativeClose;
	        this[_handle].close = originalClose;
	        // `_processChunk()` adds an 'error' listener. If we don't remove it
	        // after each call, these handlers start piling up.
	        this[_handle].removeAllListeners('error');
	        // make sure OUR error listener is still attached tho
	      }
	    }

	    if (this[_handle])
	      this[_handle].on('error', er => this[_onError](new ZlibError(er)));

	    let writeReturn;
	    if (result) {
	      if (Array.isArray(result) && result.length > 0) {
	        // The first buffer is always `handle._outBuffer`, which would be
	        // re-used for later invocations; so, we always have to copy that one.
	        writeReturn = this[_superWrite](Buffer.from(result[0]));
	        for (let i = 1; i < result.length; i++) {
	          writeReturn = this[_superWrite](result[i]);
	        }
	      } else {
	        writeReturn = this[_superWrite](Buffer.from(result));
	      }
	    }

	    if (cb)
	      cb();
	    return writeReturn
	  }

	  [_superWrite] (data) {
	    return super.write(data)
	  }
	}

	class Zlib extends ZlibBase {
	  constructor (opts, mode) {
	    opts = opts || {};

	    opts.flush = opts.flush || constants.Z_NO_FLUSH;
	    opts.finishFlush = opts.finishFlush || constants.Z_FINISH;
	    super(opts, mode);

	    this[_fullFlushFlag] = constants.Z_FULL_FLUSH;
	    this[_level] = opts.level;
	    this[_strategy] = opts.strategy;
	  }

	  params (level, strategy) {
	    if (this[_sawError])
	      return

	    if (!this[_handle])
	      throw new Error('cannot switch params when binding is closed')

	    // no way to test this without also not supporting params at all
	    /* istanbul ignore if */
	    if (!this[_handle].params)
	      throw new Error('not supported in this implementation')

	    if (this[_level] !== level || this[_strategy] !== strategy) {
	      this.flush(constants.Z_SYNC_FLUSH);
	      assert(this[_handle], 'zlib binding closed');
	      // .params() calls .flush(), but the latter is always async in the
	      // core zlib. We override .flush() temporarily to intercept that and
	      // flush synchronously.
	      const origFlush = this[_handle].flush;
	      this[_handle].flush = (flushFlag, cb) => {
	        this.flush(flushFlag);
	        cb();
	      };
	      try {
	        this[_handle].params(level, strategy);
	      } finally {
	        this[_handle].flush = origFlush;
	      }
	      /* istanbul ignore else */
	      if (this[_handle]) {
	        this[_level] = level;
	        this[_strategy] = strategy;
	      }
	    }
	  }
	}

	// minimal 2-byte header
	class Deflate extends Zlib {
	  constructor (opts) {
	    super(opts, 'Deflate');
	  }
	}

	class Inflate extends Zlib {
	  constructor (opts) {
	    super(opts, 'Inflate');
	  }
	}

	// gzip - bigger header, same deflate compression
	const _portable = Symbol('_portable');
	class Gzip extends Zlib {
	  constructor (opts) {
	    super(opts, 'Gzip');
	    this[_portable] = opts && !!opts.portable;
	  }

	  [_superWrite] (data) {
	    if (!this[_portable])
	      return super[_superWrite](data)

	    // we'll always get the header emitted in one first chunk
	    // overwrite the OS indicator byte with 0xFF
	    this[_portable] = false;
	    data[9] = 255;
	    return super[_superWrite](data)
	  }
	}

	class Gunzip extends Zlib {
	  constructor (opts) {
	    super(opts, 'Gunzip');
	  }
	}

	// raw - no header
	class DeflateRaw extends Zlib {
	  constructor (opts) {
	    super(opts, 'DeflateRaw');
	  }
	}

	class InflateRaw extends Zlib {
	  constructor (opts) {
	    super(opts, 'InflateRaw');
	  }
	}

	// auto-detect header.
	class Unzip extends Zlib {
	  constructor (opts) {
	    super(opts, 'Unzip');
	  }
	}

	class Brotli extends ZlibBase {
	  constructor (opts, mode) {
	    opts = opts || {};

	    opts.flush = opts.flush || constants.BROTLI_OPERATION_PROCESS;
	    opts.finishFlush = opts.finishFlush || constants.BROTLI_OPERATION_FINISH;

	    super(opts, mode);

	    this[_fullFlushFlag] = constants.BROTLI_OPERATION_FLUSH;
	  }
	}

	class BrotliCompress extends Brotli {
	  constructor (opts) {
	    super(opts, 'BrotliCompress');
	  }
	}

	class BrotliDecompress extends Brotli {
	  constructor (opts) {
	    super(opts, 'BrotliDecompress');
	  }
	}

	minizlib.Deflate = Deflate;
	minizlib.Inflate = Inflate;
	minizlib.Gzip = Gzip;
	minizlib.Gunzip = Gunzip;
	minizlib.DeflateRaw = DeflateRaw;
	minizlib.InflateRaw = InflateRaw;
	minizlib.Unzip = Unzip;
	/* istanbul ignore else */
	if (typeof realZlib.BrotliCompress === 'function') {
	  minizlib.BrotliCompress = BrotliCompress;
	  minizlib.BrotliDecompress = BrotliDecompress;
	} else {
	  minizlib.BrotliCompress = minizlib.BrotliDecompress = class {
	    constructor () {
	      throw new Error('Brotli is not supported in this version of Node.js')
	    }
	  };
	}
	return minizlib;
}

var normalizeWindowsPath;
var hasRequiredNormalizeWindowsPath;

function requireNormalizeWindowsPath () {
	if (hasRequiredNormalizeWindowsPath) return normalizeWindowsPath;
	hasRequiredNormalizeWindowsPath = 1;
	// on windows, either \ or / are valid directory separators.
	// on unix, \ is a valid character in filenames.
	// so, on windows, and only on windows, we replace all \ chars with /,
	// so that we can use / as our one and only directory separator char.

	const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
	normalizeWindowsPath = platform !== 'win32' ? p => p
	  : p => p && p.replace(/\\/g, '/');
	return normalizeWindowsPath;
}

var readEntry;
var hasRequiredReadEntry;

function requireReadEntry () {
	if (hasRequiredReadEntry) return readEntry;
	hasRequiredReadEntry = 1;
	const { Minipass } = requireMinipass$1();
	const normPath = requireNormalizeWindowsPath();

	const SLURP = Symbol('slurp');
	readEntry = class ReadEntry extends Minipass {
	  constructor (header, ex, gex) {
	    super();
	    // read entries always start life paused.  this is to avoid the
	    // situation where Minipass's auto-ending empty streams results
	    // in an entry ending before we're ready for it.
	    this.pause();
	    this.extended = ex;
	    this.globalExtended = gex;
	    this.header = header;
	    this.startBlockSize = 512 * Math.ceil(header.size / 512);
	    this.blockRemain = this.startBlockSize;
	    this.remain = header.size;
	    this.type = header.type;
	    this.meta = false;
	    this.ignore = false;
	    switch (this.type) {
	      case 'File':
	      case 'OldFile':
	      case 'Link':
	      case 'SymbolicLink':
	      case 'CharacterDevice':
	      case 'BlockDevice':
	      case 'Directory':
	      case 'FIFO':
	      case 'ContiguousFile':
	      case 'GNUDumpDir':
	        break

	      case 'NextFileHasLongLinkpath':
	      case 'NextFileHasLongPath':
	      case 'OldGnuLongPath':
	      case 'GlobalExtendedHeader':
	      case 'ExtendedHeader':
	      case 'OldExtendedHeader':
	        this.meta = true;
	        break

	      // NOTE: gnutar and bsdtar treat unrecognized types as 'File'
	      // it may be worth doing the same, but with a warning.
	      default:
	        this.ignore = true;
	    }

	    this.path = normPath(header.path);
	    this.mode = header.mode;
	    if (this.mode) {
	      this.mode = this.mode & 0o7777;
	    }
	    this.uid = header.uid;
	    this.gid = header.gid;
	    this.uname = header.uname;
	    this.gname = header.gname;
	    this.size = header.size;
	    this.mtime = header.mtime;
	    this.atime = header.atime;
	    this.ctime = header.ctime;
	    this.linkpath = normPath(header.linkpath);
	    this.uname = header.uname;
	    this.gname = header.gname;

	    if (ex) {
	      this[SLURP](ex);
	    }
	    if (gex) {
	      this[SLURP](gex, true);
	    }
	  }

	  write (data) {
	    const writeLen = data.length;
	    if (writeLen > this.blockRemain) {
	      throw new Error('writing more to entry than is appropriate')
	    }

	    const r = this.remain;
	    const br = this.blockRemain;
	    this.remain = Math.max(0, r - writeLen);
	    this.blockRemain = Math.max(0, br - writeLen);
	    if (this.ignore) {
	      return true
	    }

	    if (r >= writeLen) {
	      return super.write(data)
	    }

	    // r < writeLen
	    return super.write(data.slice(0, r))
	  }

	  [SLURP] (ex, global) {
	    for (const k in ex) {
	      // we slurp in everything except for the path attribute in
	      // a global extended header, because that's weird.
	      if (ex[k] !== null && ex[k] !== undefined &&
	          !(global && k === 'path')) {
	        this[k] = k === 'path' || k === 'linkpath' ? normPath(ex[k]) : ex[k];
	      }
	    }
	  }
	};
	return readEntry;
}

var types = {};

var hasRequiredTypes;

function requireTypes () {
	if (hasRequiredTypes) return types;
	hasRequiredTypes = 1;
	(function (exports) {
		// map types from key to human-friendly name
		exports.name = new Map([
		  ['0', 'File'],
		  // same as File
		  ['', 'OldFile'],
		  ['1', 'Link'],
		  ['2', 'SymbolicLink'],
		  // Devices and FIFOs aren't fully supported
		  // they are parsed, but skipped when unpacking
		  ['3', 'CharacterDevice'],
		  ['4', 'BlockDevice'],
		  ['5', 'Directory'],
		  ['6', 'FIFO'],
		  // same as File
		  ['7', 'ContiguousFile'],
		  // pax headers
		  ['g', 'GlobalExtendedHeader'],
		  ['x', 'ExtendedHeader'],
		  // vendor-specific stuff
		  // skip
		  ['A', 'SolarisACL'],
		  // like 5, but with data, which should be skipped
		  ['D', 'GNUDumpDir'],
		  // metadata only, skip
		  ['I', 'Inode'],
		  // data = link path of next file
		  ['K', 'NextFileHasLongLinkpath'],
		  // data = path of next file
		  ['L', 'NextFileHasLongPath'],
		  // skip
		  ['M', 'ContinuationFile'],
		  // like L
		  ['N', 'OldGnuLongPath'],
		  // skip
		  ['S', 'SparseFile'],
		  // skip
		  ['V', 'TapeVolumeHeader'],
		  // like x
		  ['X', 'OldExtendedHeader'],
		]);

		// map the other direction
		exports.code = new Map(Array.from(exports.name).map(kv => [kv[1], kv[0]])); 
	} (types));
	return types;
}

var largeNumbers;
var hasRequiredLargeNumbers;

function requireLargeNumbers () {
	if (hasRequiredLargeNumbers) return largeNumbers;
	hasRequiredLargeNumbers = 1;
	// Tar can encode large and negative numbers using a leading byte of
	// 0xff for negative, and 0x80 for positive.

	const encode = (num, buf) => {
	  if (!Number.isSafeInteger(num)) {
	  // The number is so large that javascript cannot represent it with integer
	  // precision.
	    throw Error('cannot encode number outside of javascript safe integer range')
	  } else if (num < 0) {
	    encodeNegative(num, buf);
	  } else {
	    encodePositive(num, buf);
	  }
	  return buf
	};

	const encodePositive = (num, buf) => {
	  buf[0] = 0x80;

	  for (var i = buf.length; i > 1; i--) {
	    buf[i - 1] = num & 0xff;
	    num = Math.floor(num / 0x100);
	  }
	};

	const encodeNegative = (num, buf) => {
	  buf[0] = 0xff;
	  var flipped = false;
	  num = num * -1;
	  for (var i = buf.length; i > 1; i--) {
	    var byte = num & 0xff;
	    num = Math.floor(num / 0x100);
	    if (flipped) {
	      buf[i - 1] = onesComp(byte);
	    } else if (byte === 0) {
	      buf[i - 1] = 0;
	    } else {
	      flipped = true;
	      buf[i - 1] = twosComp(byte);
	    }
	  }
	};

	const parse = (buf) => {
	  const pre = buf[0];
	  const value = pre === 0x80 ? pos(buf.slice(1, buf.length))
	    : pre === 0xff ? twos(buf)
	    : null;
	  if (value === null) {
	    throw Error('invalid base256 encoding')
	  }

	  if (!Number.isSafeInteger(value)) {
	  // The number is so large that javascript cannot represent it with integer
	  // precision.
	    throw Error('parsed number outside of javascript safe integer range')
	  }

	  return value
	};

	const twos = (buf) => {
	  var len = buf.length;
	  var sum = 0;
	  var flipped = false;
	  for (var i = len - 1; i > -1; i--) {
	    var byte = buf[i];
	    var f;
	    if (flipped) {
	      f = onesComp(byte);
	    } else if (byte === 0) {
	      f = byte;
	    } else {
	      flipped = true;
	      f = twosComp(byte);
	    }
	    if (f !== 0) {
	      sum -= f * Math.pow(256, len - i - 1);
	    }
	  }
	  return sum
	};

	const pos = (buf) => {
	  var len = buf.length;
	  var sum = 0;
	  for (var i = len - 1; i > -1; i--) {
	    var byte = buf[i];
	    if (byte !== 0) {
	      sum += byte * Math.pow(256, len - i - 1);
	    }
	  }
	  return sum
	};

	const onesComp = byte => (0xff ^ byte) & 0xff;

	const twosComp = byte => ((0xff ^ byte) + 1) & 0xff;

	largeNumbers = {
	  encode,
	  parse,
	};
	return largeNumbers;
}

var header;
var hasRequiredHeader;

function requireHeader () {
	if (hasRequiredHeader) return header;
	hasRequiredHeader = 1;
	// parse a 512-byte header block to a data object, or vice-versa
	// encode returns `true` if a pax extended header is needed, because
	// the data could not be faithfully encoded in a simple header.
	// (Also, check header.needPax to see if it needs a pax header.)

	const types = requireTypes();
	const pathModule = require$$1.posix;
	const large = requireLargeNumbers();

	const SLURP = Symbol('slurp');
	const TYPE = Symbol('type');

	class Header {
	  constructor (data, off, ex, gex) {
	    this.cksumValid = false;
	    this.needPax = false;
	    this.nullBlock = false;

	    this.block = null;
	    this.path = null;
	    this.mode = null;
	    this.uid = null;
	    this.gid = null;
	    this.size = null;
	    this.mtime = null;
	    this.cksum = null;
	    this[TYPE] = '0';
	    this.linkpath = null;
	    this.uname = null;
	    this.gname = null;
	    this.devmaj = 0;
	    this.devmin = 0;
	    this.atime = null;
	    this.ctime = null;

	    if (Buffer.isBuffer(data)) {
	      this.decode(data, off || 0, ex, gex);
	    } else if (data) {
	      this.set(data);
	    }
	  }

	  decode (buf, off, ex, gex) {
	    if (!off) {
	      off = 0;
	    }

	    if (!buf || !(buf.length >= off + 512)) {
	      throw new Error('need 512 bytes for header')
	    }

	    this.path = decString(buf, off, 100);
	    this.mode = decNumber(buf, off + 100, 8);
	    this.uid = decNumber(buf, off + 108, 8);
	    this.gid = decNumber(buf, off + 116, 8);
	    this.size = decNumber(buf, off + 124, 12);
	    this.mtime = decDate(buf, off + 136, 12);
	    this.cksum = decNumber(buf, off + 148, 12);

	    // if we have extended or global extended headers, apply them now
	    // See https://github.com/npm/node-tar/pull/187
	    this[SLURP](ex);
	    this[SLURP](gex, true);

	    // old tar versions marked dirs as a file with a trailing /
	    this[TYPE] = decString(buf, off + 156, 1);
	    if (this[TYPE] === '') {
	      this[TYPE] = '0';
	    }
	    if (this[TYPE] === '0' && this.path.slice(-1) === '/') {
	      this[TYPE] = '5';
	    }

	    // tar implementations sometimes incorrectly put the stat(dir).size
	    // as the size in the tarball, even though Directory entries are
	    // not able to have any body at all.  In the very rare chance that
	    // it actually DOES have a body, we weren't going to do anything with
	    // it anyway, and it'll just be a warning about an invalid header.
	    if (this[TYPE] === '5') {
	      this.size = 0;
	    }

	    this.linkpath = decString(buf, off + 157, 100);
	    if (buf.slice(off + 257, off + 265).toString() === 'ustar\u000000') {
	      this.uname = decString(buf, off + 265, 32);
	      this.gname = decString(buf, off + 297, 32);
	      this.devmaj = decNumber(buf, off + 329, 8);
	      this.devmin = decNumber(buf, off + 337, 8);
	      if (buf[off + 475] !== 0) {
	        // definitely a prefix, definitely >130 chars.
	        const prefix = decString(buf, off + 345, 155);
	        this.path = prefix + '/' + this.path;
	      } else {
	        const prefix = decString(buf, off + 345, 130);
	        if (prefix) {
	          this.path = prefix + '/' + this.path;
	        }
	        this.atime = decDate(buf, off + 476, 12);
	        this.ctime = decDate(buf, off + 488, 12);
	      }
	    }

	    let sum = 8 * 0x20;
	    for (let i = off; i < off + 148; i++) {
	      sum += buf[i];
	    }

	    for (let i = off + 156; i < off + 512; i++) {
	      sum += buf[i];
	    }

	    this.cksumValid = sum === this.cksum;
	    if (this.cksum === null && sum === 8 * 0x20) {
	      this.nullBlock = true;
	    }
	  }

	  [SLURP] (ex, global) {
	    for (const k in ex) {
	      // we slurp in everything except for the path attribute in
	      // a global extended header, because that's weird.
	      if (ex[k] !== null && ex[k] !== undefined &&
	          !(global && k === 'path')) {
	        this[k] = ex[k];
	      }
	    }
	  }

	  encode (buf, off) {
	    if (!buf) {
	      buf = this.block = Buffer.alloc(512);
	      off = 0;
	    }

	    if (!off) {
	      off = 0;
	    }

	    if (!(buf.length >= off + 512)) {
	      throw new Error('need 512 bytes for header')
	    }

	    const prefixSize = this.ctime || this.atime ? 130 : 155;
	    const split = splitPrefix(this.path || '', prefixSize);
	    const path = split[0];
	    const prefix = split[1];
	    this.needPax = split[2];

	    this.needPax = encString(buf, off, 100, path) || this.needPax;
	    this.needPax = encNumber(buf, off + 100, 8, this.mode) || this.needPax;
	    this.needPax = encNumber(buf, off + 108, 8, this.uid) || this.needPax;
	    this.needPax = encNumber(buf, off + 116, 8, this.gid) || this.needPax;
	    this.needPax = encNumber(buf, off + 124, 12, this.size) || this.needPax;
	    this.needPax = encDate(buf, off + 136, 12, this.mtime) || this.needPax;
	    buf[off + 156] = this[TYPE].charCodeAt(0);
	    this.needPax = encString(buf, off + 157, 100, this.linkpath) || this.needPax;
	    buf.write('ustar\u000000', off + 257, 8);
	    this.needPax = encString(buf, off + 265, 32, this.uname) || this.needPax;
	    this.needPax = encString(buf, off + 297, 32, this.gname) || this.needPax;
	    this.needPax = encNumber(buf, off + 329, 8, this.devmaj) || this.needPax;
	    this.needPax = encNumber(buf, off + 337, 8, this.devmin) || this.needPax;
	    this.needPax = encString(buf, off + 345, prefixSize, prefix) || this.needPax;
	    if (buf[off + 475] !== 0) {
	      this.needPax = encString(buf, off + 345, 155, prefix) || this.needPax;
	    } else {
	      this.needPax = encString(buf, off + 345, 130, prefix) || this.needPax;
	      this.needPax = encDate(buf, off + 476, 12, this.atime) || this.needPax;
	      this.needPax = encDate(buf, off + 488, 12, this.ctime) || this.needPax;
	    }

	    let sum = 8 * 0x20;
	    for (let i = off; i < off + 148; i++) {
	      sum += buf[i];
	    }

	    for (let i = off + 156; i < off + 512; i++) {
	      sum += buf[i];
	    }

	    this.cksum = sum;
	    encNumber(buf, off + 148, 8, this.cksum);
	    this.cksumValid = true;

	    return this.needPax
	  }

	  set (data) {
	    for (const i in data) {
	      if (data[i] !== null && data[i] !== undefined) {
	        this[i] = data[i];
	      }
	    }
	  }

	  get type () {
	    return types.name.get(this[TYPE]) || this[TYPE]
	  }

	  get typeKey () {
	    return this[TYPE]
	  }

	  set type (type) {
	    if (types.code.has(type)) {
	      this[TYPE] = types.code.get(type);
	    } else {
	      this[TYPE] = type;
	    }
	  }
	}

	const splitPrefix = (p, prefixSize) => {
	  const pathSize = 100;
	  let pp = p;
	  let prefix = '';
	  let ret;
	  const root = pathModule.parse(p).root || '.';

	  if (Buffer.byteLength(pp) < pathSize) {
	    ret = [pp, prefix, false];
	  } else {
	    // first set prefix to the dir, and path to the base
	    prefix = pathModule.dirname(pp);
	    pp = pathModule.basename(pp);

	    do {
	      if (Buffer.byteLength(pp) <= pathSize &&
	          Buffer.byteLength(prefix) <= prefixSize) {
	        // both fit!
	        ret = [pp, prefix, false];
	      } else if (Buffer.byteLength(pp) > pathSize &&
	          Buffer.byteLength(prefix) <= prefixSize) {
	        // prefix fits in prefix, but path doesn't fit in path
	        ret = [pp.slice(0, pathSize - 1), prefix, true];
	      } else {
	        // make path take a bit from prefix
	        pp = pathModule.join(pathModule.basename(prefix), pp);
	        prefix = pathModule.dirname(prefix);
	      }
	    } while (prefix !== root && !ret)

	    // at this point, found no resolution, just truncate
	    if (!ret) {
	      ret = [p.slice(0, pathSize - 1), '', true];
	    }
	  }
	  return ret
	};

	const decString = (buf, off, size) =>
	  buf.slice(off, off + size).toString('utf8').replace(/\0.*/, '');

	const decDate = (buf, off, size) =>
	  numToDate(decNumber(buf, off, size));

	const numToDate = num => num === null ? null : new Date(num * 1000);

	const decNumber = (buf, off, size) =>
	  buf[off] & 0x80 ? large.parse(buf.slice(off, off + size))
	  : decSmallNumber(buf, off, size);

	const nanNull = value => isNaN(value) ? null : value;

	const decSmallNumber = (buf, off, size) =>
	  nanNull(parseInt(
	    buf.slice(off, off + size)
	      .toString('utf8').replace(/\0.*$/, '').trim(), 8));

	// the maximum encodable as a null-terminated octal, by field size
	const MAXNUM = {
	  12: 0o77777777777,
	  8: 0o7777777,
	};

	const encNumber = (buf, off, size, number) =>
	  number === null ? false :
	  number > MAXNUM[size] || number < 0
	    ? (large.encode(number, buf.slice(off, off + size)), true)
	    : (encSmallNumber(buf, off, size, number), false);

	const encSmallNumber = (buf, off, size, number) =>
	  buf.write(octalString(number, size), off, size, 'ascii');

	const octalString = (number, size) =>
	  padOctal(Math.floor(number).toString(8), size);

	const padOctal = (string, size) =>
	  (string.length === size - 1 ? string
	  : new Array(size - string.length - 1).join('0') + string + ' ') + '\0';

	const encDate = (buf, off, size, date) =>
	  date === null ? false :
	  encNumber(buf, off, size, date.getTime() / 1000);

	// enough to fill the longest string we've got
	const NULLS = new Array(156).join('\0');
	// pad with nulls, return true if it's longer or non-ascii
	const encString = (buf, off, size, string) =>
	  string === null ? false :
	  (buf.write(string + NULLS, off, size, 'utf8'),
	  string.length !== Buffer.byteLength(string) || string.length > size);

	header = Header;
	return header;
}

var pax;
var hasRequiredPax;

function requirePax () {
	if (hasRequiredPax) return pax;
	hasRequiredPax = 1;
	const Header = requireHeader();
	const path = require$$1;

	class Pax {
	  constructor (obj, global) {
	    this.atime = obj.atime || null;
	    this.charset = obj.charset || null;
	    this.comment = obj.comment || null;
	    this.ctime = obj.ctime || null;
	    this.gid = obj.gid || null;
	    this.gname = obj.gname || null;
	    this.linkpath = obj.linkpath || null;
	    this.mtime = obj.mtime || null;
	    this.path = obj.path || null;
	    this.size = obj.size || null;
	    this.uid = obj.uid || null;
	    this.uname = obj.uname || null;
	    this.dev = obj.dev || null;
	    this.ino = obj.ino || null;
	    this.nlink = obj.nlink || null;
	    this.global = global || false;
	  }

	  encode () {
	    const body = this.encodeBody();
	    if (body === '') {
	      return null
	    }

	    const bodyLen = Buffer.byteLength(body);
	    // round up to 512 bytes
	    // add 512 for header
	    const bufLen = 512 * Math.ceil(1 + bodyLen / 512);
	    const buf = Buffer.allocUnsafe(bufLen);

	    // 0-fill the header section, it might not hit every field
	    for (let i = 0; i < 512; i++) {
	      buf[i] = 0;
	    }

	    new Header({
	      // XXX split the path
	      // then the path should be PaxHeader + basename, but less than 99,
	      // prepend with the dirname
	      path: ('PaxHeader/' + path.basename(this.path)).slice(0, 99),
	      mode: this.mode || 0o644,
	      uid: this.uid || null,
	      gid: this.gid || null,
	      size: bodyLen,
	      mtime: this.mtime || null,
	      type: this.global ? 'GlobalExtendedHeader' : 'ExtendedHeader',
	      linkpath: '',
	      uname: this.uname || '',
	      gname: this.gname || '',
	      devmaj: 0,
	      devmin: 0,
	      atime: this.atime || null,
	      ctime: this.ctime || null,
	    }).encode(buf);

	    buf.write(body, 512, bodyLen, 'utf8');

	    // null pad after the body
	    for (let i = bodyLen + 512; i < buf.length; i++) {
	      buf[i] = 0;
	    }

	    return buf
	  }

	  encodeBody () {
	    return (
	      this.encodeField('path') +
	      this.encodeField('ctime') +
	      this.encodeField('atime') +
	      this.encodeField('dev') +
	      this.encodeField('ino') +
	      this.encodeField('nlink') +
	      this.encodeField('charset') +
	      this.encodeField('comment') +
	      this.encodeField('gid') +
	      this.encodeField('gname') +
	      this.encodeField('linkpath') +
	      this.encodeField('mtime') +
	      this.encodeField('size') +
	      this.encodeField('uid') +
	      this.encodeField('uname')
	    )
	  }

	  encodeField (field) {
	    if (this[field] === null || this[field] === undefined) {
	      return ''
	    }
	    const v = this[field] instanceof Date ? this[field].getTime() / 1000
	      : this[field];
	    const s = ' ' +
	      (field === 'dev' || field === 'ino' || field === 'nlink'
	        ? 'SCHILY.' : '') +
	      field + '=' + v + '\n';
	    const byteLen = Buffer.byteLength(s);
	    // the digits includes the length of the digits in ascii base-10
	    // so if it's 9 characters, then adding 1 for the 9 makes it 10
	    // which makes it 11 chars.
	    let digits = Math.floor(Math.log(byteLen) / Math.log(10)) + 1;
	    if (byteLen + digits >= Math.pow(10, digits)) {
	      digits += 1;
	    }
	    const len = digits + byteLen;
	    return len + s
	  }
	}

	Pax.parse = (string, ex, g) => new Pax(merge(parseKV(string), ex), g);

	const merge = (a, b) =>
	  b ? Object.keys(a).reduce((s, k) => (s[k] = a[k], s), b) : a;

	const parseKV = string =>
	  string
	    .replace(/\n$/, '')
	    .split('\n')
	    .reduce(parseKVLine, Object.create(null));

	const parseKVLine = (set, line) => {
	  const n = parseInt(line, 10);

	  // XXX Values with \n in them will fail this.
	  // Refactor to not be a naive line-by-line parse.
	  if (n !== Buffer.byteLength(line) + 1) {
	    return set
	  }

	  line = line.slice((n + ' ').length);
	  const kv = line.split('=');
	  const k = kv.shift().replace(/^SCHILY\.(dev|ino|nlink)/, '$1');
	  if (!k) {
	    return set
	  }

	  const v = kv.join('=');
	  set[k] = /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k)
	    ? new Date(v * 1000)
	    : /^[0-9]+$/.test(v) ? +v
	    : v;
	  return set
	};

	pax = Pax;
	return pax;
}

var stripTrailingSlashes;
var hasRequiredStripTrailingSlashes;

function requireStripTrailingSlashes () {
	if (hasRequiredStripTrailingSlashes) return stripTrailingSlashes;
	hasRequiredStripTrailingSlashes = 1;
	// warning: extremely hot code path.
	// This has been meticulously optimized for use
	// within npm install on large package trees.
	// Do not edit without careful benchmarking.
	stripTrailingSlashes = str => {
	  let i = str.length - 1;
	  let slashesStart = -1;
	  while (i > -1 && str.charAt(i) === '/') {
	    slashesStart = i;
	    i--;
	  }
	  return slashesStart === -1 ? str : str.slice(0, slashesStart)
	};
	return stripTrailingSlashes;
}

var warnMixin;
var hasRequiredWarnMixin;

function requireWarnMixin () {
	if (hasRequiredWarnMixin) return warnMixin;
	hasRequiredWarnMixin = 1;
	warnMixin = Base => class extends Base {
	  warn (code, message, data = {}) {
	    if (this.file) {
	      data.file = this.file;
	    }
	    if (this.cwd) {
	      data.cwd = this.cwd;
	    }
	    data.code = message instanceof Error && message.code || code;
	    data.tarCode = code;
	    if (!this.strict && data.recoverable !== false) {
	      if (message instanceof Error) {
	        data = Object.assign(message, data);
	        message = message.message;
	      }
	      this.emit('warn', data.tarCode, message, data);
	    } else if (message instanceof Error) {
	      this.emit('error', Object.assign(message, data));
	    } else {
	      this.emit('error', Object.assign(new Error(`${code}: ${message}`), data));
	    }
	  }
	};
	return warnMixin;
}

var winchars;
var hasRequiredWinchars;

function requireWinchars () {
	if (hasRequiredWinchars) return winchars;
	hasRequiredWinchars = 1;

	// When writing files on Windows, translate the characters to their
	// 0xf000 higher-encoded versions.

	const raw = [
	  '|',
	  '<',
	  '>',
	  '?',
	  ':',
	];

	const win = raw.map(char =>
	  String.fromCharCode(0xf000 + char.charCodeAt(0)));

	const toWin = new Map(raw.map((char, i) => [char, win[i]]));
	const toRaw = new Map(win.map((char, i) => [char, raw[i]]));

	winchars = {
	  encode: s => raw.reduce((s, c) => s.split(c).join(toWin.get(c)), s),
	  decode: s => win.reduce((s, c) => s.split(c).join(toRaw.get(c)), s),
	};
	return winchars;
}

var stripAbsolutePath;
var hasRequiredStripAbsolutePath;

function requireStripAbsolutePath () {
	if (hasRequiredStripAbsolutePath) return stripAbsolutePath;
	hasRequiredStripAbsolutePath = 1;
	// unix absolute paths are also absolute on win32, so we use this for both
	const { isAbsolute, parse } = require$$1.win32;

	// returns [root, stripped]
	// Note that windows will think that //x/y/z/a has a "root" of //x/y, and in
	// those cases, we want to sanitize it to x/y/z/a, not z/a, so we strip /
	// explicitly if it's the first character.
	// drive-specific relative paths on Windows get their root stripped off even
	// though they are not absolute, so `c:../foo` becomes ['c:', '../foo']
	stripAbsolutePath = path => {
	  let r = '';

	  let parsed = parse(path);
	  while (isAbsolute(path) || parsed.root) {
	    // windows will think that //x/y/z has a "root" of //x/y/
	    // but strip the //?/C:/ off of //?/C:/path
	    const root = path.charAt(0) === '/' && path.slice(0, 4) !== '//?/' ? '/'
	      : parsed.root;
	    path = path.slice(root.length);
	    r += root;
	    parsed = parse(path);
	  }
	  return [r, path]
	};
	return stripAbsolutePath;
}

var modeFix;
var hasRequiredModeFix;

function requireModeFix () {
	if (hasRequiredModeFix) return modeFix;
	hasRequiredModeFix = 1;
	modeFix = (mode, isDir, portable) => {
	  mode &= 0o7777;

	  // in portable mode, use the minimum reasonable umask
	  // if this system creates files with 0o664 by default
	  // (as some linux distros do), then we'll write the
	  // archive with 0o644 instead.  Also, don't ever create
	  // a file that is not readable/writable by the owner.
	  if (portable) {
	    mode = (mode | 0o600) & -19;
	  }

	  // if dirs are readable, then they should be listable
	  if (isDir) {
	    if (mode & 0o400) {
	      mode |= 0o100;
	    }
	    if (mode & 0o40) {
	      mode |= 0o10;
	    }
	    if (mode & 0o4) {
	      mode |= 0o1;
	    }
	  }
	  return mode
	};
	return modeFix;
}

var writeEntry;
var hasRequiredWriteEntry;

function requireWriteEntry () {
	if (hasRequiredWriteEntry) return writeEntry;
	hasRequiredWriteEntry = 1;
	const { Minipass } = requireMinipass$1();
	const Pax = requirePax();
	const Header = requireHeader();
	const fs = require$$0$2;
	const path = require$$1;
	const normPath = requireNormalizeWindowsPath();
	const stripSlash = requireStripTrailingSlashes();

	const prefixPath = (path, prefix) => {
	  if (!prefix) {
	    return normPath(path)
	  }
	  path = normPath(path).replace(/^\.(\/|$)/, '');
	  return stripSlash(prefix) + '/' + path
	};

	const maxReadSize = 16 * 1024 * 1024;
	const PROCESS = Symbol('process');
	const FILE = Symbol('file');
	const DIRECTORY = Symbol('directory');
	const SYMLINK = Symbol('symlink');
	const HARDLINK = Symbol('hardlink');
	const HEADER = Symbol('header');
	const READ = Symbol('read');
	const LSTAT = Symbol('lstat');
	const ONLSTAT = Symbol('onlstat');
	const ONREAD = Symbol('onread');
	const ONREADLINK = Symbol('onreadlink');
	const OPENFILE = Symbol('openfile');
	const ONOPENFILE = Symbol('onopenfile');
	const CLOSE = Symbol('close');
	const MODE = Symbol('mode');
	const AWAITDRAIN = Symbol('awaitDrain');
	const ONDRAIN = Symbol('ondrain');
	const PREFIX = Symbol('prefix');
	const HAD_ERROR = Symbol('hadError');
	const warner = requireWarnMixin();
	const winchars = requireWinchars();
	const stripAbsolutePath = requireStripAbsolutePath();

	const modeFix = requireModeFix();

	const WriteEntry = warner(class WriteEntry extends Minipass {
	  constructor (p, opt) {
	    opt = opt || {};
	    super(opt);
	    if (typeof p !== 'string') {
	      throw new TypeError('path is required')
	    }
	    this.path = normPath(p);
	    // suppress atime, ctime, uid, gid, uname, gname
	    this.portable = !!opt.portable;
	    // until node has builtin pwnam functions, this'll have to do
	    this.myuid = process.getuid && process.getuid() || 0;
	    this.myuser = process.env.USER || '';
	    this.maxReadSize = opt.maxReadSize || maxReadSize;
	    this.linkCache = opt.linkCache || new Map();
	    this.statCache = opt.statCache || new Map();
	    this.preservePaths = !!opt.preservePaths;
	    this.cwd = normPath(opt.cwd || process.cwd());
	    this.strict = !!opt.strict;
	    this.noPax = !!opt.noPax;
	    this.noMtime = !!opt.noMtime;
	    this.mtime = opt.mtime || null;
	    this.prefix = opt.prefix ? normPath(opt.prefix) : null;

	    this.fd = null;
	    this.blockLen = null;
	    this.blockRemain = null;
	    this.buf = null;
	    this.offset = null;
	    this.length = null;
	    this.pos = null;
	    this.remain = null;

	    if (typeof opt.onwarn === 'function') {
	      this.on('warn', opt.onwarn);
	    }

	    let pathWarn = false;
	    if (!this.preservePaths) {
	      const [root, stripped] = stripAbsolutePath(this.path);
	      if (root) {
	        this.path = stripped;
	        pathWarn = root;
	      }
	    }

	    this.win32 = !!opt.win32 || process.platform === 'win32';
	    if (this.win32) {
	      // force the \ to / normalization, since we might not *actually*
	      // be on windows, but want \ to be considered a path separator.
	      this.path = winchars.decode(this.path.replace(/\\/g, '/'));
	      p = p.replace(/\\/g, '/');
	    }

	    this.absolute = normPath(opt.absolute || path.resolve(this.cwd, p));

	    if (this.path === '') {
	      this.path = './';
	    }

	    if (pathWarn) {
	      this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, {
	        entry: this,
	        path: pathWarn + this.path,
	      });
	    }

	    if (this.statCache.has(this.absolute)) {
	      this[ONLSTAT](this.statCache.get(this.absolute));
	    } else {
	      this[LSTAT]();
	    }
	  }

	  emit (ev, ...data) {
	    if (ev === 'error') {
	      this[HAD_ERROR] = true;
	    }
	    return super.emit(ev, ...data)
	  }

	  [LSTAT] () {
	    fs.lstat(this.absolute, (er, stat) => {
	      if (er) {
	        return this.emit('error', er)
	      }
	      this[ONLSTAT](stat);
	    });
	  }

	  [ONLSTAT] (stat) {
	    this.statCache.set(this.absolute, stat);
	    this.stat = stat;
	    if (!stat.isFile()) {
	      stat.size = 0;
	    }
	    this.type = getType(stat);
	    this.emit('stat', stat);
	    this[PROCESS]();
	  }

	  [PROCESS] () {
	    switch (this.type) {
	      case 'File': return this[FILE]()
	      case 'Directory': return this[DIRECTORY]()
	      case 'SymbolicLink': return this[SYMLINK]()
	      // unsupported types are ignored.
	      default: return this.end()
	    }
	  }

	  [MODE] (mode) {
	    return modeFix(mode, this.type === 'Directory', this.portable)
	  }

	  [PREFIX] (path) {
	    return prefixPath(path, this.prefix)
	  }

	  [HEADER] () {
	    if (this.type === 'Directory' && this.portable) {
	      this.noMtime = true;
	    }

	    this.header = new Header({
	      path: this[PREFIX](this.path),
	      // only apply the prefix to hard links.
	      linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath)
	      : this.linkpath,
	      // only the permissions and setuid/setgid/sticky bitflags
	      // not the higher-order bits that specify file type
	      mode: this[MODE](this.stat.mode),
	      uid: this.portable ? null : this.stat.uid,
	      gid: this.portable ? null : this.stat.gid,
	      size: this.stat.size,
	      mtime: this.noMtime ? null : this.mtime || this.stat.mtime,
	      type: this.type,
	      uname: this.portable ? null :
	      this.stat.uid === this.myuid ? this.myuser : '',
	      atime: this.portable ? null : this.stat.atime,
	      ctime: this.portable ? null : this.stat.ctime,
	    });

	    if (this.header.encode() && !this.noPax) {
	      super.write(new Pax({
	        atime: this.portable ? null : this.header.atime,
	        ctime: this.portable ? null : this.header.ctime,
	        gid: this.portable ? null : this.header.gid,
	        mtime: this.noMtime ? null : this.mtime || this.header.mtime,
	        path: this[PREFIX](this.path),
	        linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath)
	        : this.linkpath,
	        size: this.header.size,
	        uid: this.portable ? null : this.header.uid,
	        uname: this.portable ? null : this.header.uname,
	        dev: this.portable ? null : this.stat.dev,
	        ino: this.portable ? null : this.stat.ino,
	        nlink: this.portable ? null : this.stat.nlink,
	      }).encode());
	    }
	    super.write(this.header.block);
	  }

	  [DIRECTORY] () {
	    if (this.path.slice(-1) !== '/') {
	      this.path += '/';
	    }
	    this.stat.size = 0;
	    this[HEADER]();
	    this.end();
	  }

	  [SYMLINK] () {
	    fs.readlink(this.absolute, (er, linkpath) => {
	      if (er) {
	        return this.emit('error', er)
	      }
	      this[ONREADLINK](linkpath);
	    });
	  }

	  [ONREADLINK] (linkpath) {
	    this.linkpath = normPath(linkpath);
	    this[HEADER]();
	    this.end();
	  }

	  [HARDLINK] (linkpath) {
	    this.type = 'Link';
	    this.linkpath = normPath(path.relative(this.cwd, linkpath));
	    this.stat.size = 0;
	    this[HEADER]();
	    this.end();
	  }

	  [FILE] () {
	    if (this.stat.nlink > 1) {
	      const linkKey = this.stat.dev + ':' + this.stat.ino;
	      if (this.linkCache.has(linkKey)) {
	        const linkpath = this.linkCache.get(linkKey);
	        if (linkpath.indexOf(this.cwd) === 0) {
	          return this[HARDLINK](linkpath)
	        }
	      }
	      this.linkCache.set(linkKey, this.absolute);
	    }

	    this[HEADER]();
	    if (this.stat.size === 0) {
	      return this.end()
	    }

	    this[OPENFILE]();
	  }

	  [OPENFILE] () {
	    fs.open(this.absolute, 'r', (er, fd) => {
	      if (er) {
	        return this.emit('error', er)
	      }
	      this[ONOPENFILE](fd);
	    });
	  }

	  [ONOPENFILE] (fd) {
	    this.fd = fd;
	    if (this[HAD_ERROR]) {
	      return this[CLOSE]()
	    }

	    this.blockLen = 512 * Math.ceil(this.stat.size / 512);
	    this.blockRemain = this.blockLen;
	    const bufLen = Math.min(this.blockLen, this.maxReadSize);
	    this.buf = Buffer.allocUnsafe(bufLen);
	    this.offset = 0;
	    this.pos = 0;
	    this.remain = this.stat.size;
	    this.length = this.buf.length;
	    this[READ]();
	  }

	  [READ] () {
	    const { fd, buf, offset, length, pos } = this;
	    fs.read(fd, buf, offset, length, pos, (er, bytesRead) => {
	      if (er) {
	        // ignoring the error from close(2) is a bad practice, but at
	        // this point we already have an error, don't need another one
	        return this[CLOSE](() => this.emit('error', er))
	      }
	      this[ONREAD](bytesRead);
	    });
	  }

	  [CLOSE] (cb) {
	    fs.close(this.fd, cb);
	  }

	  [ONREAD] (bytesRead) {
	    if (bytesRead <= 0 && this.remain > 0) {
	      const er = new Error('encountered unexpected EOF');
	      er.path = this.absolute;
	      er.syscall = 'read';
	      er.code = 'EOF';
	      return this[CLOSE](() => this.emit('error', er))
	    }

	    if (bytesRead > this.remain) {
	      const er = new Error('did not encounter expected EOF');
	      er.path = this.absolute;
	      er.syscall = 'read';
	      er.code = 'EOF';
	      return this[CLOSE](() => this.emit('error', er))
	    }

	    // null out the rest of the buffer, if we could fit the block padding
	    // at the end of this loop, we've incremented bytesRead and this.remain
	    // to be incremented up to the blockRemain level, as if we had expected
	    // to get a null-padded file, and read it until the end.  then we will
	    // decrement both remain and blockRemain by bytesRead, and know that we
	    // reached the expected EOF, without any null buffer to append.
	    if (bytesRead === this.remain) {
	      for (let i = bytesRead; i < this.length && bytesRead < this.blockRemain; i++) {
	        this.buf[i + this.offset] = 0;
	        bytesRead++;
	        this.remain++;
	      }
	    }

	    const writeBuf = this.offset === 0 && bytesRead === this.buf.length ?
	      this.buf : this.buf.slice(this.offset, this.offset + bytesRead);

	    const flushed = this.write(writeBuf);
	    if (!flushed) {
	      this[AWAITDRAIN](() => this[ONDRAIN]());
	    } else {
	      this[ONDRAIN]();
	    }
	  }

	  [AWAITDRAIN] (cb) {
	    this.once('drain', cb);
	  }

	  write (writeBuf) {
	    if (this.blockRemain < writeBuf.length) {
	      const er = new Error('writing more data than expected');
	      er.path = this.absolute;
	      return this.emit('error', er)
	    }
	    this.remain -= writeBuf.length;
	    this.blockRemain -= writeBuf.length;
	    this.pos += writeBuf.length;
	    this.offset += writeBuf.length;
	    return super.write(writeBuf)
	  }

	  [ONDRAIN] () {
	    if (!this.remain) {
	      if (this.blockRemain) {
	        super.write(Buffer.alloc(this.blockRemain));
	      }
	      return this[CLOSE](er => er ? this.emit('error', er) : this.end())
	    }

	    if (this.offset >= this.length) {
	      // if we only have a smaller bit left to read, alloc a smaller buffer
	      // otherwise, keep it the same length it was before.
	      this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length));
	      this.offset = 0;
	    }
	    this.length = this.buf.length - this.offset;
	    this[READ]();
	  }
	});

	class WriteEntrySync extends WriteEntry {
	  [LSTAT] () {
	    this[ONLSTAT](fs.lstatSync(this.absolute));
	  }

	  [SYMLINK] () {
	    this[ONREADLINK](fs.readlinkSync(this.absolute));
	  }

	  [OPENFILE] () {
	    this[ONOPENFILE](fs.openSync(this.absolute, 'r'));
	  }

	  [READ] () {
	    let threw = true;
	    try {
	      const { fd, buf, offset, length, pos } = this;
	      const bytesRead = fs.readSync(fd, buf, offset, length, pos);
	      this[ONREAD](bytesRead);
	      threw = false;
	    } finally {
	      // ignoring the error from close(2) is a bad practice, but at
	      // this point we already have an error, don't need another one
	      if (threw) {
	        try {
	          this[CLOSE](() => {});
	        } catch (er) {}
	      }
	    }
	  }

	  [AWAITDRAIN] (cb) {
	    cb();
	  }

	  [CLOSE] (cb) {
	    fs.closeSync(this.fd);
	    cb();
	  }
	}

	const WriteEntryTar = warner(class WriteEntryTar extends Minipass {
	  constructor (readEntry, opt) {
	    opt = opt || {};
	    super(opt);
	    this.preservePaths = !!opt.preservePaths;
	    this.portable = !!opt.portable;
	    this.strict = !!opt.strict;
	    this.noPax = !!opt.noPax;
	    this.noMtime = !!opt.noMtime;

	    this.readEntry = readEntry;
	    this.type = readEntry.type;
	    if (this.type === 'Directory' && this.portable) {
	      this.noMtime = true;
	    }

	    this.prefix = opt.prefix || null;

	    this.path = normPath(readEntry.path);
	    this.mode = this[MODE](readEntry.mode);
	    this.uid = this.portable ? null : readEntry.uid;
	    this.gid = this.portable ? null : readEntry.gid;
	    this.uname = this.portable ? null : readEntry.uname;
	    this.gname = this.portable ? null : readEntry.gname;
	    this.size = readEntry.size;
	    this.mtime = this.noMtime ? null : opt.mtime || readEntry.mtime;
	    this.atime = this.portable ? null : readEntry.atime;
	    this.ctime = this.portable ? null : readEntry.ctime;
	    this.linkpath = normPath(readEntry.linkpath);

	    if (typeof opt.onwarn === 'function') {
	      this.on('warn', opt.onwarn);
	    }

	    let pathWarn = false;
	    if (!this.preservePaths) {
	      const [root, stripped] = stripAbsolutePath(this.path);
	      if (root) {
	        this.path = stripped;
	        pathWarn = root;
	      }
	    }

	    this.remain = readEntry.size;
	    this.blockRemain = readEntry.startBlockSize;

	    this.header = new Header({
	      path: this[PREFIX](this.path),
	      linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath)
	      : this.linkpath,
	      // only the permissions and setuid/setgid/sticky bitflags
	      // not the higher-order bits that specify file type
	      mode: this.mode,
	      uid: this.portable ? null : this.uid,
	      gid: this.portable ? null : this.gid,
	      size: this.size,
	      mtime: this.noMtime ? null : this.mtime,
	      type: this.type,
	      uname: this.portable ? null : this.uname,
	      atime: this.portable ? null : this.atime,
	      ctime: this.portable ? null : this.ctime,
	    });

	    if (pathWarn) {
	      this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, {
	        entry: this,
	        path: pathWarn + this.path,
	      });
	    }

	    if (this.header.encode() && !this.noPax) {
	      super.write(new Pax({
	        atime: this.portable ? null : this.atime,
	        ctime: this.portable ? null : this.ctime,
	        gid: this.portable ? null : this.gid,
	        mtime: this.noMtime ? null : this.mtime,
	        path: this[PREFIX](this.path),
	        linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath)
	        : this.linkpath,
	        size: this.size,
	        uid: this.portable ? null : this.uid,
	        uname: this.portable ? null : this.uname,
	        dev: this.portable ? null : this.readEntry.dev,
	        ino: this.portable ? null : this.readEntry.ino,
	        nlink: this.portable ? null : this.readEntry.nlink,
	      }).encode());
	    }

	    super.write(this.header.block);
	    readEntry.pipe(this);
	  }

	  [PREFIX] (path) {
	    return prefixPath(path, this.prefix)
	  }

	  [MODE] (mode) {
	    return modeFix(mode, this.type === 'Directory', this.portable)
	  }

	  write (data) {
	    const writeLen = data.length;
	    if (writeLen > this.blockRemain) {
	      throw new Error('writing more to entry than is appropriate')
	    }
	    this.blockRemain -= writeLen;
	    return super.write(data)
	  }

	  end () {
	    if (this.blockRemain) {
	      super.write(Buffer.alloc(this.blockRemain));
	    }
	    return super.end()
	  }
	});

	WriteEntry.Sync = WriteEntrySync;
	WriteEntry.Tar = WriteEntryTar;

	const getType = stat =>
	  stat.isFile() ? 'File'
	  : stat.isDirectory() ? 'Directory'
	  : stat.isSymbolicLink() ? 'SymbolicLink'
	  : 'Unsupported';

	writeEntry = WriteEntry;
	return writeEntry;
}

var iterator;
var hasRequiredIterator;

function requireIterator () {
	if (hasRequiredIterator) return iterator;
	hasRequiredIterator = 1;
	iterator = function (Yallist) {
	  Yallist.prototype[Symbol.iterator] = function* () {
	    for (let walker = this.head; walker; walker = walker.next) {
	      yield walker.value;
	    }
	  };
	};
	return iterator;
}

var yallist;
var hasRequiredYallist;

function requireYallist () {
	if (hasRequiredYallist) return yallist;
	hasRequiredYallist = 1;
	yallist = Yallist;

	Yallist.Node = Node;
	Yallist.create = Yallist;

	function Yallist (list) {
	  var self = this;
	  if (!(self instanceof Yallist)) {
	    self = new Yallist();
	  }

	  self.tail = null;
	  self.head = null;
	  self.length = 0;

	  if (list && typeof list.forEach === 'function') {
	    list.forEach(function (item) {
	      self.push(item);
	    });
	  } else if (arguments.length > 0) {
	    for (var i = 0, l = arguments.length; i < l; i++) {
	      self.push(arguments[i]);
	    }
	  }

	  return self
	}

	Yallist.prototype.removeNode = function (node) {
	  if (node.list !== this) {
	    throw new Error('removing node which does not belong to this list')
	  }

	  var next = node.next;
	  var prev = node.prev;

	  if (next) {
	    next.prev = prev;
	  }

	  if (prev) {
	    prev.next = next;
	  }

	  if (node === this.head) {
	    this.head = next;
	  }
	  if (node === this.tail) {
	    this.tail = prev;
	  }

	  node.list.length--;
	  node.next = null;
	  node.prev = null;
	  node.list = null;

	  return next
	};

	Yallist.prototype.unshiftNode = function (node) {
	  if (node === this.head) {
	    return
	  }

	  if (node.list) {
	    node.list.removeNode(node);
	  }

	  var head = this.head;
	  node.list = this;
	  node.next = head;
	  if (head) {
	    head.prev = node;
	  }

	  this.head = node;
	  if (!this.tail) {
	    this.tail = node;
	  }
	  this.length++;
	};

	Yallist.prototype.pushNode = function (node) {
	  if (node === this.tail) {
	    return
	  }

	  if (node.list) {
	    node.list.removeNode(node);
	  }

	  var tail = this.tail;
	  node.list = this;
	  node.prev = tail;
	  if (tail) {
	    tail.next = node;
	  }

	  this.tail = node;
	  if (!this.head) {
	    this.head = node;
	  }
	  this.length++;
	};

	Yallist.prototype.push = function () {
	  for (var i = 0, l = arguments.length; i < l; i++) {
	    push(this, arguments[i]);
	  }
	  return this.length
	};

	Yallist.prototype.unshift = function () {
	  for (var i = 0, l = arguments.length; i < l; i++) {
	    unshift(this, arguments[i]);
	  }
	  return this.length
	};

	Yallist.prototype.pop = function () {
	  if (!this.tail) {
	    return undefined
	  }

	  var res = this.tail.value;
	  this.tail = this.tail.prev;
	  if (this.tail) {
	    this.tail.next = null;
	  } else {
	    this.head = null;
	  }
	  this.length--;
	  return res
	};

	Yallist.prototype.shift = function () {
	  if (!this.head) {
	    return undefined
	  }

	  var res = this.head.value;
	  this.head = this.head.next;
	  if (this.head) {
	    this.head.prev = null;
	  } else {
	    this.tail = null;
	  }
	  this.length--;
	  return res
	};

	Yallist.prototype.forEach = function (fn, thisp) {
	  thisp = thisp || this;
	  for (var walker = this.head, i = 0; walker !== null; i++) {
	    fn.call(thisp, walker.value, i, this);
	    walker = walker.next;
	  }
	};

	Yallist.prototype.forEachReverse = function (fn, thisp) {
	  thisp = thisp || this;
	  for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {
	    fn.call(thisp, walker.value, i, this);
	    walker = walker.prev;
	  }
	};

	Yallist.prototype.get = function (n) {
	  for (var i = 0, walker = this.head; walker !== null && i < n; i++) {
	    // abort out of the list early if we hit a cycle
	    walker = walker.next;
	  }
	  if (i === n && walker !== null) {
	    return walker.value
	  }
	};

	Yallist.prototype.getReverse = function (n) {
	  for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {
	    // abort out of the list early if we hit a cycle
	    walker = walker.prev;
	  }
	  if (i === n && walker !== null) {
	    return walker.value
	  }
	};

	Yallist.prototype.map = function (fn, thisp) {
	  thisp = thisp || this;
	  var res = new Yallist();
	  for (var walker = this.head; walker !== null;) {
	    res.push(fn.call(thisp, walker.value, this));
	    walker = walker.next;
	  }
	  return res
	};

	Yallist.prototype.mapReverse = function (fn, thisp) {
	  thisp = thisp || this;
	  var res = new Yallist();
	  for (var walker = this.tail; walker !== null;) {
	    res.push(fn.call(thisp, walker.value, this));
	    walker = walker.prev;
	  }
	  return res
	};

	Yallist.prototype.reduce = function (fn, initial) {
	  var acc;
	  var walker = this.head;
	  if (arguments.length > 1) {
	    acc = initial;
	  } else if (this.head) {
	    walker = this.head.next;
	    acc = this.head.value;
	  } else {
	    throw new TypeError('Reduce of empty list with no initial value')
	  }

	  for (var i = 0; walker !== null; i++) {
	    acc = fn(acc, walker.value, i);
	    walker = walker.next;
	  }

	  return acc
	};

	Yallist.prototype.reduceReverse = function (fn, initial) {
	  var acc;
	  var walker = this.tail;
	  if (arguments.length > 1) {
	    acc = initial;
	  } else if (this.tail) {
	    walker = this.tail.prev;
	    acc = this.tail.value;
	  } else {
	    throw new TypeError('Reduce of empty list with no initial value')
	  }

	  for (var i = this.length - 1; walker !== null; i--) {
	    acc = fn(acc, walker.value, i);
	    walker = walker.prev;
	  }

	  return acc
	};

	Yallist.prototype.toArray = function () {
	  var arr = new Array(this.length);
	  for (var i = 0, walker = this.head; walker !== null; i++) {
	    arr[i] = walker.value;
	    walker = walker.next;
	  }
	  return arr
	};

	Yallist.prototype.toArrayReverse = function () {
	  var arr = new Array(this.length);
	  for (var i = 0, walker = this.tail; walker !== null; i++) {
	    arr[i] = walker.value;
	    walker = walker.prev;
	  }
	  return arr
	};

	Yallist.prototype.slice = function (from, to) {
	  to = to || this.length;
	  if (to < 0) {
	    to += this.length;
	  }
	  from = from || 0;
	  if (from < 0) {
	    from += this.length;
	  }
	  var ret = new Yallist();
	  if (to < from || to < 0) {
	    return ret
	  }
	  if (from < 0) {
	    from = 0;
	  }
	  if (to > this.length) {
	    to = this.length;
	  }
	  for (var i = 0, walker = this.head; walker !== null && i < from; i++) {
	    walker = walker.next;
	  }
	  for (; walker !== null && i < to; i++, walker = walker.next) {
	    ret.push(walker.value);
	  }
	  return ret
	};

	Yallist.prototype.sliceReverse = function (from, to) {
	  to = to || this.length;
	  if (to < 0) {
	    to += this.length;
	  }
	  from = from || 0;
	  if (from < 0) {
	    from += this.length;
	  }
	  var ret = new Yallist();
	  if (to < from || to < 0) {
	    return ret
	  }
	  if (from < 0) {
	    from = 0;
	  }
	  if (to > this.length) {
	    to = this.length;
	  }
	  for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {
	    walker = walker.prev;
	  }
	  for (; walker !== null && i > from; i--, walker = walker.prev) {
	    ret.push(walker.value);
	  }
	  return ret
	};

	Yallist.prototype.splice = function (start, deleteCount, ...nodes) {
	  if (start > this.length) {
	    start = this.length - 1;
	  }
	  if (start < 0) {
	    start = this.length + start;
	  }

	  for (var i = 0, walker = this.head; walker !== null && i < start; i++) {
	    walker = walker.next;
	  }

	  var ret = [];
	  for (var i = 0; walker && i < deleteCount; i++) {
	    ret.push(walker.value);
	    walker = this.removeNode(walker);
	  }
	  if (walker === null) {
	    walker = this.tail;
	  }

	  if (walker !== this.head && walker !== this.tail) {
	    walker = walker.prev;
	  }

	  for (var i = 0; i < nodes.length; i++) {
	    walker = insert(this, walker, nodes[i]);
	  }
	  return ret;
	};

	Yallist.prototype.reverse = function () {
	  var head = this.head;
	  var tail = this.tail;
	  for (var walker = head; walker !== null; walker = walker.prev) {
	    var p = walker.prev;
	    walker.prev = walker.next;
	    walker.next = p;
	  }
	  this.head = tail;
	  this.tail = head;
	  return this
	};

	function insert (self, node, value) {
	  var inserted = node === self.head ?
	    new Node(value, null, node, self) :
	    new Node(value, node, node.next, self);

	  if (inserted.next === null) {
	    self.tail = inserted;
	  }
	  if (inserted.prev === null) {
	    self.head = inserted;
	  }

	  self.length++;

	  return inserted
	}

	function push (self, item) {
	  self.tail = new Node(item, self.tail, null, self);
	  if (!self.head) {
	    self.head = self.tail;
	  }
	  self.length++;
	}

	function unshift (self, item) {
	  self.head = new Node(item, null, self.head, self);
	  if (!self.tail) {
	    self.tail = self.head;
	  }
	  self.length++;
	}

	function Node (value, prev, next, list) {
	  if (!(this instanceof Node)) {
	    return new Node(value, prev, next, list)
	  }

	  this.list = list;
	  this.value = value;

	  if (prev) {
	    prev.next = this;
	    this.prev = prev;
	  } else {
	    this.prev = null;
	  }

	  if (next) {
	    next.prev = this;
	    this.next = next;
	  } else {
	    this.next = null;
	  }
	}

	try {
	  // add if support for Symbol.iterator is present
	  requireIterator()(Yallist);
	} catch (er) {}
	return yallist;
}

var pack;
var hasRequiredPack;

function requirePack () {
	if (hasRequiredPack) return pack;
	hasRequiredPack = 1;

	// A readable tar stream creator
	// Technically, this is a transform stream that you write paths into,
	// and tar format comes out of.
	// The `add()` method is like `write()` but returns this,
	// and end() return `this` as well, so you can
	// do `new Pack(opt).add('files').add('dir').end().pipe(output)
	// You could also do something like:
	// streamOfPaths().pipe(new Pack()).pipe(new fs.WriteStream('out.tar'))

	class PackJob {
	  constructor (path, absolute) {
	    this.path = path || './';
	    this.absolute = absolute;
	    this.entry = null;
	    this.stat = null;
	    this.readdir = null;
	    this.pending = false;
	    this.ignore = false;
	    this.piped = false;
	  }
	}

	const { Minipass } = requireMinipass$1();
	const zlib = requireMinizlib();
	const ReadEntry = requireReadEntry();
	const WriteEntry = requireWriteEntry();
	const WriteEntrySync = WriteEntry.Sync;
	const WriteEntryTar = WriteEntry.Tar;
	const Yallist = requireYallist();
	const EOF = Buffer.alloc(1024);
	const ONSTAT = Symbol('onStat');
	const ENDED = Symbol('ended');
	const QUEUE = Symbol('queue');
	const CURRENT = Symbol('current');
	const PROCESS = Symbol('process');
	const PROCESSING = Symbol('processing');
	const PROCESSJOB = Symbol('processJob');
	const JOBS = Symbol('jobs');
	const JOBDONE = Symbol('jobDone');
	const ADDFSENTRY = Symbol('addFSEntry');
	const ADDTARENTRY = Symbol('addTarEntry');
	const STAT = Symbol('stat');
	const READDIR = Symbol('readdir');
	const ONREADDIR = Symbol('onreaddir');
	const PIPE = Symbol('pipe');
	const ENTRY = Symbol('entry');
	const ENTRYOPT = Symbol('entryOpt');
	const WRITEENTRYCLASS = Symbol('writeEntryClass');
	const WRITE = Symbol('write');
	const ONDRAIN = Symbol('ondrain');

	const fs = require$$0$2;
	const path = require$$1;
	const warner = requireWarnMixin();
	const normPath = requireNormalizeWindowsPath();

	const Pack = warner(class Pack extends Minipass {
	  constructor (opt) {
	    super(opt);
	    opt = opt || Object.create(null);
	    this.opt = opt;
	    this.file = opt.file || '';
	    this.cwd = opt.cwd || process.cwd();
	    this.maxReadSize = opt.maxReadSize;
	    this.preservePaths = !!opt.preservePaths;
	    this.strict = !!opt.strict;
	    this.noPax = !!opt.noPax;
	    this.prefix = normPath(opt.prefix || '');
	    this.linkCache = opt.linkCache || new Map();
	    this.statCache = opt.statCache || new Map();
	    this.readdirCache = opt.readdirCache || new Map();

	    this[WRITEENTRYCLASS] = WriteEntry;
	    if (typeof opt.onwarn === 'function') {
	      this.on('warn', opt.onwarn);
	    }

	    this.portable = !!opt.portable;
	    this.zip = null;

	    if (opt.gzip || opt.brotli) {
	      if (opt.gzip && opt.brotli) {
	        throw new TypeError('gzip and brotli are mutually exclusive')
	      }
	      if (opt.gzip) {
	        if (typeof opt.gzip !== 'object') {
	          opt.gzip = {};
	        }
	        if (this.portable) {
	          opt.gzip.portable = true;
	        }
	        this.zip = new zlib.Gzip(opt.gzip);
	      }
	      if (opt.brotli) {
	        if (typeof opt.brotli !== 'object') {
	          opt.brotli = {};
	        }
	        this.zip = new zlib.BrotliCompress(opt.brotli);
	      }
	      this.zip.on('data', chunk => super.write(chunk));
	      this.zip.on('end', _ => super.end());
	      this.zip.on('drain', _ => this[ONDRAIN]());
	      this.on('resume', _ => this.zip.resume());
	    } else {
	      this.on('drain', this[ONDRAIN]);
	    }

	    this.noDirRecurse = !!opt.noDirRecurse;
	    this.follow = !!opt.follow;
	    this.noMtime = !!opt.noMtime;
	    this.mtime = opt.mtime || null;

	    this.filter = typeof opt.filter === 'function' ? opt.filter : _ => true;

	    this[QUEUE] = new Yallist();
	    this[JOBS] = 0;
	    this.jobs = +opt.jobs || 4;
	    this[PROCESSING] = false;
	    this[ENDED] = false;
	  }

	  [WRITE] (chunk) {
	    return super.write(chunk)
	  }

	  add (path) {
	    this.write(path);
	    return this
	  }

	  end (path) {
	    if (path) {
	      this.write(path);
	    }
	    this[ENDED] = true;
	    this[PROCESS]();
	    return this
	  }

	  write (path) {
	    if (this[ENDED]) {
	      throw new Error('write after end')
	    }

	    if (path instanceof ReadEntry) {
	      this[ADDTARENTRY](path);
	    } else {
	      this[ADDFSENTRY](path);
	    }
	    return this.flowing
	  }

	  [ADDTARENTRY] (p) {
	    const absolute = normPath(path.resolve(this.cwd, p.path));
	    // in this case, we don't have to wait for the stat
	    if (!this.filter(p.path, p)) {
	      p.resume();
	    } else {
	      const job = new PackJob(p.path, absolute, false);
	      job.entry = new WriteEntryTar(p, this[ENTRYOPT](job));
	      job.entry.on('end', _ => this[JOBDONE](job));
	      this[JOBS] += 1;
	      this[QUEUE].push(job);
	    }

	    this[PROCESS]();
	  }

	  [ADDFSENTRY] (p) {
	    const absolute = normPath(path.resolve(this.cwd, p));
	    this[QUEUE].push(new PackJob(p, absolute));
	    this[PROCESS]();
	  }

	  [STAT] (job) {
	    job.pending = true;
	    this[JOBS] += 1;
	    const stat = this.follow ? 'stat' : 'lstat';
	    fs[stat](job.absolute, (er, stat) => {
	      job.pending = false;
	      this[JOBS] -= 1;
	      if (er) {
	        this.emit('error', er);
	      } else {
	        this[ONSTAT](job, stat);
	      }
	    });
	  }

	  [ONSTAT] (job, stat) {
	    this.statCache.set(job.absolute, stat);
	    job.stat = stat;

	    // now we have the stat, we can filter it.
	    if (!this.filter(job.path, stat)) {
	      job.ignore = true;
	    }

	    this[PROCESS]();
	  }

	  [READDIR] (job) {
	    job.pending = true;
	    this[JOBS] += 1;
	    fs.readdir(job.absolute, (er, entries) => {
	      job.pending = false;
	      this[JOBS] -= 1;
	      if (er) {
	        return this.emit('error', er)
	      }
	      this[ONREADDIR](job, entries);
	    });
	  }

	  [ONREADDIR] (job, entries) {
	    this.readdirCache.set(job.absolute, entries);
	    job.readdir = entries;
	    this[PROCESS]();
	  }

	  [PROCESS] () {
	    if (this[PROCESSING]) {
	      return
	    }

	    this[PROCESSING] = true;
	    for (let w = this[QUEUE].head;
	      w !== null && this[JOBS] < this.jobs;
	      w = w.next) {
	      this[PROCESSJOB](w.value);
	      if (w.value.ignore) {
	        const p = w.next;
	        this[QUEUE].removeNode(w);
	        w.next = p;
	      }
	    }

	    this[PROCESSING] = false;

	    if (this[ENDED] && !this[QUEUE].length && this[JOBS] === 0) {
	      if (this.zip) {
	        this.zip.end(EOF);
	      } else {
	        super.write(EOF);
	        super.end();
	      }
	    }
	  }

	  get [CURRENT] () {
	    return this[QUEUE] && this[QUEUE].head && this[QUEUE].head.value
	  }

	  [JOBDONE] (job) {
	    this[QUEUE].shift();
	    this[JOBS] -= 1;
	    this[PROCESS]();
	  }

	  [PROCESSJOB] (job) {
	    if (job.pending) {
	      return
	    }

	    if (job.entry) {
	      if (job === this[CURRENT] && !job.piped) {
	        this[PIPE](job);
	      }
	      return
	    }

	    if (!job.stat) {
	      if (this.statCache.has(job.absolute)) {
	        this[ONSTAT](job, this.statCache.get(job.absolute));
	      } else {
	        this[STAT](job);
	      }
	    }
	    if (!job.stat) {
	      return
	    }

	    // filtered out!
	    if (job.ignore) {
	      return
	    }

	    if (!this.noDirRecurse && job.stat.isDirectory() && !job.readdir) {
	      if (this.readdirCache.has(job.absolute)) {
	        this[ONREADDIR](job, this.readdirCache.get(job.absolute));
	      } else {
	        this[READDIR](job);
	      }
	      if (!job.readdir) {
	        return
	      }
	    }

	    // we know it doesn't have an entry, because that got checked above
	    job.entry = this[ENTRY](job);
	    if (!job.entry) {
	      job.ignore = true;
	      return
	    }

	    if (job === this[CURRENT] && !job.piped) {
	      this[PIPE](job);
	    }
	  }

	  [ENTRYOPT] (job) {
	    return {
	      onwarn: (code, msg, data) => this.warn(code, msg, data),
	      noPax: this.noPax,
	      cwd: this.cwd,
	      absolute: job.absolute,
	      preservePaths: this.preservePaths,
	      maxReadSize: this.maxReadSize,
	      strict: this.strict,
	      portable: this.portable,
	      linkCache: this.linkCache,
	      statCache: this.statCache,
	      noMtime: this.noMtime,
	      mtime: this.mtime,
	      prefix: this.prefix,
	    }
	  }

	  [ENTRY] (job) {
	    this[JOBS] += 1;
	    try {
	      return new this[WRITEENTRYCLASS](job.path, this[ENTRYOPT](job))
	        .on('end', () => this[JOBDONE](job))
	        .on('error', er => this.emit('error', er))
	    } catch (er) {
	      this.emit('error', er);
	    }
	  }

	  [ONDRAIN] () {
	    if (this[CURRENT] && this[CURRENT].entry) {
	      this[CURRENT].entry.resume();
	    }
	  }

	  // like .pipe() but using super, because our write() is special
	  [PIPE] (job) {
	    job.piped = true;

	    if (job.readdir) {
	      job.readdir.forEach(entry => {
	        const p = job.path;
	        const base = p === './' ? '' : p.replace(/\/*$/, '/');
	        this[ADDFSENTRY](base + entry);
	      });
	    }

	    const source = job.entry;
	    const zip = this.zip;

	    if (zip) {
	      source.on('data', chunk => {
	        if (!zip.write(chunk)) {
	          source.pause();
	        }
	      });
	    } else {
	      source.on('data', chunk => {
	        if (!super.write(chunk)) {
	          source.pause();
	        }
	      });
	    }
	  }

	  pause () {
	    if (this.zip) {
	      this.zip.pause();
	    }
	    return super.pause()
	  }
	});

	class PackSync extends Pack {
	  constructor (opt) {
	    super(opt);
	    this[WRITEENTRYCLASS] = WriteEntrySync;
	  }

	  // pause/resume are no-ops in sync streams.
	  pause () {}
	  resume () {}

	  [STAT] (job) {
	    const stat = this.follow ? 'statSync' : 'lstatSync';
	    this[ONSTAT](job, fs[stat](job.absolute));
	  }

	  [READDIR] (job, stat) {
	    this[ONREADDIR](job, fs.readdirSync(job.absolute));
	  }

	  // gotta get it all in this tick
	  [PIPE] (job) {
	    const source = job.entry;
	    const zip = this.zip;

	    if (job.readdir) {
	      job.readdir.forEach(entry => {
	        const p = job.path;
	        const base = p === './' ? '' : p.replace(/\/*$/, '/');
	        this[ADDFSENTRY](base + entry);
	      });
	    }

	    if (zip) {
	      source.on('data', chunk => {
	        zip.write(chunk);
	      });
	    } else {
	      source.on('data', chunk => {
	        super[WRITE](chunk);
	      });
	    }
	  }
	}

	Pack.Sync = PackSync;

	pack = Pack;
	return pack;
}

var fsMinipass = {};

var hasRequiredFsMinipass;

function requireFsMinipass () {
	if (hasRequiredFsMinipass) return fsMinipass;
	hasRequiredFsMinipass = 1;
	const MiniPass = requireMinipass();
	const EE = require$$0$1.EventEmitter;
	const fs = require$$0$2;

	let writev = fs.writev;
	/* istanbul ignore next */
	if (!writev) {
	  // This entire block can be removed if support for earlier than Node.js
	  // 12.9.0 is not needed.
	  const binding = process.binding('fs');
	  const FSReqWrap = binding.FSReqWrap || binding.FSReqCallback;

	  writev = (fd, iovec, pos, cb) => {
	    const done = (er, bw) => cb(er, bw, iovec);
	    const req = new FSReqWrap();
	    req.oncomplete = done;
	    binding.writeBuffers(fd, iovec, pos, req);
	  };
	}

	const _autoClose = Symbol('_autoClose');
	const _close = Symbol('_close');
	const _ended = Symbol('_ended');
	const _fd = Symbol('_fd');
	const _finished = Symbol('_finished');
	const _flags = Symbol('_flags');
	const _flush = Symbol('_flush');
	const _handleChunk = Symbol('_handleChunk');
	const _makeBuf = Symbol('_makeBuf');
	const _mode = Symbol('_mode');
	const _needDrain = Symbol('_needDrain');
	const _onerror = Symbol('_onerror');
	const _onopen = Symbol('_onopen');
	const _onread = Symbol('_onread');
	const _onwrite = Symbol('_onwrite');
	const _open = Symbol('_open');
	const _path = Symbol('_path');
	const _pos = Symbol('_pos');
	const _queue = Symbol('_queue');
	const _read = Symbol('_read');
	const _readSize = Symbol('_readSize');
	const _reading = Symbol('_reading');
	const _remain = Symbol('_remain');
	const _size = Symbol('_size');
	const _write = Symbol('_write');
	const _writing = Symbol('_writing');
	const _defaultFlag = Symbol('_defaultFlag');
	const _errored = Symbol('_errored');

	class ReadStream extends MiniPass {
	  constructor (path, opt) {
	    opt = opt || {};
	    super(opt);

	    this.readable = true;
	    this.writable = false;

	    if (typeof path !== 'string')
	      throw new TypeError('path must be a string')

	    this[_errored] = false;
	    this[_fd] = typeof opt.fd === 'number' ? opt.fd : null;
	    this[_path] = path;
	    this[_readSize] = opt.readSize || 16*1024*1024;
	    this[_reading] = false;
	    this[_size] = typeof opt.size === 'number' ? opt.size : Infinity;
	    this[_remain] = this[_size];
	    this[_autoClose] = typeof opt.autoClose === 'boolean' ?
	      opt.autoClose : true;

	    if (typeof this[_fd] === 'number')
	      this[_read]();
	    else
	      this[_open]();
	  }

	  get fd () { return this[_fd] }
	  get path () { return this[_path] }

	  write () {
	    throw new TypeError('this is a readable stream')
	  }

	  end () {
	    throw new TypeError('this is a readable stream')
	  }

	  [_open] () {
	    fs.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd));
	  }

	  [_onopen] (er, fd) {
	    if (er)
	      this[_onerror](er);
	    else {
	      this[_fd] = fd;
	      this.emit('open', fd);
	      this[_read]();
	    }
	  }

	  [_makeBuf] () {
	    return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain]))
	  }

	  [_read] () {
	    if (!this[_reading]) {
	      this[_reading] = true;
	      const buf = this[_makeBuf]();
	      /* istanbul ignore if */
	      if (buf.length === 0)
	        return process.nextTick(() => this[_onread](null, 0, buf))
	      fs.read(this[_fd], buf, 0, buf.length, null, (er, br, buf) =>
	        this[_onread](er, br, buf));
	    }
	  }

	  [_onread] (er, br, buf) {
	    this[_reading] = false;
	    if (er)
	      this[_onerror](er);
	    else if (this[_handleChunk](br, buf))
	      this[_read]();
	  }

	  [_close] () {
	    if (this[_autoClose] && typeof this[_fd] === 'number') {
	      const fd = this[_fd];
	      this[_fd] = null;
	      fs.close(fd, er => er ? this.emit('error', er) : this.emit('close'));
	    }
	  }

	  [_onerror] (er) {
	    this[_reading] = true;
	    this[_close]();
	    this.emit('error', er);
	  }

	  [_handleChunk] (br, buf) {
	    let ret = false;
	    // no effect if infinite
	    this[_remain] -= br;
	    if (br > 0)
	      ret = super.write(br < buf.length ? buf.slice(0, br) : buf);

	    if (br === 0 || this[_remain] <= 0) {
	      ret = false;
	      this[_close]();
	      super.end();
	    }

	    return ret
	  }

	  emit (ev, data) {
	    switch (ev) {
	      case 'prefinish':
	      case 'finish':
	        break

	      case 'drain':
	        if (typeof this[_fd] === 'number')
	          this[_read]();
	        break

	      case 'error':
	        if (this[_errored])
	          return
	        this[_errored] = true;
	        return super.emit(ev, data)

	      default:
	        return super.emit(ev, data)
	    }
	  }
	}

	class ReadStreamSync extends ReadStream {
	  [_open] () {
	    let threw = true;
	    try {
	      this[_onopen](null, fs.openSync(this[_path], 'r'));
	      threw = false;
	    } finally {
	      if (threw)
	        this[_close]();
	    }
	  }

	  [_read] () {
	    let threw = true;
	    try {
	      if (!this[_reading]) {
	        this[_reading] = true;
	        do {
	          const buf = this[_makeBuf]();
	          /* istanbul ignore next */
	          const br = buf.length === 0 ? 0
	            : fs.readSync(this[_fd], buf, 0, buf.length, null);
	          if (!this[_handleChunk](br, buf))
	            break
	        } while (true)
	        this[_reading] = false;
	      }
	      threw = false;
	    } finally {
	      if (threw)
	        this[_close]();
	    }
	  }

	  [_close] () {
	    if (this[_autoClose] && typeof this[_fd] === 'number') {
	      const fd = this[_fd];
	      this[_fd] = null;
	      fs.closeSync(fd);
	      this.emit('close');
	    }
	  }
	}

	class WriteStream extends EE {
	  constructor (path, opt) {
	    opt = opt || {};
	    super(opt);
	    this.readable = false;
	    this.writable = true;
	    this[_errored] = false;
	    this[_writing] = false;
	    this[_ended] = false;
	    this[_needDrain] = false;
	    this[_queue] = [];
	    this[_path] = path;
	    this[_fd] = typeof opt.fd === 'number' ? opt.fd : null;
	    this[_mode] = opt.mode === undefined ? 0o666 : opt.mode;
	    this[_pos] = typeof opt.start === 'number' ? opt.start : null;
	    this[_autoClose] = typeof opt.autoClose === 'boolean' ?
	      opt.autoClose : true;

	    // truncating makes no sense when writing into the middle
	    const defaultFlag = this[_pos] !== null ? 'r+' : 'w';
	    this[_defaultFlag] = opt.flags === undefined;
	    this[_flags] = this[_defaultFlag] ? defaultFlag : opt.flags;

	    if (this[_fd] === null)
	      this[_open]();
	  }

	  emit (ev, data) {
	    if (ev === 'error') {
	      if (this[_errored])
	        return
	      this[_errored] = true;
	    }
	    return super.emit(ev, data)
	  }


	  get fd () { return this[_fd] }
	  get path () { return this[_path] }

	  [_onerror] (er) {
	    this[_close]();
	    this[_writing] = true;
	    this.emit('error', er);
	  }

	  [_open] () {
	    fs.open(this[_path], this[_flags], this[_mode],
	      (er, fd) => this[_onopen](er, fd));
	  }

	  [_onopen] (er, fd) {
	    if (this[_defaultFlag] &&
	        this[_flags] === 'r+' &&
	        er && er.code === 'ENOENT') {
	      this[_flags] = 'w';
	      this[_open]();
	    } else if (er)
	      this[_onerror](er);
	    else {
	      this[_fd] = fd;
	      this.emit('open', fd);
	      this[_flush]();
	    }
	  }

	  end (buf, enc) {
	    if (buf)
	      this.write(buf, enc);

	    this[_ended] = true;

	    // synthetic after-write logic, where drain/finish live
	    if (!this[_writing] && !this[_queue].length &&
	        typeof this[_fd] === 'number')
	      this[_onwrite](null, 0);
	    return this
	  }

	  write (buf, enc) {
	    if (typeof buf === 'string')
	      buf = Buffer.from(buf, enc);

	    if (this[_ended]) {
	      this.emit('error', new Error('write() after end()'));
	      return false
	    }

	    if (this[_fd] === null || this[_writing] || this[_queue].length) {
	      this[_queue].push(buf);
	      this[_needDrain] = true;
	      return false
	    }

	    this[_writing] = true;
	    this[_write](buf);
	    return true
	  }

	  [_write] (buf) {
	    fs.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) =>
	      this[_onwrite](er, bw));
	  }

	  [_onwrite] (er, bw) {
	    if (er)
	      this[_onerror](er);
	    else {
	      if (this[_pos] !== null)
	        this[_pos] += bw;
	      if (this[_queue].length)
	        this[_flush]();
	      else {
	        this[_writing] = false;

	        if (this[_ended] && !this[_finished]) {
	          this[_finished] = true;
	          this[_close]();
	          this.emit('finish');
	        } else if (this[_needDrain]) {
	          this[_needDrain] = false;
	          this.emit('drain');
	        }
	      }
	    }
	  }

	  [_flush] () {
	    if (this[_queue].length === 0) {
	      if (this[_ended])
	        this[_onwrite](null, 0);
	    } else if (this[_queue].length === 1)
	      this[_write](this[_queue].pop());
	    else {
	      const iovec = this[_queue];
	      this[_queue] = [];
	      writev(this[_fd], iovec, this[_pos],
	        (er, bw) => this[_onwrite](er, bw));
	    }
	  }

	  [_close] () {
	    if (this[_autoClose] && typeof this[_fd] === 'number') {
	      const fd = this[_fd];
	      this[_fd] = null;
	      fs.close(fd, er => er ? this.emit('error', er) : this.emit('close'));
	    }
	  }
	}

	class WriteStreamSync extends WriteStream {
	  [_open] () {
	    let fd;
	    // only wrap in a try{} block if we know we'll retry, to avoid
	    // the rethrow obscuring the error's source frame in most cases.
	    if (this[_defaultFlag] && this[_flags] === 'r+') {
	      try {
	        fd = fs.openSync(this[_path], this[_flags], this[_mode]);
	      } catch (er) {
	        if (er.code === 'ENOENT') {
	          this[_flags] = 'w';
	          return this[_open]()
	        } else
	          throw er
	      }
	    } else
	      fd = fs.openSync(this[_path], this[_flags], this[_mode]);

	    this[_onopen](null, fd);
	  }

	  [_close] () {
	    if (this[_autoClose] && typeof this[_fd] === 'number') {
	      const fd = this[_fd];
	      this[_fd] = null;
	      fs.closeSync(fd);
	      this.emit('close');
	    }
	  }

	  [_write] (buf) {
	    // throw the original, but try to close if it fails
	    let threw = true;
	    try {
	      this[_onwrite](null,
	        fs.writeSync(this[_fd], buf, 0, buf.length, this[_pos]));
	      threw = false;
	    } finally {
	      if (threw)
	        try { this[_close](); } catch (_) {}
	    }
	  }
	}

	fsMinipass.ReadStream = ReadStream;
	fsMinipass.ReadStreamSync = ReadStreamSync;

	fsMinipass.WriteStream = WriteStream;
	fsMinipass.WriteStreamSync = WriteStreamSync;
	return fsMinipass;
}

var parse;
var hasRequiredParse$2;

function requireParse$2 () {
	if (hasRequiredParse$2) return parse;
	hasRequiredParse$2 = 1;

	// this[BUFFER] is the remainder of a chunk if we're waiting for
	// the full 512 bytes of a header to come in.  We will Buffer.concat()
	// it to the next write(), which is a mem copy, but a small one.
	//
	// this[QUEUE] is a Yallist of entries that haven't been emitted
	// yet this can only get filled up if the user keeps write()ing after
	// a write() returns false, or does a write() with more than one entry
	//
	// We don't buffer chunks, we always parse them and either create an
	// entry, or push it into the active entry.  The ReadEntry class knows
	// to throw data away if .ignore=true
	//
	// Shift entry off the buffer when it emits 'end', and emit 'entry' for
	// the next one in the list.
	//
	// At any time, we're pushing body chunks into the entry at WRITEENTRY,
	// and waiting for 'end' on the entry at READENTRY
	//
	// ignored entries get .resume() called on them straight away

	const warner = requireWarnMixin();
	const Header = requireHeader();
	const EE = require$$0$1;
	const Yallist = requireYallist();
	const maxMetaEntrySize = 1024 * 1024;
	const Entry = requireReadEntry();
	const Pax = requirePax();
	const zlib = requireMinizlib();
	const { nextTick } = require$$7;

	const gzipHeader = Buffer.from([0x1f, 0x8b]);
	const STATE = Symbol('state');
	const WRITEENTRY = Symbol('writeEntry');
	const READENTRY = Symbol('readEntry');
	const NEXTENTRY = Symbol('nextEntry');
	const PROCESSENTRY = Symbol('processEntry');
	const EX = Symbol('extendedHeader');
	const GEX = Symbol('globalExtendedHeader');
	const META = Symbol('meta');
	const EMITMETA = Symbol('emitMeta');
	const BUFFER = Symbol('buffer');
	const QUEUE = Symbol('queue');
	const ENDED = Symbol('ended');
	const EMITTEDEND = Symbol('emittedEnd');
	const EMIT = Symbol('emit');
	const UNZIP = Symbol('unzip');
	const CONSUMECHUNK = Symbol('consumeChunk');
	const CONSUMECHUNKSUB = Symbol('consumeChunkSub');
	const CONSUMEBODY = Symbol('consumeBody');
	const CONSUMEMETA = Symbol('consumeMeta');
	const CONSUMEHEADER = Symbol('consumeHeader');
	const CONSUMING = Symbol('consuming');
	const BUFFERCONCAT = Symbol('bufferConcat');
	const MAYBEEND = Symbol('maybeEnd');
	const WRITING = Symbol('writing');
	const ABORTED = Symbol('aborted');
	const DONE = Symbol('onDone');
	const SAW_VALID_ENTRY = Symbol('sawValidEntry');
	const SAW_NULL_BLOCK = Symbol('sawNullBlock');
	const SAW_EOF = Symbol('sawEOF');
	const CLOSESTREAM = Symbol('closeStream');

	const noop = _ => true;

	parse = warner(class Parser extends EE {
	  constructor (opt) {
	    opt = opt || {};
	    super(opt);

	    this.file = opt.file || '';

	    // set to boolean false when an entry starts.  1024 bytes of \0
	    // is technically a valid tarball, albeit a boring one.
	    this[SAW_VALID_ENTRY] = null;

	    // these BADARCHIVE errors can't be detected early. listen on DONE.
	    this.on(DONE, _ => {
	      if (this[STATE] === 'begin' || this[SAW_VALID_ENTRY] === false) {
	        // either less than 1 block of data, or all entries were invalid.
	        // Either way, probably not even a tarball.
	        this.warn('TAR_BAD_ARCHIVE', 'Unrecognized archive format');
	      }
	    });

	    if (opt.ondone) {
	      this.on(DONE, opt.ondone);
	    } else {
	      this.on(DONE, _ => {
	        this.emit('prefinish');
	        this.emit('finish');
	        this.emit('end');
	      });
	    }

	    this.strict = !!opt.strict;
	    this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize;
	    this.filter = typeof opt.filter === 'function' ? opt.filter : noop;
	    // Unlike gzip, brotli doesn't have any magic bytes to identify it
	    // Users need to explicitly tell us they're extracting a brotli file
	    // Or we infer from the file extension
	    const isTBR = (opt.file && (
	        opt.file.endsWith('.tar.br') || opt.file.endsWith('.tbr')));
	    // if it's a tbr file it MIGHT be brotli, but we don't know until
	    // we look at it and verify it's not a valid tar file.
	    this.brotli = !opt.gzip && opt.brotli !== undefined ? opt.brotli
	      : isTBR ? undefined
	      : false;

	    // have to set this so that streams are ok piping into it
	    this.writable = true;
	    this.readable = false;

	    this[QUEUE] = new Yallist();
	    this[BUFFER] = null;
	    this[READENTRY] = null;
	    this[WRITEENTRY] = null;
	    this[STATE] = 'begin';
	    this[META] = '';
	    this[EX] = null;
	    this[GEX] = null;
	    this[ENDED] = false;
	    this[UNZIP] = null;
	    this[ABORTED] = false;
	    this[SAW_NULL_BLOCK] = false;
	    this[SAW_EOF] = false;

	    this.on('end', () => this[CLOSESTREAM]());

	    if (typeof opt.onwarn === 'function') {
	      this.on('warn', opt.onwarn);
	    }
	    if (typeof opt.onentry === 'function') {
	      this.on('entry', opt.onentry);
	    }
	  }

	  [CONSUMEHEADER] (chunk, position) {
	    if (this[SAW_VALID_ENTRY] === null) {
	      this[SAW_VALID_ENTRY] = false;
	    }
	    let header;
	    try {
	      header = new Header(chunk, position, this[EX], this[GEX]);
	    } catch (er) {
	      return this.warn('TAR_ENTRY_INVALID', er)
	    }

	    if (header.nullBlock) {
	      if (this[SAW_NULL_BLOCK]) {
	        this[SAW_EOF] = true;
	        // ending an archive with no entries.  pointless, but legal.
	        if (this[STATE] === 'begin') {
	          this[STATE] = 'header';
	        }
	        this[EMIT]('eof');
	      } else {
	        this[SAW_NULL_BLOCK] = true;
	        this[EMIT]('nullBlock');
	      }
	    } else {
	      this[SAW_NULL_BLOCK] = false;
	      if (!header.cksumValid) {
	        this.warn('TAR_ENTRY_INVALID', 'checksum failure', { header });
	      } else if (!header.path) {
	        this.warn('TAR_ENTRY_INVALID', 'path is required', { header });
	      } else {
	        const type = header.type;
	        if (/^(Symbolic)?Link$/.test(type) && !header.linkpath) {
	          this.warn('TAR_ENTRY_INVALID', 'linkpath required', { header });
	        } else if (!/^(Symbolic)?Link$/.test(type) && header.linkpath) {
	          this.warn('TAR_ENTRY_INVALID', 'linkpath forbidden', { header });
	        } else {
	          const entry = this[WRITEENTRY] = new Entry(header, this[EX], this[GEX]);

	          // we do this for meta & ignored entries as well, because they
	          // are still valid tar, or else we wouldn't know to ignore them
	          if (!this[SAW_VALID_ENTRY]) {
	            if (entry.remain) {
	              // this might be the one!
	              const onend = () => {
	                if (!entry.invalid) {
	                  this[SAW_VALID_ENTRY] = true;
	                }
	              };
	              entry.on('end', onend);
	            } else {
	              this[SAW_VALID_ENTRY] = true;
	            }
	          }

	          if (entry.meta) {
	            if (entry.size > this.maxMetaEntrySize) {
	              entry.ignore = true;
	              this[EMIT]('ignoredEntry', entry);
	              this[STATE] = 'ignore';
	              entry.resume();
	            } else if (entry.size > 0) {
	              this[META] = '';
	              entry.on('data', c => this[META] += c);
	              this[STATE] = 'meta';
	            }
	          } else {
	            this[EX] = null;
	            entry.ignore = entry.ignore || !this.filter(entry.path, entry);

	            if (entry.ignore) {
	              // probably valid, just not something we care about
	              this[EMIT]('ignoredEntry', entry);
	              this[STATE] = entry.remain ? 'ignore' : 'header';
	              entry.resume();
	            } else {
	              if (entry.remain) {
	                this[STATE] = 'body';
	              } else {
	                this[STATE] = 'header';
	                entry.end();
	              }

	              if (!this[READENTRY]) {
	                this[QUEUE].push(entry);
	                this[NEXTENTRY]();
	              } else {
	                this[QUEUE].push(entry);
	              }
	            }
	          }
	        }
	      }
	    }
	  }

	  [CLOSESTREAM] () {
	    nextTick(() => this.emit('close'));
	  }

	  [PROCESSENTRY] (entry) {
	    let go = true;

	    if (!entry) {
	      this[READENTRY] = null;
	      go = false;
	    } else if (Array.isArray(entry)) {
	      this.emit.apply(this, entry);
	    } else {
	      this[READENTRY] = entry;
	      this.emit('entry', entry);
	      if (!entry.emittedEnd) {
	        entry.on('end', _ => this[NEXTENTRY]());
	        go = false;
	      }
	    }

	    return go
	  }

	  [NEXTENTRY] () {
	    do {} while (this[PROCESSENTRY](this[QUEUE].shift()))

	    if (!this[QUEUE].length) {
	      // At this point, there's nothing in the queue, but we may have an
	      // entry which is being consumed (readEntry).
	      // If we don't, then we definitely can handle more data.
	      // If we do, and either it's flowing, or it has never had any data
	      // written to it, then it needs more.
	      // The only other possibility is that it has returned false from a
	      // write() call, so we wait for the next drain to continue.
	      const re = this[READENTRY];
	      const drainNow = !re || re.flowing || re.size === re.remain;
	      if (drainNow) {
	        if (!this[WRITING]) {
	          this.emit('drain');
	        }
	      } else {
	        re.once('drain', _ => this.emit('drain'));
	      }
	    }
	  }

	  [CONSUMEBODY] (chunk, position) {
	    // write up to but no  more than writeEntry.blockRemain
	    const entry = this[WRITEENTRY];
	    const br = entry.blockRemain;
	    const c = (br >= chunk.length && position === 0) ? chunk
	      : chunk.slice(position, position + br);

	    entry.write(c);

	    if (!entry.blockRemain) {
	      this[STATE] = 'header';
	      this[WRITEENTRY] = null;
	      entry.end();
	    }

	    return c.length
	  }

	  [CONSUMEMETA] (chunk, position) {
	    const entry = this[WRITEENTRY];
	    const ret = this[CONSUMEBODY](chunk, position);

	    // if we finished, then the entry is reset
	    if (!this[WRITEENTRY]) {
	      this[EMITMETA](entry);
	    }

	    return ret
	  }

	  [EMIT] (ev, data, extra) {
	    if (!this[QUEUE].length && !this[READENTRY]) {
	      this.emit(ev, data, extra);
	    } else {
	      this[QUEUE].push([ev, data, extra]);
	    }
	  }

	  [EMITMETA] (entry) {
	    this[EMIT]('meta', this[META]);
	    switch (entry.type) {
	      case 'ExtendedHeader':
	      case 'OldExtendedHeader':
	        this[EX] = Pax.parse(this[META], this[EX], false);
	        break

	      case 'GlobalExtendedHeader':
	        this[GEX] = Pax.parse(this[META], this[GEX], true);
	        break

	      case 'NextFileHasLongPath':
	      case 'OldGnuLongPath':
	        this[EX] = this[EX] || Object.create(null);
	        this[EX].path = this[META].replace(/\0.*/, '');
	        break

	      case 'NextFileHasLongLinkpath':
	        this[EX] = this[EX] || Object.create(null);
	        this[EX].linkpath = this[META].replace(/\0.*/, '');
	        break

	      /* istanbul ignore next */
	      default: throw new Error('unknown meta: ' + entry.type)
	    }
	  }

	  abort (error) {
	    this[ABORTED] = true;
	    this.emit('abort', error);
	    // always throws, even in non-strict mode
	    this.warn('TAR_ABORT', error, { recoverable: false });
	  }

	  write (chunk) {
	    if (this[ABORTED]) {
	      return
	    }

	    // first write, might be gzipped
	    const needSniff = this[UNZIP] === null ||
	      this.brotli === undefined && this[UNZIP] === false;
	    if (needSniff && chunk) {
	      if (this[BUFFER]) {
	        chunk = Buffer.concat([this[BUFFER], chunk]);
	        this[BUFFER] = null;
	      }
	      if (chunk.length < gzipHeader.length) {
	        this[BUFFER] = chunk;
	        return true
	      }

	      // look for gzip header
	      for (let i = 0; this[UNZIP] === null && i < gzipHeader.length; i++) {
	        if (chunk[i] !== gzipHeader[i]) {
	          this[UNZIP] = false;
	        }
	      }

	      const maybeBrotli = this.brotli === undefined;
	      if (this[UNZIP] === false && maybeBrotli) {
	        // read the first header to see if it's a valid tar file. If so,
	        // we can safely assume that it's not actually brotli, despite the
	        // .tbr or .tar.br file extension.
	        // if we ended before getting a full chunk, yes, def brotli
	        if (chunk.length < 512) {
	          if (this[ENDED]) {
	            this.brotli = true;
	          } else {
	            this[BUFFER] = chunk;
	            return true
	          }
	        } else {
	          // if it's tar, it's pretty reliably not brotli, chances of
	          // that happening are astronomical.
	          try {
	            new Header(chunk.slice(0, 512));
	            this.brotli = false;
	          } catch (_) {
	            this.brotli = true;
	          }
	        }
	      }

	      if (this[UNZIP] === null || (this[UNZIP] === false && this.brotli)) {
	        const ended = this[ENDED];
	        this[ENDED] = false;
	        this[UNZIP] = this[UNZIP] === null
	          ? new zlib.Unzip()
	          : new zlib.BrotliDecompress();
	        this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk));
	        this[UNZIP].on('error', er => this.abort(er));
	        this[UNZIP].on('end', _ => {
	          this[ENDED] = true;
	          this[CONSUMECHUNK]();
	        });
	        this[WRITING] = true;
	        const ret = this[UNZIP][ended ? 'end' : 'write'](chunk);
	        this[WRITING] = false;
	        return ret
	      }
	    }

	    this[WRITING] = true;
	    if (this[UNZIP]) {
	      this[UNZIP].write(chunk);
	    } else {
	      this[CONSUMECHUNK](chunk);
	    }
	    this[WRITING] = false;

	    // return false if there's a queue, or if the current entry isn't flowing
	    const ret =
	      this[QUEUE].length ? false :
	      this[READENTRY] ? this[READENTRY].flowing :
	      true;

	    // if we have no queue, then that means a clogged READENTRY
	    if (!ret && !this[QUEUE].length) {
	      this[READENTRY].once('drain', _ => this.emit('drain'));
	    }

	    return ret
	  }

	  [BUFFERCONCAT] (c) {
	    if (c && !this[ABORTED]) {
	      this[BUFFER] = this[BUFFER] ? Buffer.concat([this[BUFFER], c]) : c;
	    }
	  }

	  [MAYBEEND] () {
	    if (this[ENDED] &&
	        !this[EMITTEDEND] &&
	        !this[ABORTED] &&
	        !this[CONSUMING]) {
	      this[EMITTEDEND] = true;
	      const entry = this[WRITEENTRY];
	      if (entry && entry.blockRemain) {
	        // truncated, likely a damaged file
	        const have = this[BUFFER] ? this[BUFFER].length : 0;
	        this.warn('TAR_BAD_ARCHIVE', `Truncated input (needed ${
	          entry.blockRemain} more bytes, only ${have} available)`, { entry });
	        if (this[BUFFER]) {
	          entry.write(this[BUFFER]);
	        }
	        entry.end();
	      }
	      this[EMIT](DONE);
	    }
	  }

	  [CONSUMECHUNK] (chunk) {
	    if (this[CONSUMING]) {
	      this[BUFFERCONCAT](chunk);
	    } else if (!chunk && !this[BUFFER]) {
	      this[MAYBEEND]();
	    } else {
	      this[CONSUMING] = true;
	      if (this[BUFFER]) {
	        this[BUFFERCONCAT](chunk);
	        const c = this[BUFFER];
	        this[BUFFER] = null;
	        this[CONSUMECHUNKSUB](c);
	      } else {
	        this[CONSUMECHUNKSUB](chunk);
	      }

	      while (this[BUFFER] &&
	          this[BUFFER].length >= 512 &&
	          !this[ABORTED] &&
	          !this[SAW_EOF]) {
	        const c = this[BUFFER];
	        this[BUFFER] = null;
	        this[CONSUMECHUNKSUB](c);
	      }
	      this[CONSUMING] = false;
	    }

	    if (!this[BUFFER] || this[ENDED]) {
	      this[MAYBEEND]();
	    }
	  }

	  [CONSUMECHUNKSUB] (chunk) {
	    // we know that we are in CONSUMING mode, so anything written goes into
	    // the buffer.  Advance the position and put any remainder in the buffer.
	    let position = 0;
	    const length = chunk.length;
	    while (position + 512 <= length && !this[ABORTED] && !this[SAW_EOF]) {
	      switch (this[STATE]) {
	        case 'begin':
	        case 'header':
	          this[CONSUMEHEADER](chunk, position);
	          position += 512;
	          break

	        case 'ignore':
	        case 'body':
	          position += this[CONSUMEBODY](chunk, position);
	          break

	        case 'meta':
	          position += this[CONSUMEMETA](chunk, position);
	          break

	        /* istanbul ignore next */
	        default:
	          throw new Error('invalid state: ' + this[STATE])
	      }
	    }

	    if (position < length) {
	      if (this[BUFFER]) {
	        this[BUFFER] = Buffer.concat([chunk.slice(position), this[BUFFER]]);
	      } else {
	        this[BUFFER] = chunk.slice(position);
	      }
	    }
	  }

	  end (chunk) {
	    if (!this[ABORTED]) {
	      if (this[UNZIP]) {
	        this[UNZIP].end(chunk);
	      } else {
	        this[ENDED] = true;
	        if (this.brotli === undefined) chunk = chunk || Buffer.alloc(0);
	        this.write(chunk);
	      }
	    }
	  }
	});
	return parse;
}

var list_1;
var hasRequiredList;

function requireList () {
	if (hasRequiredList) return list_1;
	hasRequiredList = 1;

	// XXX: This shares a lot in common with extract.js
	// maybe some DRY opportunity here?

	// tar -t
	const hlo = requireHighLevelOpt();
	const Parser = requireParse$2();
	const fs = require$$0$2;
	const fsm = requireFsMinipass();
	const path = require$$1;
	const stripSlash = requireStripTrailingSlashes();

	list_1 = (opt_, files, cb) => {
	  if (typeof opt_ === 'function') {
	    cb = opt_, files = null, opt_ = {};
	  } else if (Array.isArray(opt_)) {
	    files = opt_, opt_ = {};
	  }

	  if (typeof files === 'function') {
	    cb = files, files = null;
	  }

	  if (!files) {
	    files = [];
	  } else {
	    files = Array.from(files);
	  }

	  const opt = hlo(opt_);

	  if (opt.sync && typeof cb === 'function') {
	    throw new TypeError('callback not supported for sync tar functions')
	  }

	  if (!opt.file && typeof cb === 'function') {
	    throw new TypeError('callback only supported with file option')
	  }

	  if (files.length) {
	    filesFilter(opt, files);
	  }

	  if (!opt.noResume) {
	    onentryFunction(opt);
	  }

	  return opt.file && opt.sync ? listFileSync(opt)
	    : opt.file ? listFile(opt, cb)
	    : list(opt)
	};

	const onentryFunction = opt => {
	  const onentry = opt.onentry;
	  opt.onentry = onentry ? e => {
	    onentry(e);
	    e.resume();
	  } : e => e.resume();
	};

	// construct a filter that limits the file entries listed
	// include child entries if a dir is included
	const filesFilter = (opt, files) => {
	  const map = new Map(files.map(f => [stripSlash(f), true]));
	  const filter = opt.filter;

	  const mapHas = (file, r) => {
	    const root = r || path.parse(file).root || '.';
	    const ret = file === root ? false
	      : map.has(file) ? map.get(file)
	      : mapHas(path.dirname(file), root);

	    map.set(file, ret);
	    return ret
	  };

	  opt.filter = filter
	    ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file))
	    : file => mapHas(stripSlash(file));
	};

	const listFileSync = opt => {
	  const p = list(opt);
	  const file = opt.file;
	  let threw = true;
	  let fd;
	  try {
	    const stat = fs.statSync(file);
	    const readSize = opt.maxReadSize || 16 * 1024 * 1024;
	    if (stat.size < readSize) {
	      p.end(fs.readFileSync(file));
	    } else {
	      let pos = 0;
	      const buf = Buffer.allocUnsafe(readSize);
	      fd = fs.openSync(file, 'r');
	      while (pos < stat.size) {
	        const bytesRead = fs.readSync(fd, buf, 0, readSize, pos);
	        pos += bytesRead;
	        p.write(buf.slice(0, bytesRead));
	      }
	      p.end();
	    }
	    threw = false;
	  } finally {
	    if (threw && fd) {
	      try {
	        fs.closeSync(fd);
	      } catch (er) {}
	    }
	  }
	};

	const listFile = (opt, cb) => {
	  const parse = new Parser(opt);
	  const readSize = opt.maxReadSize || 16 * 1024 * 1024;

	  const file = opt.file;
	  const p = new Promise((resolve, reject) => {
	    parse.on('error', reject);
	    parse.on('end', resolve);

	    fs.stat(file, (er, stat) => {
	      if (er) {
	        reject(er);
	      } else {
	        const stream = new fsm.ReadStream(file, {
	          readSize: readSize,
	          size: stat.size,
	        });
	        stream.on('error', reject);
	        stream.pipe(parse);
	      }
	    });
	  });
	  return cb ? p.then(cb, cb) : p
	};

	const list = opt => new Parser(opt);
	return list_1;
}

var create_1;
var hasRequiredCreate;

function requireCreate () {
	if (hasRequiredCreate) return create_1;
	hasRequiredCreate = 1;

	// tar -c
	const hlo = requireHighLevelOpt();

	const Pack = requirePack();
	const fsm = requireFsMinipass();
	const t = requireList();
	const path = require$$1;

	create_1 = (opt_, files, cb) => {
	  if (typeof files === 'function') {
	    cb = files;
	  }

	  if (Array.isArray(opt_)) {
	    files = opt_, opt_ = {};
	  }

	  if (!files || !Array.isArray(files) || !files.length) {
	    throw new TypeError('no files or directories specified')
	  }

	  files = Array.from(files);

	  const opt = hlo(opt_);

	  if (opt.sync && typeof cb === 'function') {
	    throw new TypeError('callback not supported for sync tar functions')
	  }

	  if (!opt.file && typeof cb === 'function') {
	    throw new TypeError('callback only supported with file option')
	  }

	  return opt.file && opt.sync ? createFileSync(opt, files)
	    : opt.file ? createFile(opt, files, cb)
	    : opt.sync ? createSync(opt, files)
	    : create(opt, files)
	};

	const createFileSync = (opt, files) => {
	  const p = new Pack.Sync(opt);
	  const stream = new fsm.WriteStreamSync(opt.file, {
	    mode: opt.mode || 0o666,
	  });
	  p.pipe(stream);
	  addFilesSync(p, files);
	};

	const createFile = (opt, files, cb) => {
	  const p = new Pack(opt);
	  const stream = new fsm.WriteStream(opt.file, {
	    mode: opt.mode || 0o666,
	  });
	  p.pipe(stream);

	  const promise = new Promise((res, rej) => {
	    stream.on('error', rej);
	    stream.on('close', res);
	    p.on('error', rej);
	  });

	  addFilesAsync(p, files);

	  return cb ? promise.then(cb, cb) : promise
	};

	const addFilesSync = (p, files) => {
	  files.forEach(file => {
	    if (file.charAt(0) === '@') {
	      t({
	        file: path.resolve(p.cwd, file.slice(1)),
	        sync: true,
	        noResume: true,
	        onentry: entry => p.add(entry),
	      });
	    } else {
	      p.add(file);
	    }
	  });
	  p.end();
	};

	const addFilesAsync = (p, files) => {
	  while (files.length) {
	    const file = files.shift();
	    if (file.charAt(0) === '@') {
	      return t({
	        file: path.resolve(p.cwd, file.slice(1)),
	        noResume: true,
	        onentry: entry => p.add(entry),
	      }).then(_ => addFilesAsync(p, files))
	    } else {
	      p.add(file);
	    }
	  }
	  p.end();
	};

	const createSync = (opt, files) => {
	  const p = new Pack.Sync(opt);
	  addFilesSync(p, files);
	  return p
	};

	const create = (opt, files) => {
	  const p = new Pack(opt);
	  addFilesAsync(p, files);
	  return p
	};
	return create_1;
}

var replace_1;
var hasRequiredReplace;

function requireReplace () {
	if (hasRequiredReplace) return replace_1;
	hasRequiredReplace = 1;

	// tar -r
	const hlo = requireHighLevelOpt();
	const Pack = requirePack();
	const fs = require$$0$2;
	const fsm = requireFsMinipass();
	const t = requireList();
	const path = require$$1;

	// starting at the head of the file, read a Header
	// If the checksum is invalid, that's our position to start writing
	// If it is, jump forward by the specified size (round up to 512)
	// and try again.
	// Write the new Pack stream starting there.

	const Header = requireHeader();

	replace_1 = (opt_, files, cb) => {
	  const opt = hlo(opt_);

	  if (!opt.file) {
	    throw new TypeError('file is required')
	  }

	  if (opt.gzip || opt.brotli || opt.file.endsWith('.br') || opt.file.endsWith('.tbr')) {
	    throw new TypeError('cannot append to compressed archives')
	  }

	  if (!files || !Array.isArray(files) || !files.length) {
	    throw new TypeError('no files or directories specified')
	  }

	  files = Array.from(files);

	  return opt.sync ? replaceSync(opt, files)
	    : replace(opt, files, cb)
	};

	const replaceSync = (opt, files) => {
	  const p = new Pack.Sync(opt);

	  let threw = true;
	  let fd;
	  let position;

	  try {
	    try {
	      fd = fs.openSync(opt.file, 'r+');
	    } catch (er) {
	      if (er.code === 'ENOENT') {
	        fd = fs.openSync(opt.file, 'w+');
	      } else {
	        throw er
	      }
	    }

	    const st = fs.fstatSync(fd);
	    const headBuf = Buffer.alloc(512);

	    POSITION: for (position = 0; position < st.size; position += 512) {
	      for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) {
	        bytes = fs.readSync(
	          fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos
	        );

	        if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) {
	          throw new Error('cannot append to compressed archives')
	        }

	        if (!bytes) {
	          break POSITION
	        }
	      }

	      const h = new Header(headBuf);
	      if (!h.cksumValid) {
	        break
	      }
	      const entryBlockSize = 512 * Math.ceil(h.size / 512);
	      if (position + entryBlockSize + 512 > st.size) {
	        break
	      }
	      // the 512 for the header we just parsed will be added as well
	      // also jump ahead all the blocks for the body
	      position += entryBlockSize;
	      if (opt.mtimeCache) {
	        opt.mtimeCache.set(h.path, h.mtime);
	      }
	    }
	    threw = false;

	    streamSync(opt, p, position, fd, files);
	  } finally {
	    if (threw) {
	      try {
	        fs.closeSync(fd);
	      } catch (er) {}
	    }
	  }
	};

	const streamSync = (opt, p, position, fd, files) => {
	  const stream = new fsm.WriteStreamSync(opt.file, {
	    fd: fd,
	    start: position,
	  });
	  p.pipe(stream);
	  addFilesSync(p, files);
	};

	const replace = (opt, files, cb) => {
	  files = Array.from(files);
	  const p = new Pack(opt);

	  const getPos = (fd, size, cb_) => {
	    const cb = (er, pos) => {
	      if (er) {
	        fs.close(fd, _ => cb_(er));
	      } else {
	        cb_(null, pos);
	      }
	    };

	    let position = 0;
	    if (size === 0) {
	      return cb(null, 0)
	    }

	    let bufPos = 0;
	    const headBuf = Buffer.alloc(512);
	    const onread = (er, bytes) => {
	      if (er) {
	        return cb(er)
	      }
	      bufPos += bytes;
	      if (bufPos < 512 && bytes) {
	        return fs.read(
	          fd, headBuf, bufPos, headBuf.length - bufPos,
	          position + bufPos, onread
	        )
	      }

	      if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) {
	        return cb(new Error('cannot append to compressed archives'))
	      }

	      // truncated header
	      if (bufPos < 512) {
	        return cb(null, position)
	      }

	      const h = new Header(headBuf);
	      if (!h.cksumValid) {
	        return cb(null, position)
	      }

	      const entryBlockSize = 512 * Math.ceil(h.size / 512);
	      if (position + entryBlockSize + 512 > size) {
	        return cb(null, position)
	      }

	      position += entryBlockSize + 512;
	      if (position >= size) {
	        return cb(null, position)
	      }

	      if (opt.mtimeCache) {
	        opt.mtimeCache.set(h.path, h.mtime);
	      }
	      bufPos = 0;
	      fs.read(fd, headBuf, 0, 512, position, onread);
	    };
	    fs.read(fd, headBuf, 0, 512, position, onread);
	  };

	  const promise = new Promise((resolve, reject) => {
	    p.on('error', reject);
	    let flag = 'r+';
	    const onopen = (er, fd) => {
	      if (er && er.code === 'ENOENT' && flag === 'r+') {
	        flag = 'w+';
	        return fs.open(opt.file, flag, onopen)
	      }

	      if (er) {
	        return reject(er)
	      }

	      fs.fstat(fd, (er, st) => {
	        if (er) {
	          return fs.close(fd, () => reject(er))
	        }

	        getPos(fd, st.size, (er, position) => {
	          if (er) {
	            return reject(er)
	          }
	          const stream = new fsm.WriteStream(opt.file, {
	            fd: fd,
	            start: position,
	          });
	          p.pipe(stream);
	          stream.on('error', reject);
	          stream.on('close', resolve);
	          addFilesAsync(p, files);
	        });
	      });
	    };
	    fs.open(opt.file, flag, onopen);
	  });

	  return cb ? promise.then(cb, cb) : promise
	};

	const addFilesSync = (p, files) => {
	  files.forEach(file => {
	    if (file.charAt(0) === '@') {
	      t({
	        file: path.resolve(p.cwd, file.slice(1)),
	        sync: true,
	        noResume: true,
	        onentry: entry => p.add(entry),
	      });
	    } else {
	      p.add(file);
	    }
	  });
	  p.end();
	};

	const addFilesAsync = (p, files) => {
	  while (files.length) {
	    const file = files.shift();
	    if (file.charAt(0) === '@') {
	      return t({
	        file: path.resolve(p.cwd, file.slice(1)),
	        noResume: true,
	        onentry: entry => p.add(entry),
	      }).then(_ => addFilesAsync(p, files))
	    } else {
	      p.add(file);
	    }
	  }
	  p.end();
	};
	return replace_1;
}

var update;
var hasRequiredUpdate;

function requireUpdate () {
	if (hasRequiredUpdate) return update;
	hasRequiredUpdate = 1;

	// tar -u

	const hlo = requireHighLevelOpt();
	const r = requireReplace();
	// just call tar.r with the filter and mtimeCache

	update = (opt_, files, cb) => {
	  const opt = hlo(opt_);

	  if (!opt.file) {
	    throw new TypeError('file is required')
	  }

	  if (opt.gzip || opt.brotli || opt.file.endsWith('.br') || opt.file.endsWith('.tbr')) {
	    throw new TypeError('cannot append to compressed archives')
	  }

	  if (!files || !Array.isArray(files) || !files.length) {
	    throw new TypeError('no files or directories specified')
	  }

	  files = Array.from(files);

	  mtimeFilter(opt);
	  return r(opt, files, cb)
	};

	const mtimeFilter = opt => {
	  const filter = opt.filter;

	  if (!opt.mtimeCache) {
	    opt.mtimeCache = new Map();
	  }

	  opt.filter = filter ? (path, stat) =>
	    filter(path, stat) && !(opt.mtimeCache.get(path) > stat.mtime)
	    : (path, stat) => !(opt.mtimeCache.get(path) > stat.mtime);
	};
	return update;
}

var mkdir = {exports: {}};

var optsArg_1;
var hasRequiredOptsArg;

function requireOptsArg () {
	if (hasRequiredOptsArg) return optsArg_1;
	hasRequiredOptsArg = 1;
	const { promisify } = require$$0$5;
	const fs = require$$0$2;
	const optsArg = opts => {
	  if (!opts)
	    opts = { mode: 0o777, fs };
	  else if (typeof opts === 'object')
	    opts = { mode: 0o777, fs, ...opts };
	  else if (typeof opts === 'number')
	    opts = { mode: opts, fs };
	  else if (typeof opts === 'string')
	    opts = { mode: parseInt(opts, 8), fs };
	  else
	    throw new TypeError('invalid options argument')

	  opts.mkdir = opts.mkdir || opts.fs.mkdir || fs.mkdir;
	  opts.mkdirAsync = promisify(opts.mkdir);
	  opts.stat = opts.stat || opts.fs.stat || fs.stat;
	  opts.statAsync = promisify(opts.stat);
	  opts.statSync = opts.statSync || opts.fs.statSync || fs.statSync;
	  opts.mkdirSync = opts.mkdirSync || opts.fs.mkdirSync || fs.mkdirSync;
	  return opts
	};
	optsArg_1 = optsArg;
	return optsArg_1;
}

var pathArg_1;
var hasRequiredPathArg;

function requirePathArg () {
	if (hasRequiredPathArg) return pathArg_1;
	hasRequiredPathArg = 1;
	const platform = process.env.__TESTING_MKDIRP_PLATFORM__ || process.platform;
	const { resolve, parse } = require$$1;
	const pathArg = path => {
	  if (/\0/.test(path)) {
	    // simulate same failure that node raises
	    throw Object.assign(
	      new TypeError('path must be a string without null bytes'),
	      {
	        path,
	        code: 'ERR_INVALID_ARG_VALUE',
	      }
	    )
	  }

	  path = resolve(path);
	  if (platform === 'win32') {
	    const badWinChars = /[*|"<>?:]/;
	    const {root} = parse(path);
	    if (badWinChars.test(path.substr(root.length))) {
	      throw Object.assign(new Error('Illegal characters in path.'), {
	        path,
	        code: 'EINVAL',
	      })
	    }
	  }

	  return path
	};
	pathArg_1 = pathArg;
	return pathArg_1;
}

var findMade_1;
var hasRequiredFindMade;

function requireFindMade () {
	if (hasRequiredFindMade) return findMade_1;
	hasRequiredFindMade = 1;
	const {dirname} = require$$1;

	const findMade = (opts, parent, path = undefined) => {
	  // we never want the 'made' return value to be a root directory
	  if (path === parent)
	    return Promise.resolve()

	  return opts.statAsync(parent).then(
	    st => st.isDirectory() ? path : undefined, // will fail later
	    er => er.code === 'ENOENT'
	      ? findMade(opts, dirname(parent), parent)
	      : undefined
	  )
	};

	const findMadeSync = (opts, parent, path = undefined) => {
	  if (path === parent)
	    return undefined

	  try {
	    return opts.statSync(parent).isDirectory() ? path : undefined
	  } catch (er) {
	    return er.code === 'ENOENT'
	      ? findMadeSync(opts, dirname(parent), parent)
	      : undefined
	  }
	};

	findMade_1 = {findMade, findMadeSync};
	return findMade_1;
}

var mkdirpManual_1;
var hasRequiredMkdirpManual;

function requireMkdirpManual () {
	if (hasRequiredMkdirpManual) return mkdirpManual_1;
	hasRequiredMkdirpManual = 1;
	const {dirname} = require$$1;

	const mkdirpManual = (path, opts, made) => {
	  opts.recursive = false;
	  const parent = dirname(path);
	  if (parent === path) {
	    return opts.mkdirAsync(path, opts).catch(er => {
	      // swallowed by recursive implementation on posix systems
	      // any other error is a failure
	      if (er.code !== 'EISDIR')
	        throw er
	    })
	  }

	  return opts.mkdirAsync(path, opts).then(() => made || path, er => {
	    if (er.code === 'ENOENT')
	      return mkdirpManual(parent, opts)
	        .then(made => mkdirpManual(path, opts, made))
	    if (er.code !== 'EEXIST' && er.code !== 'EROFS')
	      throw er
	    return opts.statAsync(path).then(st => {
	      if (st.isDirectory())
	        return made
	      else
	        throw er
	    }, () => { throw er })
	  })
	};

	const mkdirpManualSync = (path, opts, made) => {
	  const parent = dirname(path);
	  opts.recursive = false;

	  if (parent === path) {
	    try {
	      return opts.mkdirSync(path, opts)
	    } catch (er) {
	      // swallowed by recursive implementation on posix systems
	      // any other error is a failure
	      if (er.code !== 'EISDIR')
	        throw er
	      else
	        return
	    }
	  }

	  try {
	    opts.mkdirSync(path, opts);
	    return made || path
	  } catch (er) {
	    if (er.code === 'ENOENT')
	      return mkdirpManualSync(path, opts, mkdirpManualSync(parent, opts, made))
	    if (er.code !== 'EEXIST' && er.code !== 'EROFS')
	      throw er
	    try {
	      if (!opts.statSync(path).isDirectory())
	        throw er
	    } catch (_) {
	      throw er
	    }
	  }
	};

	mkdirpManual_1 = {mkdirpManual, mkdirpManualSync};
	return mkdirpManual_1;
}

var mkdirpNative_1;
var hasRequiredMkdirpNative;

function requireMkdirpNative () {
	if (hasRequiredMkdirpNative) return mkdirpNative_1;
	hasRequiredMkdirpNative = 1;
	const {dirname} = require$$1;
	const {findMade, findMadeSync} = requireFindMade();
	const {mkdirpManual, mkdirpManualSync} = requireMkdirpManual();

	const mkdirpNative = (path, opts) => {
	  opts.recursive = true;
	  const parent = dirname(path);
	  if (parent === path)
	    return opts.mkdirAsync(path, opts)

	  return findMade(opts, path).then(made =>
	    opts.mkdirAsync(path, opts).then(() => made)
	    .catch(er => {
	      if (er.code === 'ENOENT')
	        return mkdirpManual(path, opts)
	      else
	        throw er
	    }))
	};

	const mkdirpNativeSync = (path, opts) => {
	  opts.recursive = true;
	  const parent = dirname(path);
	  if (parent === path)
	    return opts.mkdirSync(path, opts)

	  const made = findMadeSync(opts, path);
	  try {
	    opts.mkdirSync(path, opts);
	    return made
	  } catch (er) {
	    if (er.code === 'ENOENT')
	      return mkdirpManualSync(path, opts)
	    else
	      throw er
	  }
	};

	mkdirpNative_1 = {mkdirpNative, mkdirpNativeSync};
	return mkdirpNative_1;
}

var useNative_1;
var hasRequiredUseNative;

function requireUseNative () {
	if (hasRequiredUseNative) return useNative_1;
	hasRequiredUseNative = 1;
	const fs = require$$0$2;

	const version = process.env.__TESTING_MKDIRP_NODE_VERSION__ || process.version;
	const versArr = version.replace(/^v/, '').split('.');
	const hasNative = +versArr[0] > 10 || +versArr[0] === 10 && +versArr[1] >= 12;

	const useNative = !hasNative ? () => false : opts => opts.mkdir === fs.mkdir;
	const useNativeSync = !hasNative ? () => false : opts => opts.mkdirSync === fs.mkdirSync;

	useNative_1 = {useNative, useNativeSync};
	return useNative_1;
}

var mkdirp_1;
var hasRequiredMkdirp;

function requireMkdirp () {
	if (hasRequiredMkdirp) return mkdirp_1;
	hasRequiredMkdirp = 1;
	const optsArg = requireOptsArg();
	const pathArg = requirePathArg();

	const {mkdirpNative, mkdirpNativeSync} = requireMkdirpNative();
	const {mkdirpManual, mkdirpManualSync} = requireMkdirpManual();
	const {useNative, useNativeSync} = requireUseNative();


	const mkdirp = (path, opts) => {
	  path = pathArg(path);
	  opts = optsArg(opts);
	  return useNative(opts)
	    ? mkdirpNative(path, opts)
	    : mkdirpManual(path, opts)
	};

	const mkdirpSync = (path, opts) => {
	  path = pathArg(path);
	  opts = optsArg(opts);
	  return useNativeSync(opts)
	    ? mkdirpNativeSync(path, opts)
	    : mkdirpManualSync(path, opts)
	};

	mkdirp.sync = mkdirpSync;
	mkdirp.native = (path, opts) => mkdirpNative(pathArg(path), optsArg(opts));
	mkdirp.manual = (path, opts) => mkdirpManual(pathArg(path), optsArg(opts));
	mkdirp.nativeSync = (path, opts) => mkdirpNativeSync(pathArg(path), optsArg(opts));
	mkdirp.manualSync = (path, opts) => mkdirpManualSync(pathArg(path), optsArg(opts));

	mkdirp_1 = mkdirp;
	return mkdirp_1;
}

var chownr_1;
var hasRequiredChownr;

function requireChownr () {
	if (hasRequiredChownr) return chownr_1;
	hasRequiredChownr = 1;
	const fs = require$$0$2;
	const path = require$$1;

	/* istanbul ignore next */
	const LCHOWN = fs.lchown ? 'lchown' : 'chown';
	/* istanbul ignore next */
	const LCHOWNSYNC = fs.lchownSync ? 'lchownSync' : 'chownSync';

	/* istanbul ignore next */
	const needEISDIRHandled = fs.lchown &&
	  !process.version.match(/v1[1-9]+\./) &&
	  !process.version.match(/v10\.[6-9]/);

	const lchownSync = (path, uid, gid) => {
	  try {
	    return fs[LCHOWNSYNC](path, uid, gid)
	  } catch (er) {
	    if (er.code !== 'ENOENT')
	      throw er
	  }
	};

	/* istanbul ignore next */
	const chownSync = (path, uid, gid) => {
	  try {
	    return fs.chownSync(path, uid, gid)
	  } catch (er) {
	    if (er.code !== 'ENOENT')
	      throw er
	  }
	};

	/* istanbul ignore next */
	const handleEISDIR =
	  needEISDIRHandled ? (path, uid, gid, cb) => er => {
	    // Node prior to v10 had a very questionable implementation of
	    // fs.lchown, which would always try to call fs.open on a directory
	    // Fall back to fs.chown in those cases.
	    if (!er || er.code !== 'EISDIR')
	      cb(er);
	    else
	      fs.chown(path, uid, gid, cb);
	  }
	  : (_, __, ___, cb) => cb;

	/* istanbul ignore next */
	const handleEISDirSync =
	  needEISDIRHandled ? (path, uid, gid) => {
	    try {
	      return lchownSync(path, uid, gid)
	    } catch (er) {
	      if (er.code !== 'EISDIR')
	        throw er
	      chownSync(path, uid, gid);
	    }
	  }
	  : (path, uid, gid) => lchownSync(path, uid, gid);

	// fs.readdir could only accept an options object as of node v6
	const nodeVersion = process.version;
	let readdir = (path, options, cb) => fs.readdir(path, options, cb);
	let readdirSync = (path, options) => fs.readdirSync(path, options);
	/* istanbul ignore next */
	if (/^v4\./.test(nodeVersion))
	  readdir = (path, options, cb) => fs.readdir(path, cb);

	const chown = (cpath, uid, gid, cb) => {
	  fs[LCHOWN](cpath, uid, gid, handleEISDIR(cpath, uid, gid, er => {
	    // Skip ENOENT error
	    cb(er && er.code !== 'ENOENT' ? er : null);
	  }));
	};

	const chownrKid = (p, child, uid, gid, cb) => {
	  if (typeof child === 'string')
	    return fs.lstat(path.resolve(p, child), (er, stats) => {
	      // Skip ENOENT error
	      if (er)
	        return cb(er.code !== 'ENOENT' ? er : null)
	      stats.name = child;
	      chownrKid(p, stats, uid, gid, cb);
	    })

	  if (child.isDirectory()) {
	    chownr(path.resolve(p, child.name), uid, gid, er => {
	      if (er)
	        return cb(er)
	      const cpath = path.resolve(p, child.name);
	      chown(cpath, uid, gid, cb);
	    });
	  } else {
	    const cpath = path.resolve(p, child.name);
	    chown(cpath, uid, gid, cb);
	  }
	};


	const chownr = (p, uid, gid, cb) => {
	  readdir(p, { withFileTypes: true }, (er, children) => {
	    // any error other than ENOTDIR or ENOTSUP means it's not readable,
	    // or doesn't exist.  give up.
	    if (er) {
	      if (er.code === 'ENOENT')
	        return cb()
	      else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')
	        return cb(er)
	    }
	    if (er || !children.length)
	      return chown(p, uid, gid, cb)

	    let len = children.length;
	    let errState = null;
	    const then = er => {
	      if (errState)
	        return
	      if (er)
	        return cb(errState = er)
	      if (-- len === 0)
	        return chown(p, uid, gid, cb)
	    };

	    children.forEach(child => chownrKid(p, child, uid, gid, then));
	  });
	};

	const chownrKidSync = (p, child, uid, gid) => {
	  if (typeof child === 'string') {
	    try {
	      const stats = fs.lstatSync(path.resolve(p, child));
	      stats.name = child;
	      child = stats;
	    } catch (er) {
	      if (er.code === 'ENOENT')
	        return
	      else
	        throw er
	    }
	  }

	  if (child.isDirectory())
	    chownrSync(path.resolve(p, child.name), uid, gid);

	  handleEISDirSync(path.resolve(p, child.name), uid, gid);
	};

	const chownrSync = (p, uid, gid) => {
	  let children;
	  try {
	    children = readdirSync(p, { withFileTypes: true });
	  } catch (er) {
	    if (er.code === 'ENOENT')
	      return
	    else if (er.code === 'ENOTDIR' || er.code === 'ENOTSUP')
	      return handleEISDirSync(p, uid, gid)
	    else
	      throw er
	  }

	  if (children && children.length)
	    children.forEach(child => chownrKidSync(p, child, uid, gid));

	  return handleEISDirSync(p, uid, gid)
	};

	chownr_1 = chownr;
	chownr.sync = chownrSync;
	return chownr_1;
}

var hasRequiredMkdir;

function requireMkdir () {
	if (hasRequiredMkdir) return mkdir.exports;
	hasRequiredMkdir = 1;
	// wrapper around mkdirp for tar's needs.

	// TODO: This should probably be a class, not functionally
	// passing around state in a gazillion args.

	const mkdirp = requireMkdirp();
	const fs = require$$0$2;
	const path = require$$1;
	const chownr = requireChownr();
	const normPath = requireNormalizeWindowsPath();

	class SymlinkError extends Error {
	  constructor (symlink, path) {
	    super('Cannot extract through symbolic link');
	    this.path = path;
	    this.symlink = symlink;
	  }

	  get name () {
	    return 'SylinkError'
	  }
	}

	class CwdError extends Error {
	  constructor (path, code) {
	    super(code + ': Cannot cd into \'' + path + '\'');
	    this.path = path;
	    this.code = code;
	  }

	  get name () {
	    return 'CwdError'
	  }
	}

	const cGet = (cache, key) => cache.get(normPath(key));
	const cSet = (cache, key, val) => cache.set(normPath(key), val);

	const checkCwd = (dir, cb) => {
	  fs.stat(dir, (er, st) => {
	    if (er || !st.isDirectory()) {
	      er = new CwdError(dir, er && er.code || 'ENOTDIR');
	    }
	    cb(er);
	  });
	};

	mkdir.exports = (dir, opt, cb) => {
	  dir = normPath(dir);

	  // if there's any overlap between mask and mode,
	  // then we'll need an explicit chmod
	  const umask = opt.umask;
	  const mode = opt.mode | 0o0700;
	  const needChmod = (mode & umask) !== 0;

	  const uid = opt.uid;
	  const gid = opt.gid;
	  const doChown = typeof uid === 'number' &&
	    typeof gid === 'number' &&
	    (uid !== opt.processUid || gid !== opt.processGid);

	  const preserve = opt.preserve;
	  const unlink = opt.unlink;
	  const cache = opt.cache;
	  const cwd = normPath(opt.cwd);

	  const done = (er, created) => {
	    if (er) {
	      cb(er);
	    } else {
	      cSet(cache, dir, true);
	      if (created && doChown) {
	        chownr(created, uid, gid, er => done(er));
	      } else if (needChmod) {
	        fs.chmod(dir, mode, cb);
	      } else {
	        cb();
	      }
	    }
	  };

	  if (cache && cGet(cache, dir) === true) {
	    return done()
	  }

	  if (dir === cwd) {
	    return checkCwd(dir, done)
	  }

	  if (preserve) {
	    return mkdirp(dir, { mode }).then(made => done(null, made), done)
	  }

	  const sub = normPath(path.relative(cwd, dir));
	  const parts = sub.split('/');
	  mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done);
	};

	const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => {
	  if (!parts.length) {
	    return cb(null, created)
	  }
	  const p = parts.shift();
	  const part = normPath(path.resolve(base + '/' + p));
	  if (cGet(cache, part)) {
	    return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb)
	  }
	  fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb));
	};

	const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => {
	  if (er) {
	    fs.lstat(part, (statEr, st) => {
	      if (statEr) {
	        statEr.path = statEr.path && normPath(statEr.path);
	        cb(statEr);
	      } else if (st.isDirectory()) {
	        mkdir_(part, parts, mode, cache, unlink, cwd, created, cb);
	      } else if (unlink) {
	        fs.unlink(part, er => {
	          if (er) {
	            return cb(er)
	          }
	          fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb));
	        });
	      } else if (st.isSymbolicLink()) {
	        return cb(new SymlinkError(part, part + '/' + parts.join('/')))
	      } else {
	        cb(er);
	      }
	    });
	  } else {
	    created = created || part;
	    mkdir_(part, parts, mode, cache, unlink, cwd, created, cb);
	  }
	};

	const checkCwdSync = dir => {
	  let ok = false;
	  let code = 'ENOTDIR';
	  try {
	    ok = fs.statSync(dir).isDirectory();
	  } catch (er) {
	    code = er.code;
	  } finally {
	    if (!ok) {
	      throw new CwdError(dir, code)
	    }
	  }
	};

	mkdir.exports.sync = (dir, opt) => {
	  dir = normPath(dir);
	  // if there's any overlap between mask and mode,
	  // then we'll need an explicit chmod
	  const umask = opt.umask;
	  const mode = opt.mode | 0o0700;
	  const needChmod = (mode & umask) !== 0;

	  const uid = opt.uid;
	  const gid = opt.gid;
	  const doChown = typeof uid === 'number' &&
	    typeof gid === 'number' &&
	    (uid !== opt.processUid || gid !== opt.processGid);

	  const preserve = opt.preserve;
	  const unlink = opt.unlink;
	  const cache = opt.cache;
	  const cwd = normPath(opt.cwd);

	  const done = (created) => {
	    cSet(cache, dir, true);
	    if (created && doChown) {
	      chownr.sync(created, uid, gid);
	    }
	    if (needChmod) {
	      fs.chmodSync(dir, mode);
	    }
	  };

	  if (cache && cGet(cache, dir) === true) {
	    return done()
	  }

	  if (dir === cwd) {
	    checkCwdSync(cwd);
	    return done()
	  }

	  if (preserve) {
	    return done(mkdirp.sync(dir, mode))
	  }

	  const sub = normPath(path.relative(cwd, dir));
	  const parts = sub.split('/');
	  let created = null;
	  for (let p = parts.shift(), part = cwd;
	    p && (part += '/' + p);
	    p = parts.shift()) {
	    part = normPath(path.resolve(part));
	    if (cGet(cache, part)) {
	      continue
	    }

	    try {
	      fs.mkdirSync(part, mode);
	      created = created || part;
	      cSet(cache, part, true);
	    } catch (er) {
	      const st = fs.lstatSync(part);
	      if (st.isDirectory()) {
	        cSet(cache, part, true);
	        continue
	      } else if (unlink) {
	        fs.unlinkSync(part);
	        fs.mkdirSync(part, mode);
	        created = created || part;
	        cSet(cache, part, true);
	        continue
	      } else if (st.isSymbolicLink()) {
	        return new SymlinkError(part, part + '/' + parts.join('/'))
	      }
	    }
	  }

	  return done(created)
	};
	return mkdir.exports;
}

var normalizeUnicode;
var hasRequiredNormalizeUnicode;

function requireNormalizeUnicode () {
	if (hasRequiredNormalizeUnicode) return normalizeUnicode;
	hasRequiredNormalizeUnicode = 1;
	// warning: extremely hot code path.
	// This has been meticulously optimized for use
	// within npm install on large package trees.
	// Do not edit without careful benchmarking.
	const normalizeCache = Object.create(null);
	const { hasOwnProperty } = Object.prototype;
	normalizeUnicode = s => {
	  if (!hasOwnProperty.call(normalizeCache, s)) {
	    normalizeCache[s] = s.normalize('NFD');
	  }
	  return normalizeCache[s]
	};
	return normalizeUnicode;
}

var pathReservations;
var hasRequiredPathReservations;

function requirePathReservations () {
	if (hasRequiredPathReservations) return pathReservations;
	hasRequiredPathReservations = 1;
	// A path exclusive reservation system
	// reserve([list, of, paths], fn)
	// When the fn is first in line for all its paths, it
	// is called with a cb that clears the reservation.
	//
	// Used by async unpack to avoid clobbering paths in use,
	// while still allowing maximal safe parallelization.

	const assert = require$$5;
	const normalize = requireNormalizeUnicode();
	const stripSlashes = requireStripTrailingSlashes();
	const { join } = require$$1;

	const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
	const isWindows = platform === 'win32';

	pathReservations = () => {
	  // path => [function or Set]
	  // A Set object means a directory reservation
	  // A fn is a direct reservation on that path
	  const queues = new Map();

	  // fn => {paths:[path,...], dirs:[path, ...]}
	  const reservations = new Map();

	  // return a set of parent dirs for a given path
	  // '/a/b/c/d' -> ['/', '/a', '/a/b', '/a/b/c', '/a/b/c/d']
	  const getDirs = path => {
	    const dirs = path.split('/').slice(0, -1).reduce((set, path) => {
	      if (set.length) {
	        path = join(set[set.length - 1], path);
	      }
	      set.push(path || '/');
	      return set
	    }, []);
	    return dirs
	  };

	  // functions currently running
	  const running = new Set();

	  // return the queues for each path the function cares about
	  // fn => {paths, dirs}
	  const getQueues = fn => {
	    const res = reservations.get(fn);
	    /* istanbul ignore if - unpossible */
	    if (!res) {
	      throw new Error('function does not have any path reservations')
	    }
	    return {
	      paths: res.paths.map(path => queues.get(path)),
	      dirs: [...res.dirs].map(path => queues.get(path)),
	    }
	  };

	  // check if fn is first in line for all its paths, and is
	  // included in the first set for all its dir queues
	  const check = fn => {
	    const { paths, dirs } = getQueues(fn);
	    return paths.every(q => q[0] === fn) &&
	      dirs.every(q => q[0] instanceof Set && q[0].has(fn))
	  };

	  // run the function if it's first in line and not already running
	  const run = fn => {
	    if (running.has(fn) || !check(fn)) {
	      return false
	    }
	    running.add(fn);
	    fn(() => clear(fn));
	    return true
	  };

	  const clear = fn => {
	    if (!running.has(fn)) {
	      return false
	    }

	    const { paths, dirs } = reservations.get(fn);
	    const next = new Set();

	    paths.forEach(path => {
	      const q = queues.get(path);
	      assert.equal(q[0], fn);
	      if (q.length === 1) {
	        queues.delete(path);
	      } else {
	        q.shift();
	        if (typeof q[0] === 'function') {
	          next.add(q[0]);
	        } else {
	          q[0].forEach(fn => next.add(fn));
	        }
	      }
	    });

	    dirs.forEach(dir => {
	      const q = queues.get(dir);
	      assert(q[0] instanceof Set);
	      if (q[0].size === 1 && q.length === 1) {
	        queues.delete(dir);
	      } else if (q[0].size === 1) {
	        q.shift();

	        // must be a function or else the Set would've been reused
	        next.add(q[0]);
	      } else {
	        q[0].delete(fn);
	      }
	    });
	    running.delete(fn);

	    next.forEach(fn => run(fn));
	    return true
	  };

	  const reserve = (paths, fn) => {
	    // collide on matches across case and unicode normalization
	    // On windows, thanks to the magic of 8.3 shortnames, it is fundamentally
	    // impossible to determine whether two paths refer to the same thing on
	    // disk, without asking the kernel for a shortname.
	    // So, we just pretend that every path matches every other path here,
	    // effectively removing all parallelization on windows.
	    paths = isWindows ? ['win32 parallelization disabled'] : paths.map(p => {
	      // don't need normPath, because we skip this entirely for windows
	      return stripSlashes(join(normalize(p))).toLowerCase()
	    });

	    const dirs = new Set(
	      paths.map(path => getDirs(path)).reduce((a, b) => a.concat(b))
	    );
	    reservations.set(fn, { dirs, paths });
	    paths.forEach(path => {
	      const q = queues.get(path);
	      if (!q) {
	        queues.set(path, [fn]);
	      } else {
	        q.push(fn);
	      }
	    });
	    dirs.forEach(dir => {
	      const q = queues.get(dir);
	      if (!q) {
	        queues.set(dir, [new Set([fn])]);
	      } else if (q[q.length - 1] instanceof Set) {
	        q[q.length - 1].add(fn);
	      } else {
	        q.push(new Set([fn]));
	      }
	    });

	    return run(fn)
	  };

	  return { check, reserve }
	};
	return pathReservations;
}

var getWriteFlag;
var hasRequiredGetWriteFlag;

function requireGetWriteFlag () {
	if (hasRequiredGetWriteFlag) return getWriteFlag;
	hasRequiredGetWriteFlag = 1;
	// Get the appropriate flag to use for creating files
	// We use fmap on Windows platforms for files less than
	// 512kb.  This is a fairly low limit, but avoids making
	// things slower in some cases.  Since most of what this
	// library is used for is extracting tarballs of many
	// relatively small files in npm packages and the like,
	// it can be a big boost on Windows platforms.
	// Only supported in Node v12.9.0 and above.
	const platform = process.env.__FAKE_PLATFORM__ || process.platform;
	const isWindows = platform === 'win32';
	const fs = commonjsGlobal.__FAKE_TESTING_FS__ || require$$0$2;

	/* istanbul ignore next */
	const { O_CREAT, O_TRUNC, O_WRONLY, UV_FS_O_FILEMAP = 0 } = fs.constants;

	const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP;
	const fMapLimit = 512 * 1024;
	const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY;
	getWriteFlag = !fMapEnabled ? () => 'w'
	  : size => size < fMapLimit ? fMapFlag : 'w';
	return getWriteFlag;
}

var unpack;
var hasRequiredUnpack;

function requireUnpack () {
	if (hasRequiredUnpack) return unpack;
	hasRequiredUnpack = 1;

	// the PEND/UNPEND stuff tracks whether we're ready to emit end/close yet.
	// but the path reservations are required to avoid race conditions where
	// parallelized unpack ops may mess with one another, due to dependencies
	// (like a Link depending on its target) or destructive operations (like
	// clobbering an fs object to create one of a different type.)

	const assert = require$$5;
	const Parser = requireParse$2();
	const fs = require$$0$2;
	const fsm = requireFsMinipass();
	const path = require$$1;
	const mkdir = requireMkdir();
	const wc = requireWinchars();
	const pathReservations = requirePathReservations();
	const stripAbsolutePath = requireStripAbsolutePath();
	const normPath = requireNormalizeWindowsPath();
	const stripSlash = requireStripTrailingSlashes();
	const normalize = requireNormalizeUnicode();

	const ONENTRY = Symbol('onEntry');
	const CHECKFS = Symbol('checkFs');
	const CHECKFS2 = Symbol('checkFs2');
	const PRUNECACHE = Symbol('pruneCache');
	const ISREUSABLE = Symbol('isReusable');
	const MAKEFS = Symbol('makeFs');
	const FILE = Symbol('file');
	const DIRECTORY = Symbol('directory');
	const LINK = Symbol('link');
	const SYMLINK = Symbol('symlink');
	const HARDLINK = Symbol('hardlink');
	const UNSUPPORTED = Symbol('unsupported');
	const CHECKPATH = Symbol('checkPath');
	const MKDIR = Symbol('mkdir');
	const ONERROR = Symbol('onError');
	const PENDING = Symbol('pending');
	const PEND = Symbol('pend');
	const UNPEND = Symbol('unpend');
	const ENDED = Symbol('ended');
	const MAYBECLOSE = Symbol('maybeClose');
	const SKIP = Symbol('skip');
	const DOCHOWN = Symbol('doChown');
	const UID = Symbol('uid');
	const GID = Symbol('gid');
	const CHECKED_CWD = Symbol('checkedCwd');
	const crypto = require$$12;
	const getFlag = requireGetWriteFlag();
	const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
	const isWindows = platform === 'win32';
	const DEFAULT_MAX_DEPTH = 1024;

	// Unlinks on Windows are not atomic.
	//
	// This means that if you have a file entry, followed by another
	// file entry with an identical name, and you cannot re-use the file
	// (because it's a hardlink, or because unlink:true is set, or it's
	// Windows, which does not have useful nlink values), then the unlink
	// will be committed to the disk AFTER the new file has been written
	// over the old one, deleting the new file.
	//
	// To work around this, on Windows systems, we rename the file and then
	// delete the renamed file.  It's a sloppy kludge, but frankly, I do not
	// know of a better way to do this, given windows' non-atomic unlink
	// semantics.
	//
	// See: https://github.com/npm/node-tar/issues/183
	/* istanbul ignore next */
	const unlinkFile = (path, cb) => {
	  if (!isWindows) {
	    return fs.unlink(path, cb)
	  }

	  const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex');
	  fs.rename(path, name, er => {
	    if (er) {
	      return cb(er)
	    }
	    fs.unlink(name, cb);
	  });
	};

	/* istanbul ignore next */
	const unlinkFileSync = path => {
	  if (!isWindows) {
	    return fs.unlinkSync(path)
	  }

	  const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex');
	  fs.renameSync(path, name);
	  fs.unlinkSync(name);
	};

	// this.gid, entry.gid, this.processUid
	const uint32 = (a, b, c) =>
	  a === a >>> 0 ? a
	  : b === b >>> 0 ? b
	  : c;

	// clear the cache if it's a case-insensitive unicode-squashing match.
	// we can't know if the current file system is case-sensitive or supports
	// unicode fully, so we check for similarity on the maximally compatible
	// representation.  Err on the side of pruning, since all it's doing is
	// preventing lstats, and it's not the end of the world if we get a false
	// positive.
	// Note that on windows, we always drop the entire cache whenever a
	// symbolic link is encountered, because 8.3 filenames are impossible
	// to reason about, and collisions are hazards rather than just failures.
	const cacheKeyNormalize = path => stripSlash(normPath(normalize(path)))
	  .toLowerCase();

	const pruneCache = (cache, abs) => {
	  abs = cacheKeyNormalize(abs);
	  for (const path of cache.keys()) {
	    const pnorm = cacheKeyNormalize(path);
	    if (pnorm === abs || pnorm.indexOf(abs + '/') === 0) {
	      cache.delete(path);
	    }
	  }
	};

	const dropCache = cache => {
	  for (const key of cache.keys()) {
	    cache.delete(key);
	  }
	};

	class Unpack extends Parser {
	  constructor (opt) {
	    if (!opt) {
	      opt = {};
	    }

	    opt.ondone = _ => {
	      this[ENDED] = true;
	      this[MAYBECLOSE]();
	    };

	    super(opt);

	    this[CHECKED_CWD] = false;

	    this.reservations = pathReservations();

	    this.transform = typeof opt.transform === 'function' ? opt.transform : null;

	    this.writable = true;
	    this.readable = false;

	    this[PENDING] = 0;
	    this[ENDED] = false;

	    this.dirCache = opt.dirCache || new Map();

	    if (typeof opt.uid === 'number' || typeof opt.gid === 'number') {
	      // need both or neither
	      if (typeof opt.uid !== 'number' || typeof opt.gid !== 'number') {
	        throw new TypeError('cannot set owner without number uid and gid')
	      }
	      if (opt.preserveOwner) {
	        throw new TypeError(
	          'cannot preserve owner in archive and also set owner explicitly')
	      }
	      this.uid = opt.uid;
	      this.gid = opt.gid;
	      this.setOwner = true;
	    } else {
	      this.uid = null;
	      this.gid = null;
	      this.setOwner = false;
	    }

	    // default true for root
	    if (opt.preserveOwner === undefined && typeof opt.uid !== 'number') {
	      this.preserveOwner = process.getuid && process.getuid() === 0;
	    } else {
	      this.preserveOwner = !!opt.preserveOwner;
	    }

	    this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ?
	      process.getuid() : null;
	    this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ?
	      process.getgid() : null;

	    // prevent excessively deep nesting of subfolders
	    // set to `Infinity` to remove this restriction
	    this.maxDepth = typeof opt.maxDepth === 'number'
	      ? opt.maxDepth
	      : DEFAULT_MAX_DEPTH;

	    // mostly just for testing, but useful in some cases.
	    // Forcibly trigger a chown on every entry, no matter what
	    this.forceChown = opt.forceChown === true;

	    // turn ><?| in filenames into 0xf000-higher encoded forms
	    this.win32 = !!opt.win32 || isWindows;

	    // do not unpack over files that are newer than what's in the archive
	    this.newer = !!opt.newer;

	    // do not unpack over ANY files
	    this.keep = !!opt.keep;

	    // do not set mtime/atime of extracted entries
	    this.noMtime = !!opt.noMtime;

	    // allow .., absolute path entries, and unpacking through symlinks
	    // without this, warn and skip .., relativize absolutes, and error
	    // on symlinks in extraction path
	    this.preservePaths = !!opt.preservePaths;

	    // unlink files and links before writing. This breaks existing hard
	    // links, and removes symlink directories rather than erroring
	    this.unlink = !!opt.unlink;

	    this.cwd = normPath(path.resolve(opt.cwd || process.cwd()));
	    this.strip = +opt.strip || 0;
	    // if we're not chmodding, then we don't need the process umask
	    this.processUmask = opt.noChmod ? 0 : process.umask();
	    this.umask = typeof opt.umask === 'number' ? opt.umask : this.processUmask;

	    // default mode for dirs created as parents
	    this.dmode = opt.dmode || (0o0777 & (~this.umask));
	    this.fmode = opt.fmode || (0o0666 & (~this.umask));

	    this.on('entry', entry => this[ONENTRY](entry));
	  }

	  // a bad or damaged archive is a warning for Parser, but an error
	  // when extracting.  Mark those errors as unrecoverable, because
	  // the Unpack contract cannot be met.
	  warn (code, msg, data = {}) {
	    if (code === 'TAR_BAD_ARCHIVE' || code === 'TAR_ABORT') {
	      data.recoverable = false;
	    }
	    return super.warn(code, msg, data)
	  }

	  [MAYBECLOSE] () {
	    if (this[ENDED] && this[PENDING] === 0) {
	      this.emit('prefinish');
	      this.emit('finish');
	      this.emit('end');
	    }
	  }

	  [CHECKPATH] (entry) {
	    const p = normPath(entry.path);
	    const parts = p.split('/');

	    if (this.strip) {
	      if (parts.length < this.strip) {
	        return false
	      }
	      if (entry.type === 'Link') {
	        const linkparts = normPath(entry.linkpath).split('/');
	        if (linkparts.length >= this.strip) {
	          entry.linkpath = linkparts.slice(this.strip).join('/');
	        } else {
	          return false
	        }
	      }
	      parts.splice(0, this.strip);
	      entry.path = parts.join('/');
	    }

	    if (isFinite(this.maxDepth) && parts.length > this.maxDepth) {
	      this.warn('TAR_ENTRY_ERROR', 'path excessively deep', {
	        entry,
	        path: p,
	        depth: parts.length,
	        maxDepth: this.maxDepth,
	      });
	      return false
	    }

	    if (!this.preservePaths) {
	      if (parts.includes('..') || isWindows && /^[a-z]:\.\.$/i.test(parts[0])) {
	        this.warn('TAR_ENTRY_ERROR', `path contains '..'`, {
	          entry,
	          path: p,
	        });
	        return false
	      }

	      // strip off the root
	      const [root, stripped] = stripAbsolutePath(p);
	      if (root) {
	        entry.path = stripped;
	        this.warn('TAR_ENTRY_INFO', `stripping ${root} from absolute path`, {
	          entry,
	          path: p,
	        });
	      }
	    }

	    if (path.isAbsolute(entry.path)) {
	      entry.absolute = normPath(path.resolve(entry.path));
	    } else {
	      entry.absolute = normPath(path.resolve(this.cwd, entry.path));
	    }

	    // if we somehow ended up with a path that escapes the cwd, and we are
	    // not in preservePaths mode, then something is fishy!  This should have
	    // been prevented above, so ignore this for coverage.
	    /* istanbul ignore if - defense in depth */
	    if (!this.preservePaths &&
	        entry.absolute.indexOf(this.cwd + '/') !== 0 &&
	        entry.absolute !== this.cwd) {
	      this.warn('TAR_ENTRY_ERROR', 'path escaped extraction target', {
	        entry,
	        path: normPath(entry.path),
	        resolvedPath: entry.absolute,
	        cwd: this.cwd,
	      });
	      return false
	    }

	    // an archive can set properties on the extraction directory, but it
	    // may not replace the cwd with a different kind of thing entirely.
	    if (entry.absolute === this.cwd &&
	        entry.type !== 'Directory' &&
	        entry.type !== 'GNUDumpDir') {
	      return false
	    }

	    // only encode : chars that aren't drive letter indicators
	    if (this.win32) {
	      const { root: aRoot } = path.win32.parse(entry.absolute);
	      entry.absolute = aRoot + wc.encode(entry.absolute.slice(aRoot.length));
	      const { root: pRoot } = path.win32.parse(entry.path);
	      entry.path = pRoot + wc.encode(entry.path.slice(pRoot.length));
	    }

	    return true
	  }

	  [ONENTRY] (entry) {
	    if (!this[CHECKPATH](entry)) {
	      return entry.resume()
	    }

	    assert.equal(typeof entry.absolute, 'string');

	    switch (entry.type) {
	      case 'Directory':
	      case 'GNUDumpDir':
	        if (entry.mode) {
	          entry.mode = entry.mode | 0o700;
	        }

	      // eslint-disable-next-line no-fallthrough
	      case 'File':
	      case 'OldFile':
	      case 'ContiguousFile':
	      case 'Link':
	      case 'SymbolicLink':
	        return this[CHECKFS](entry)

	      case 'CharacterDevice':
	      case 'BlockDevice':
	      case 'FIFO':
	      default:
	        return this[UNSUPPORTED](entry)
	    }
	  }

	  [ONERROR] (er, entry) {
	    // Cwd has to exist, or else nothing works. That's serious.
	    // Other errors are warnings, which raise the error in strict
	    // mode, but otherwise continue on.
	    if (er.name === 'CwdError') {
	      this.emit('error', er);
	    } else {
	      this.warn('TAR_ENTRY_ERROR', er, { entry });
	      this[UNPEND]();
	      entry.resume();
	    }
	  }

	  [MKDIR] (dir, mode, cb) {
	    mkdir(normPath(dir), {
	      uid: this.uid,
	      gid: this.gid,
	      processUid: this.processUid,
	      processGid: this.processGid,
	      umask: this.processUmask,
	      preserve: this.preservePaths,
	      unlink: this.unlink,
	      cache: this.dirCache,
	      cwd: this.cwd,
	      mode: mode,
	      noChmod: this.noChmod,
	    }, cb);
	  }

	  [DOCHOWN] (entry) {
	    // in preserve owner mode, chown if the entry doesn't match process
	    // in set owner mode, chown if setting doesn't match process
	    return this.forceChown ||
	      this.preserveOwner &&
	      (typeof entry.uid === 'number' && entry.uid !== this.processUid ||
	        typeof entry.gid === 'number' && entry.gid !== this.processGid)
	      ||
	      (typeof this.uid === 'number' && this.uid !== this.processUid ||
	        typeof this.gid === 'number' && this.gid !== this.processGid)
	  }

	  [UID] (entry) {
	    return uint32(this.uid, entry.uid, this.processUid)
	  }

	  [GID] (entry) {
	    return uint32(this.gid, entry.gid, this.processGid)
	  }

	  [FILE] (entry, fullyDone) {
	    const mode = entry.mode & 0o7777 || this.fmode;
	    const stream = new fsm.WriteStream(entry.absolute, {
	      flags: getFlag(entry.size),
	      mode: mode,
	      autoClose: false,
	    });
	    stream.on('error', er => {
	      if (stream.fd) {
	        fs.close(stream.fd, () => {});
	      }

	      // flush all the data out so that we aren't left hanging
	      // if the error wasn't actually fatal.  otherwise the parse
	      // is blocked, and we never proceed.
	      stream.write = () => true;
	      this[ONERROR](er, entry);
	      fullyDone();
	    });

	    let actions = 1;
	    const done = er => {
	      if (er) {
	        /* istanbul ignore else - we should always have a fd by now */
	        if (stream.fd) {
	          fs.close(stream.fd, () => {});
	        }

	        this[ONERROR](er, entry);
	        fullyDone();
	        return
	      }

	      if (--actions === 0) {
	        fs.close(stream.fd, er => {
	          if (er) {
	            this[ONERROR](er, entry);
	          } else {
	            this[UNPEND]();
	          }
	          fullyDone();
	        });
	      }
	    };

	    stream.on('finish', _ => {
	      // if futimes fails, try utimes
	      // if utimes fails, fail with the original error
	      // same for fchown/chown
	      const abs = entry.absolute;
	      const fd = stream.fd;

	      if (entry.mtime && !this.noMtime) {
	        actions++;
	        const atime = entry.atime || new Date();
	        const mtime = entry.mtime;
	        fs.futimes(fd, atime, mtime, er =>
	          er ? fs.utimes(abs, atime, mtime, er2 => done(er2 && er))
	          : done());
	      }

	      if (this[DOCHOWN](entry)) {
	        actions++;
	        const uid = this[UID](entry);
	        const gid = this[GID](entry);
	        fs.fchown(fd, uid, gid, er =>
	          er ? fs.chown(abs, uid, gid, er2 => done(er2 && er))
	          : done());
	      }

	      done();
	    });

	    const tx = this.transform ? this.transform(entry) || entry : entry;
	    if (tx !== entry) {
	      tx.on('error', er => {
	        this[ONERROR](er, entry);
	        fullyDone();
	      });
	      entry.pipe(tx);
	    }
	    tx.pipe(stream);
	  }

	  [DIRECTORY] (entry, fullyDone) {
	    const mode = entry.mode & 0o7777 || this.dmode;
	    this[MKDIR](entry.absolute, mode, er => {
	      if (er) {
	        this[ONERROR](er, entry);
	        fullyDone();
	        return
	      }

	      let actions = 1;
	      const done = _ => {
	        if (--actions === 0) {
	          fullyDone();
	          this[UNPEND]();
	          entry.resume();
	        }
	      };

	      if (entry.mtime && !this.noMtime) {
	        actions++;
	        fs.utimes(entry.absolute, entry.atime || new Date(), entry.mtime, done);
	      }

	      if (this[DOCHOWN](entry)) {
	        actions++;
	        fs.chown(entry.absolute, this[UID](entry), this[GID](entry), done);
	      }

	      done();
	    });
	  }

	  [UNSUPPORTED] (entry) {
	    entry.unsupported = true;
	    this.warn('TAR_ENTRY_UNSUPPORTED',
	      `unsupported entry type: ${entry.type}`, { entry });
	    entry.resume();
	  }

	  [SYMLINK] (entry, done) {
	    this[LINK](entry, entry.linkpath, 'symlink', done);
	  }

	  [HARDLINK] (entry, done) {
	    const linkpath = normPath(path.resolve(this.cwd, entry.linkpath));
	    this[LINK](entry, linkpath, 'link', done);
	  }

	  [PEND] () {
	    this[PENDING]++;
	  }

	  [UNPEND] () {
	    this[PENDING]--;
	    this[MAYBECLOSE]();
	  }

	  [SKIP] (entry) {
	    this[UNPEND]();
	    entry.resume();
	  }

	  // Check if we can reuse an existing filesystem entry safely and
	  // overwrite it, rather than unlinking and recreating
	  // Windows doesn't report a useful nlink, so we just never reuse entries
	  [ISREUSABLE] (entry, st) {
	    return entry.type === 'File' &&
	      !this.unlink &&
	      st.isFile() &&
	      st.nlink <= 1 &&
	      !isWindows
	  }

	  // check if a thing is there, and if so, try to clobber it
	  [CHECKFS] (entry) {
	    this[PEND]();
	    const paths = [entry.path];
	    if (entry.linkpath) {
	      paths.push(entry.linkpath);
	    }
	    this.reservations.reserve(paths, done => this[CHECKFS2](entry, done));
	  }

	  [PRUNECACHE] (entry) {
	    // if we are not creating a directory, and the path is in the dirCache,
	    // then that means we are about to delete the directory we created
	    // previously, and it is no longer going to be a directory, and neither
	    // is any of its children.
	    // If a symbolic link is encountered, all bets are off.  There is no
	    // reasonable way to sanitize the cache in such a way we will be able to
	    // avoid having filesystem collisions.  If this happens with a non-symlink
	    // entry, it'll just fail to unpack, but a symlink to a directory, using an
	    // 8.3 shortname or certain unicode attacks, can evade detection and lead
	    // to arbitrary writes to anywhere on the system.
	    if (entry.type === 'SymbolicLink') {
	      dropCache(this.dirCache);
	    } else if (entry.type !== 'Directory') {
	      pruneCache(this.dirCache, entry.absolute);
	    }
	  }

	  [CHECKFS2] (entry, fullyDone) {
	    this[PRUNECACHE](entry);

	    const done = er => {
	      this[PRUNECACHE](entry);
	      fullyDone(er);
	    };

	    const checkCwd = () => {
	      this[MKDIR](this.cwd, this.dmode, er => {
	        if (er) {
	          this[ONERROR](er, entry);
	          done();
	          return
	        }
	        this[CHECKED_CWD] = true;
	        start();
	      });
	    };

	    const start = () => {
	      if (entry.absolute !== this.cwd) {
	        const parent = normPath(path.dirname(entry.absolute));
	        if (parent !== this.cwd) {
	          return this[MKDIR](parent, this.dmode, er => {
	            if (er) {
	              this[ONERROR](er, entry);
	              done();
	              return
	            }
	            afterMakeParent();
	          })
	        }
	      }
	      afterMakeParent();
	    };

	    const afterMakeParent = () => {
	      fs.lstat(entry.absolute, (lstatEr, st) => {
	        if (st && (this.keep || this.newer && st.mtime > entry.mtime)) {
	          this[SKIP](entry);
	          done();
	          return
	        }
	        if (lstatEr || this[ISREUSABLE](entry, st)) {
	          return this[MAKEFS](null, entry, done)
	        }

	        if (st.isDirectory()) {
	          if (entry.type === 'Directory') {
	            const needChmod = !this.noChmod &&
	              entry.mode &&
	              (st.mode & 0o7777) !== entry.mode;
	            const afterChmod = er => this[MAKEFS](er, entry, done);
	            if (!needChmod) {
	              return afterChmod()
	            }
	            return fs.chmod(entry.absolute, entry.mode, afterChmod)
	          }
	          // Not a dir entry, have to remove it.
	          // NB: the only way to end up with an entry that is the cwd
	          // itself, in such a way that == does not detect, is a
	          // tricky windows absolute path with UNC or 8.3 parts (and
	          // preservePaths:true, or else it will have been stripped).
	          // In that case, the user has opted out of path protections
	          // explicitly, so if they blow away the cwd, c'est la vie.
	          if (entry.absolute !== this.cwd) {
	            return fs.rmdir(entry.absolute, er =>
	              this[MAKEFS](er, entry, done))
	          }
	        }

	        // not a dir, and not reusable
	        // don't remove if the cwd, we want that error
	        if (entry.absolute === this.cwd) {
	          return this[MAKEFS](null, entry, done)
	        }

	        unlinkFile(entry.absolute, er =>
	          this[MAKEFS](er, entry, done));
	      });
	    };

	    if (this[CHECKED_CWD]) {
	      start();
	    } else {
	      checkCwd();
	    }
	  }

	  [MAKEFS] (er, entry, done) {
	    if (er) {
	      this[ONERROR](er, entry);
	      done();
	      return
	    }

	    switch (entry.type) {
	      case 'File':
	      case 'OldFile':
	      case 'ContiguousFile':
	        return this[FILE](entry, done)

	      case 'Link':
	        return this[HARDLINK](entry, done)

	      case 'SymbolicLink':
	        return this[SYMLINK](entry, done)

	      case 'Directory':
	      case 'GNUDumpDir':
	        return this[DIRECTORY](entry, done)
	    }
	  }

	  [LINK] (entry, linkpath, link, done) {
	    // XXX: get the type ('symlink' or 'junction') for windows
	    fs[link](linkpath, entry.absolute, er => {
	      if (er) {
	        this[ONERROR](er, entry);
	      } else {
	        this[UNPEND]();
	        entry.resume();
	      }
	      done();
	    });
	  }
	}

	const callSync = fn => {
	  try {
	    return [null, fn()]
	  } catch (er) {
	    return [er, null]
	  }
	};
	class UnpackSync extends Unpack {
	  [MAKEFS] (er, entry) {
	    return super[MAKEFS](er, entry, () => {})
	  }

	  [CHECKFS] (entry) {
	    this[PRUNECACHE](entry);

	    if (!this[CHECKED_CWD]) {
	      const er = this[MKDIR](this.cwd, this.dmode);
	      if (er) {
	        return this[ONERROR](er, entry)
	      }
	      this[CHECKED_CWD] = true;
	    }

	    // don't bother to make the parent if the current entry is the cwd,
	    // we've already checked it.
	    if (entry.absolute !== this.cwd) {
	      const parent = normPath(path.dirname(entry.absolute));
	      if (parent !== this.cwd) {
	        const mkParent = this[MKDIR](parent, this.dmode);
	        if (mkParent) {
	          return this[ONERROR](mkParent, entry)
	        }
	      }
	    }

	    const [lstatEr, st] = callSync(() => fs.lstatSync(entry.absolute));
	    if (st && (this.keep || this.newer && st.mtime > entry.mtime)) {
	      return this[SKIP](entry)
	    }

	    if (lstatEr || this[ISREUSABLE](entry, st)) {
	      return this[MAKEFS](null, entry)
	    }

	    if (st.isDirectory()) {
	      if (entry.type === 'Directory') {
	        const needChmod = !this.noChmod &&
	          entry.mode &&
	          (st.mode & 0o7777) !== entry.mode;
	        const [er] = needChmod ? callSync(() => {
	          fs.chmodSync(entry.absolute, entry.mode);
	        }) : [];
	        return this[MAKEFS](er, entry)
	      }
	      // not a dir entry, have to remove it
	      const [er] = callSync(() => fs.rmdirSync(entry.absolute));
	      this[MAKEFS](er, entry);
	    }

	    // not a dir, and not reusable.
	    // don't remove if it's the cwd, since we want that error.
	    const [er] = entry.absolute === this.cwd ? []
	      : callSync(() => unlinkFileSync(entry.absolute));
	    this[MAKEFS](er, entry);
	  }

	  [FILE] (entry, done) {
	    const mode = entry.mode & 0o7777 || this.fmode;

	    const oner = er => {
	      let closeError;
	      try {
	        fs.closeSync(fd);
	      } catch (e) {
	        closeError = e;
	      }
	      if (er || closeError) {
	        this[ONERROR](er || closeError, entry);
	      }
	      done();
	    };

	    let fd;
	    try {
	      fd = fs.openSync(entry.absolute, getFlag(entry.size), mode);
	    } catch (er) {
	      return oner(er)
	    }
	    const tx = this.transform ? this.transform(entry) || entry : entry;
	    if (tx !== entry) {
	      tx.on('error', er => this[ONERROR](er, entry));
	      entry.pipe(tx);
	    }

	    tx.on('data', chunk => {
	      try {
	        fs.writeSync(fd, chunk, 0, chunk.length);
	      } catch (er) {
	        oner(er);
	      }
	    });

	    tx.on('end', _ => {
	      let er = null;
	      // try both, falling futimes back to utimes
	      // if either fails, handle the first error
	      if (entry.mtime && !this.noMtime) {
	        const atime = entry.atime || new Date();
	        const mtime = entry.mtime;
	        try {
	          fs.futimesSync(fd, atime, mtime);
	        } catch (futimeser) {
	          try {
	            fs.utimesSync(entry.absolute, atime, mtime);
	          } catch (utimeser) {
	            er = futimeser;
	          }
	        }
	      }

	      if (this[DOCHOWN](entry)) {
	        const uid = this[UID](entry);
	        const gid = this[GID](entry);

	        try {
	          fs.fchownSync(fd, uid, gid);
	        } catch (fchowner) {
	          try {
	            fs.chownSync(entry.absolute, uid, gid);
	          } catch (chowner) {
	            er = er || fchowner;
	          }
	        }
	      }

	      oner(er);
	    });
	  }

	  [DIRECTORY] (entry, done) {
	    const mode = entry.mode & 0o7777 || this.dmode;
	    const er = this[MKDIR](entry.absolute, mode);
	    if (er) {
	      this[ONERROR](er, entry);
	      done();
	      return
	    }
	    if (entry.mtime && !this.noMtime) {
	      try {
	        fs.utimesSync(entry.absolute, entry.atime || new Date(), entry.mtime);
	      } catch (er) {}
	    }
	    if (this[DOCHOWN](entry)) {
	      try {
	        fs.chownSync(entry.absolute, this[UID](entry), this[GID](entry));
	      } catch (er) {}
	    }
	    done();
	    entry.resume();
	  }

	  [MKDIR] (dir, mode) {
	    try {
	      return mkdir.sync(normPath(dir), {
	        uid: this.uid,
	        gid: this.gid,
	        processUid: this.processUid,
	        processGid: this.processGid,
	        umask: this.processUmask,
	        preserve: this.preservePaths,
	        unlink: this.unlink,
	        cache: this.dirCache,
	        cwd: this.cwd,
	        mode: mode,
	      })
	    } catch (er) {
	      return er
	    }
	  }

	  [LINK] (entry, linkpath, link, done) {
	    try {
	      fs[link + 'Sync'](linkpath, entry.absolute);
	      done();
	      entry.resume();
	    } catch (er) {
	      return this[ONERROR](er, entry)
	    }
	  }
	}

	Unpack.Sync = UnpackSync;
	unpack = Unpack;
	return unpack;
}

var extract_1;
var hasRequiredExtract;

function requireExtract () {
	if (hasRequiredExtract) return extract_1;
	hasRequiredExtract = 1;

	// tar -x
	const hlo = requireHighLevelOpt();
	const Unpack = requireUnpack();
	const fs = require$$0$2;
	const fsm = requireFsMinipass();
	const path = require$$1;
	const stripSlash = requireStripTrailingSlashes();

	extract_1 = (opt_, files, cb) => {
	  if (typeof opt_ === 'function') {
	    cb = opt_, files = null, opt_ = {};
	  } else if (Array.isArray(opt_)) {
	    files = opt_, opt_ = {};
	  }

	  if (typeof files === 'function') {
	    cb = files, files = null;
	  }

	  if (!files) {
	    files = [];
	  } else {
	    files = Array.from(files);
	  }

	  const opt = hlo(opt_);

	  if (opt.sync && typeof cb === 'function') {
	    throw new TypeError('callback not supported for sync tar functions')
	  }

	  if (!opt.file && typeof cb === 'function') {
	    throw new TypeError('callback only supported with file option')
	  }

	  if (files.length) {
	    filesFilter(opt, files);
	  }

	  return opt.file && opt.sync ? extractFileSync(opt)
	    : opt.file ? extractFile(opt, cb)
	    : opt.sync ? extractSync(opt)
	    : extract(opt)
	};

	// construct a filter that limits the file entries listed
	// include child entries if a dir is included
	const filesFilter = (opt, files) => {
	  const map = new Map(files.map(f => [stripSlash(f), true]));
	  const filter = opt.filter;

	  const mapHas = (file, r) => {
	    const root = r || path.parse(file).root || '.';
	    const ret = file === root ? false
	      : map.has(file) ? map.get(file)
	      : mapHas(path.dirname(file), root);

	    map.set(file, ret);
	    return ret
	  };

	  opt.filter = filter
	    ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file))
	    : file => mapHas(stripSlash(file));
	};

	const extractFileSync = opt => {
	  const u = new Unpack.Sync(opt);

	  const file = opt.file;
	  const stat = fs.statSync(file);
	  // This trades a zero-byte read() syscall for a stat
	  // However, it will usually result in less memory allocation
	  const readSize = opt.maxReadSize || 16 * 1024 * 1024;
	  const stream = new fsm.ReadStreamSync(file, {
	    readSize: readSize,
	    size: stat.size,
	  });
	  stream.pipe(u);
	};

	const extractFile = (opt, cb) => {
	  const u = new Unpack(opt);
	  const readSize = opt.maxReadSize || 16 * 1024 * 1024;

	  const file = opt.file;
	  const p = new Promise((resolve, reject) => {
	    u.on('error', reject);
	    u.on('close', resolve);

	    // This trades a zero-byte read() syscall for a stat
	    // However, it will usually result in less memory allocation
	    fs.stat(file, (er, stat) => {
	      if (er) {
	        reject(er);
	      } else {
	        const stream = new fsm.ReadStream(file, {
	          readSize: readSize,
	          size: stat.size,
	        });
	        stream.on('error', reject);
	        stream.pipe(u);
	      }
	    });
	  });
	  return cb ? p.then(cb, cb) : p
	};

	const extractSync = opt => new Unpack.Sync(opt);

	const extract = opt => new Unpack(opt);
	return extract_1;
}

var hasRequiredTar;

function requireTar () {
	if (hasRequiredTar) return tar;
	hasRequiredTar = 1;

	// high-level commands
	tar.c = tar.create = requireCreate();
	tar.r = tar.replace = requireReplace();
	tar.t = tar.list = requireList();
	tar.u = tar.update = requireUpdate();
	tar.x = tar.extract = requireExtract();

	// classes
	tar.Pack = requirePack();
	tar.Unpack = requireUnpack();
	tar.Parse = requireParse$2();
	tar.ReadEntry = requireReadEntry();
	tar.WriteEntry = requireWriteEntry();
	tar.Header = requireHeader();
	tar.Pax = requirePax();
	tar.types = requireTypes();
	return tar;
}

var bundler;
var hasRequiredBundler;

function requireBundler () {
	if (hasRequiredBundler) return bundler;
	hasRequiredBundler = 1;
	const fs = require$$0$2;
	const path = require$$1;
	const { spawn, spawnSync } = require$$2$2;
	const archiver = requireArchiver();
	const tar = requireTar();

	class ProjectBundler {
	  constructor() {
	    this.supportedFormats = ["js", "zip", "tar", "exe", "msix", "sh"];
	    this.tempDir = path.join(process.cwd(), ".bpack-temp");
	  }

	  async bundle(format, options = {}) {
	    const { output, include, exclude, minify = true, platform = process.platform } = options;

	    console.log(`šŸ”§ Starting bundle process for format: ${format}`);

	    try {
	      // Ensure temp directory exists
	      if (!fs.existsSync(this.tempDir)) {
	        fs.mkdirSync(this.tempDir, { recursive: true });
	      }

	      switch (format) {
	        case "js":
	          return await this.bundleToJS(output, { minify, include, exclude })
	        case "zip":
	          return await this.bundleToZip(output, { include, exclude })
	        case "tar":
	          return await this.bundleToTar(output, { include, exclude })
	        case "exe":
	          return await this.bundleToExe(output, { platform, minify })
	        case "msix":
	          return await this.bundleToMSIX(output, options)
	        case "sh":
	          return await this.bundleToShellInstaller(output, options)
	        default:
	          throw new Error(`Unsupported format: ${format}`)
	      }
	    } catch (error) {
	      console.error(`āŒ Bundle failed: ${error.message}`);
	      throw error
	    } finally {
	      // Cleanup temp directory
	      this.cleanup();
	    }
	  }

	  async bundleToJS(outputPath, options) {
	    console.log("šŸ“¦ Bundling to single JavaScript file...");

	    const packageJson = this.getPackageJson();
	    const entryPoint = packageJson.main || "index.js";

	    // Use webpack or rollup for bundling
	    const bundlerConfig = this.createBundlerConfig(entryPoint, outputPath, options);

	    if (this.hasWebpack()) {
	      return await this.bundleWithWebpack(bundlerConfig)
	    } else if (this.hasRollup()) {
	      return await this.bundleWithRollup(bundlerConfig)
	    } else {
	      // Fallback: simple concatenation
	      return await this.simpleBundleJS(entryPoint, outputPath, options)
	    }
	  }

	  async bundleToZip(outputPath, options) {
	    console.log("šŸ“¦ Creating ZIP archive...");

	    const output = fs.createWriteStream(outputPath || "bundle.zip");
	    const archive = archiver("zip", { zlib: { level: 9 } });

	    return new Promise((resolve, reject) => {
	      output.on("close", () => {
	        console.log(`āœ… ZIP created: ${archive.pointer()} bytes`);
	        resolve(outputPath || "bundle.zip");
	      });

	      archive.on("error", reject);
	      archive.pipe(output);

	      // Add files based on include/exclude patterns
	      this.addFilesToArchive(archive, options);
	      archive.finalize();
	    })
	  }

	  async bundleToTar(outputPath, options) {
	    console.log("šŸ“¦ Creating TAR archive...");

	    const files = this.getFilesToBundle(options);
	    const tarPath = outputPath || "bundle.tar.gz";

	    await tar.create(
	      {
	        gzip: true,
	        file: tarPath,
	        cwd: process.cwd(),
	      },
	      files,
	    );

	    console.log(`āœ… TAR created: ${tarPath}`);
	    return tarPath
	  }

	  async bundleToExe(outputPath, options) {
	    console.log("šŸ“¦ Creating executable...");

	    // First bundle to JS
	    const jsBundle = path.join(this.tempDir, "bundle.js");
	    await this.bundleToJS(jsBundle, options);

	    // Use nexe or pkg to create executable
	    if (this.hasNexe()) {
	      return await this.createExeWithNexe(jsBundle, outputPath, options)
	    } else if (this.hasPkg()) {
	      return await this.createExeWithPkg(jsBundle, outputPath, options)
	    } else {
	      throw new Error("No executable bundler found. Install nexe or pkg: npm install -g nexe pkg")
	    }
	  }

	  async bundleToMSIX(outputPath, options) {
	    if (process.platform !== "win32") {
	      throw new Error("MSIX packages can only be created on Windows")
	    }

	    console.log("šŸ“¦ Creating MSIX installer...");

	    // Create app manifest and package structure
	    const packageDir = path.join(this.tempDir, "msix-package");
	    await this.createMSIXStructure(packageDir, options);

	    // Use Windows SDK tools to create MSIX
	    const msixPath = outputPath || "installer.msix";
	    await this.createMSIXPackage(packageDir, msixPath);

	    console.log(`āœ… MSIX created: ${msixPath}`);
	    return msixPath
	  }

	  async bundleToShellInstaller(outputPath, options) {
	    console.log("šŸ“¦ Creating shell installer...");

	    const installerPath = outputPath || "install.sh";
	    const packageJson = this.getPackageJson();

	    const installerScript = this.generateShellInstaller(packageJson, options);
	    fs.writeFileSync(installerPath, installerScript, { mode: 0o755 });

	    console.log(`āœ… Shell installer created: ${installerPath}`);
	    return installerPath
	  }

	  // Helper methods
	  getPackageJson() {
	    const packagePath = path.join(process.cwd(), "package.json");
	    if (!fs.existsSync(packagePath)) {
	      throw new Error("package.json not found")
	    }
	    return JSON.parse(fs.readFileSync(packagePath, "utf8"))
	  }

	  hasWebpack() {
	    try {
	      require.resolve("webpack");
	      return true
	    } catch {
	      return false
	    }
	  }

	  hasRollup() {
	    try {
	      require.resolve("rollup");
	      return true
	    } catch {
	      return false
	    }
	  }

	  hasNexe() {
	    const result = spawnSync("nexe", ["--version"], { shell: true });
	    return result.status === 0
	  }

	  hasPkg() {
	    const result = spawnSync("pkg", ["--version"], { shell: true });
	    return result.status === 0
	  }

	  getFilesToBundle(options) {
	    const { include = ["**/*"], exclude = ["node_modules/**", ".git/**", "*.log"] } = options;

	    // Simple file matching - in production, use glob library
	    const allFiles = this.getAllFiles(process.cwd());
	    return allFiles.filter((file) => {
	      const relativePath = path.relative(process.cwd(), file);
	      return this.matchesPattern(relativePath, include) && !this.matchesPattern(relativePath, exclude)
	    })
	  }

	  getAllFiles(dir, files = []) {
	    const entries = fs.readdirSync(dir);

	    for (const entry of entries) {
	      const fullPath = path.join(dir, entry);
	      const stat = fs.statSync(fullPath);

	      if (stat.isDirectory()) {
	        this.getAllFiles(fullPath, files);
	      } else {
	        files.push(fullPath);
	      }
	    }

	    return files
	  }

	  matchesPattern(filePath, patterns) {
	    // Simple pattern matching - in production, use minimatch
	    return patterns.some((pattern) => {
	      if (pattern.includes("**")) {
	        const regex = new RegExp(pattern.replace("**", ".*").replace("*", "[^/]*"));
	        return regex.test(filePath)
	      }
	      return filePath.includes(pattern.replace("*", ""))
	    })
	  }

	  generateShellInstaller(packageJson, options) {
	    return `#!/bin/bash
# Auto-generated installer for ${packageJson.name}
# Version: ${packageJson.version}

set -e

echo "Installing ${packageJson.name}..."

# Check for Node.js
if ! command -v node &> /dev/null; then
    echo "Node.js is required but not installed."
    echo "Please install Node.js from https://nodejs.org/"
    exit 1
fi

# Create installation directory
INSTALL_DIR="/usr/local/lib/${packageJson.name}"
sudo mkdir -p "$INSTALL_DIR"

# Extract and install files
echo "Extracting files..."
# Add extraction logic here based on bundled format

# Create symlink for global access
sudo ln -sf "$INSTALL_DIR/bin/${packageJson.name}" "/usr/local/bin/${packageJson.name}"

echo "āœ… ${packageJson.name} installed successfully!"
echo "Run '${packageJson.name} --help' to get started."
`
	  }

	  cleanup() {
	    if (fs.existsSync(this.tempDir)) {
	      fs.rmSync(this.tempDir, { recursive: true, force: true });
	    }
	  }
	}

	function displayBundlerHelp() {
	  console.log("\n\x1b[1mBetterpack Bundler\x1b[0m");
	  console.log("\nUsage: bpack bundle <format> [options]");
	  console.log("\n\x1b[1mSupported Formats:\x1b[0m");
	  console.log("  \x1b[36mjs\x1b[0m          Bundle to single JavaScript file");
	  console.log("  \x1b[36mzip\x1b[0m         Create ZIP archive");
	  console.log("  \x1b[36mtar\x1b[0m         Create TAR.GZ archive");
	  console.log("  \x1b[36mexe\x1b[0m         Create executable (requires nexe or pkg)");
	  console.log("  \x1b[36mmsix\x1b[0m        Create Windows MSIX installer");
	  console.log("  \x1b[36msh\x1b[0m          Create shell installer script");

	  console.log("\n\x1b[1mOptions:\x1b[0m");
	  console.log("  \x1b[33m-o, --output\x1b[0m    Output file path");
	  console.log("  \x1b[33m--include\x1b[0m       Include patterns (comma-separated)");
	  console.log("  \x1b[33m--exclude\x1b[0m       Exclude patterns (comma-separated)");
	  console.log("  \x1b[33m--no-minify\x1b[0m     Disable minification");
	  console.log("  \x1b[33m--platform\x1b[0m      Target platform for executables");

	  console.log("\n\x1b[1mExamples:\x1b[0m");
	  console.log("  bpack bundle js -o dist/app.js");
	  console.log('  bpack bundle zip --exclude "*.log,node_modules/**"');
	  console.log("  bpack bundle exe --platform win32");
	  console.log("  bpack bundle msix -o MyApp.msix");
	  console.log("");
	}

	async function handleBundleCommand(args) {
	  if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
	    displayBundlerHelp();
	    return
	  }

	  const format = args[0];
	  const bundler = new ProjectBundler();

	  // Parse options
	  const options = {};
	  for (let i = 1; i < args.length; i++) {
	    const arg = args[i];
	    switch (arg) {
	      case "-o":
	      case "--output":
	        options.output = args[++i];
	        break
	      case "--include":
	        options.include = args[++i].split(",");
	        break
	      case "--exclude":
	        options.exclude = args[++i].split(",");
	        break
	      case "--no-minify":
	        options.minify = false;
	        break
	      case "--platform":
	        options.platform = args[++i];
	        break
	    }
	  }

	  try {
	    const result = await bundler.bundle(format, options);
	    console.log(`šŸŽ‰ Bundle completed: ${result}`);
	  } catch (error) {
	    console.error(`āŒ Bundle failed: ${error.message}`);
	    process.exit(1);
	  }
	}

	bundler = { ProjectBundler, handleBundleCommand, displayBundlerHelp };
	return bundler;
}

var projectAnalyzer;
var hasRequiredProjectAnalyzer;

function requireProjectAnalyzer () {
	if (hasRequiredProjectAnalyzer) return projectAnalyzer;
	hasRequiredProjectAnalyzer = 1;
	const fs = require$$0$2;
	const path = require$$1;
	const { spawnSync } = require$$2$2;

	class ProjectAnalyzer {
	  constructor(projectPath = process.cwd()) {
	    this.projectPath = projectPath;
	    this.analysis = {
	      structure: {},
	      dependencies: {},
	      health: {},
	      issues: [],
	      recommendations: [],
	    };
	  }

	  async analyzeProject() {
	    console.log(`[Agent] Analyzing project at: ${this.projectPath}`);

	    await this.analyzeStructure();
	    await this.analyzeDependencies();
	    await this.analyzeHealth();
	    await this.detectIssues();
	    await this.generateRecommendations();

	    return this.analysis
	  }

	  async analyzeStructure() {
	    const structure = {
	      hasPackageJson: false,
	      hasLockfile: false,
	      lockfileType: null,
	      hasNodeModules: false,
	      hasGitRepo: false,
	      projectType: "unknown",
	      frameworks: [],
	      buildTools: [],
	    };

	    // Check for package.json
	    const packageJsonPath = path.join(this.projectPath, "package.json");
	    if (fs.existsSync(packageJsonPath)) {
	      structure.hasPackageJson = true;
	      try {
	        const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
	        structure.projectType = this.detectProjectType(packageJson);
	        structure.frameworks = this.detectFrameworks(packageJson);
	        structure.buildTools = this.detectBuildTools(packageJson);
	      } catch (error) {
	        this.analysis.issues.push({
	          type: "error",
	          category: "structure",
	          message: "Invalid package.json format",
	          severity: "high",
	        });
	      }
	    }

	    // Check for lockfiles
	    const lockfiles = {
	      "package-lock.json": "npm",
	      "yarn.lock": "yarn",
	      "pnpm-lock.yaml": "pnpm",
	      "bun.lockb": "bun",
	    };

	    for (const [filename, manager] of Object.entries(lockfiles)) {
	      if (fs.existsSync(path.join(this.projectPath, filename))) {
	        structure.hasLockfile = true;
	        structure.lockfileType = manager;
	        break
	      }
	    }

	    // Check for node_modules
	    structure.hasNodeModules = fs.existsSync(path.join(this.projectPath, "node_modules"));

	    // Check for git repository
	    structure.hasGitRepo = fs.existsSync(path.join(this.projectPath, ".git"));

	    this.analysis.structure = structure;
	  }

	  async analyzeDependencies() {
	    const packageJsonPath = path.join(this.projectPath, "package.json");
	    if (!fs.existsSync(packageJsonPath)) {
	      return
	    }

	    try {
	      const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
	      const deps = {
	        production: Object.keys(packageJson.dependencies || {}),
	        development: Object.keys(packageJson.devDependencies || {}),
	        peer: Object.keys(packageJson.peerDependencies || {}),
	        optional: Object.keys(packageJson.optionalDependencies || {}),
	        total: 0,
	        outdated: [],
	        vulnerable: [],
	        unused: [],
	      };

	      deps.total = deps.production.length + deps.development.length + deps.peer.length + deps.optional.length;

	      // Check for outdated dependencies
	      await this.checkOutdatedDependencies(deps);

	      // Check for security vulnerabilities
	      await this.checkVulnerabilities(deps);

	      this.analysis.dependencies = deps;
	    } catch (error) {
	      this.analysis.issues.push({
	        type: "error",
	        category: "dependencies",
	        message: "Failed to analyze dependencies",
	        severity: "medium",
	      });
	    }
	  }

	  async analyzeHealth() {
	    const health = {
	      score: 100,
	      status: "healthy",
	      checks: {
	        packageJson: this.analysis.structure.hasPackageJson,
	        lockfile: this.analysis.structure.hasLockfile,
	        nodeModules: this.analysis.structure.hasNodeModules,
	        gitRepo: this.analysis.structure.hasGitRepo,
	        noVulnerabilities: true,
	        upToDate: true,
	      },
	    };

	    // Calculate health score
	    let deductions = 0;

	    if (!health.checks.packageJson) deductions += 30;
	    if (!health.checks.lockfile) deductions += 20;
	    if (!health.checks.nodeModules) deductions += 10;
	    if (!health.checks.gitRepo) deductions += 5;

	    if (this.analysis.dependencies.vulnerable?.length > 0) {
	      deductions += this.analysis.dependencies.vulnerable.length * 5;
	      health.checks.noVulnerabilities = false;
	    }

	    if (this.analysis.dependencies.outdated?.length > 0) {
	      deductions += this.analysis.dependencies.outdated.length * 2;
	      health.checks.upToDate = false;
	    }

	    health.score = Math.max(0, health.score - deductions);

	    if (health.score >= 80) health.status = "healthy";
	    else if (health.score >= 60) health.status = "warning";
	    else health.status = "critical";

	    this.analysis.health = health;
	  }

	  async detectIssues() {
	    // Check for common project issues
	    if (!this.analysis.structure.hasPackageJson) {
	      this.analysis.issues.push({
	        type: "error",
	        category: "structure",
	        message: "No package.json found",
	        severity: "high",
	        fix: 'Run "npm init" to create a package.json file',
	      });
	    }

	    if (!this.analysis.structure.hasLockfile) {
	      this.analysis.issues.push({
	        type: "warning",
	        category: "structure",
	        message: "No lockfile found",
	        severity: "medium",
	        fix: 'Run "npm install" to generate a lockfile',
	      });
	    }

	    if (!this.analysis.structure.hasNodeModules && this.analysis.dependencies.total > 0) {
	      this.analysis.issues.push({
	        type: "warning",
	        category: "dependencies",
	        message: "Dependencies not installed",
	        severity: "medium",
	        fix: 'Run "bpack install" to install dependencies',
	      });
	    }

	    // Check for multiple lockfiles (conflicting package managers)
	    const lockfileCount = ["package-lock.json", "yarn.lock", "pnpm-lock.yaml", "bun.lockb"].filter((file) =>
	      fs.existsSync(path.join(this.projectPath, file)),
	    ).length;

	    if (lockfileCount > 1) {
	      this.analysis.issues.push({
	        type: "warning",
	        category: "structure",
	        message: "Multiple lockfiles detected",
	        severity: "medium",
	        fix: "Remove conflicting lockfiles and use one package manager",
	      });
	    }
	  }

	  async generateRecommendations() {
	    const recommendations = [];

	    // Performance recommendations
	    if (this.analysis.dependencies.total > 100) {
	      recommendations.push({
	        type: "performance",
	        message: "Consider auditing dependencies - high dependency count detected",
	        action: 'Run "bpack audit" to check for unused dependencies',
	      });
	    }

	    // Security recommendations
	    if (this.analysis.dependencies.vulnerable.length > 0) {
	      recommendations.push({
	        type: "security",
	        message: `${this.analysis.dependencies.vulnerable.length} vulnerable dependencies found`,
	        action: 'Run "bpack audit --fix" to fix security issues',
	      });
	    }

	    // Maintenance recommendations
	    if (this.analysis.dependencies.outdated.length > 5) {
	      recommendations.push({
	        type: "maintenance",
	        message: "Multiple outdated dependencies detected",
	        action: 'Run "bpack update" to update dependencies',
	      });
	    }

	    // Development workflow recommendations
	    if (!this.analysis.structure.hasGitRepo) {
	      recommendations.push({
	        type: "workflow",
	        message: "No git repository initialized",
	        action: 'Run "git init" to initialize version control',
	      });
	    }

	    this.analysis.recommendations = recommendations;
	  }

	  detectProjectType(packageJson) {
	    const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };

	    if (deps.react || deps["@types/react"]) return "react"
	    if (deps.vue || deps["@vue/cli"]) return "vue"
	    if (deps.angular || deps["@angular/core"]) return "angular"
	    if (deps.next || deps["next"]) return "nextjs"
	    if (deps.nuxt || deps["nuxt3"]) return "nuxt"
	    if (deps.svelte || deps["@sveltejs/kit"]) return "svelte"
	    if (deps.express || deps.fastify || deps.koa) return "backend"
	    if (packageJson.type === "module" || deps.typescript) return "modern-js"

	    return "javascript"
	  }

	  detectFrameworks(packageJson) {
	    const frameworks = [];
	    const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };

	    const frameworkMap = {
	      react: "React",
	      vue: "Vue.js",
	      "@angular/core": "Angular",
	      next: "Next.js",
	      nuxt: "Nuxt.js",
	      svelte: "Svelte",
	      "@sveltejs/kit": "SvelteKit",
	      express: "Express",
	      fastify: "Fastify",
	      koa: "Koa",
	    };

	    for (const [dep, framework] of Object.entries(frameworkMap)) {
	      if (deps[dep]) frameworks.push(framework);
	    }

	    return frameworks
	  }

	  detectBuildTools(packageJson) {
	    const buildTools = [];
	    const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };

	    const toolMap = {
	      webpack: "Webpack",
	      vite: "Vite",
	      rollup: "Rollup",
	      parcel: "Parcel",
	      esbuild: "ESBuild",
	      typescript: "TypeScript",
	      "@babel/core": "Babel",
	      eslint: "ESLint",
	      prettier: "Prettier",
	    };

	    for (const [dep, tool] of Object.entries(toolMap)) {
	      if (deps[dep]) buildTools.push(tool);
	    }

	    return buildTools
	  }

	  async checkOutdatedDependencies(deps) {
	    // This would integrate with the existing betterpack outdated command
	    try {
	      const result = spawnSync("node", [path.join(__dirname, "../index.js"), "outdated"], {
	        cwd: this.projectPath,
	        encoding: "utf8",
	        timeout: 30000,
	      });

	      if (result.stdout && result.stdout.trim() !== "All dependencies are up to date.") {
	        // Parse outdated output and populate deps.outdated
	        const lines = result.stdout.split("\n").filter((line) => line.trim());
	        deps.outdated = lines.map((line) => {
	          const parts = line.split(/\s+/);
	          return {
	            name: parts[0],
	            current: parts[1],
	            wanted: parts[2],
	            latest: parts[3],
	          }
	        });
	      }
	    } catch (error) {
	      console.log("[Agent] Could not check outdated dependencies:", error.message);
	    }
	  }

	  async checkVulnerabilities(deps) {
	    // This would integrate with the existing betterpack audit command
	    try {
	      const result = spawnSync("node", [path.join(__dirname, "../index.js"), "audit"], {
	        cwd: this.projectPath,
	        encoding: "utf8",
	        timeout: 30000,
	      });

	      if (result.stdout && result.stdout.includes("vulnerabilities")) {
	        // Parse audit output and populate deps.vulnerable
	        const vulnerabilityMatch = result.stdout.match(/(\d+) vulnerabilities/);
	        if (vulnerabilityMatch) {
	          const count = Number.parseInt(vulnerabilityMatch[1]);
	          deps.vulnerable = Array(count)
	            .fill()
	            .map((_, i) => ({
	              id: `vuln-${i}`,
	              severity: "unknown",
	              package: "unknown",
	            }));
	        }
	      }
	    } catch (error) {
	      console.log("[Agent] Could not check vulnerabilities:", error.message);
	    }
	  }

	  getAnalysisSummary() {
	    return {
	      projectType: this.analysis.structure.projectType,
	      healthScore: this.analysis.health.score,
	      healthStatus: this.analysis.health.status,
	      totalDependencies: this.analysis.dependencies.total,
	      issuesCount: this.analysis.issues.length,
	      recommendationsCount: this.analysis.recommendations.length,
	      frameworks: this.analysis.structure.frameworks,
	      buildTools: this.analysis.structure.buildTools,
	    }
	  }
	}

	projectAnalyzer = { ProjectAnalyzer };
	return projectAnalyzer;
}

var chokidar = {};

var utils$1 = {};

var constants$2;
var hasRequiredConstants$2;

function requireConstants$2 () {
	if (hasRequiredConstants$2) return constants$2;
	hasRequiredConstants$2 = 1;

	const path = require$$1;
	const WIN_SLASH = '\\\\/';
	const WIN_NO_SLASH = `[^${WIN_SLASH}]`;

	/**
	 * Posix glob regex
	 */

	const DOT_LITERAL = '\\.';
	const PLUS_LITERAL = '\\+';
	const QMARK_LITERAL = '\\?';
	const SLASH_LITERAL = '\\/';
	const ONE_CHAR = '(?=.)';
	const QMARK = '[^/]';
	const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
	const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
	const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
	const NO_DOT = `(?!${DOT_LITERAL})`;
	const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
	const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
	const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
	const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
	const STAR = `${QMARK}*?`;

	const POSIX_CHARS = {
	  DOT_LITERAL,
	  PLUS_LITERAL,
	  QMARK_LITERAL,
	  SLASH_LITERAL,
	  ONE_CHAR,
	  QMARK,
	  END_ANCHOR,
	  DOTS_SLASH,
	  NO_DOT,
	  NO_DOTS,
	  NO_DOT_SLASH,
	  NO_DOTS_SLASH,
	  QMARK_NO_DOT,
	  STAR,
	  START_ANCHOR
	};

	/**
	 * Windows glob regex
	 */

	const WINDOWS_CHARS = {
	  ...POSIX_CHARS,

	  SLASH_LITERAL: `[${WIN_SLASH}]`,
	  QMARK: WIN_NO_SLASH,
	  STAR: `${WIN_NO_SLASH}*?`,
	  DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
	  NO_DOT: `(?!${DOT_LITERAL})`,
	  NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
	  NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
	  NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
	  QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
	  START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
	  END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
	};

	/**
	 * POSIX Bracket Regex
	 */

	const POSIX_REGEX_SOURCE = {
	  alnum: 'a-zA-Z0-9',
	  alpha: 'a-zA-Z',
	  ascii: '\\x00-\\x7F',
	  blank: ' \\t',
	  cntrl: '\\x00-\\x1F\\x7F',
	  digit: '0-9',
	  graph: '\\x21-\\x7E',
	  lower: 'a-z',
	  print: '\\x20-\\x7E ',
	  punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
	  space: ' \\t\\r\\n\\v\\f',
	  upper: 'A-Z',
	  word: 'A-Za-z0-9_',
	  xdigit: 'A-Fa-f0-9'
	};

	constants$2 = {
	  MAX_LENGTH: 1024 * 64,
	  POSIX_REGEX_SOURCE,

	  // regular expressions
	  REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
	  REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
	  REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
	  REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
	  REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
	  REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,

	  // Replace globs with equivalent patterns to reduce parsing time.
	  REPLACEMENTS: {
	    '***': '*',
	    '**/**': '**',
	    '**/**/**': '**'
	  },

	  // Digits
	  CHAR_0: 48, /* 0 */
	  CHAR_9: 57, /* 9 */

	  // Alphabet chars.
	  CHAR_UPPERCASE_A: 65, /* A */
	  CHAR_LOWERCASE_A: 97, /* a */
	  CHAR_UPPERCASE_Z: 90, /* Z */
	  CHAR_LOWERCASE_Z: 122, /* z */

	  CHAR_LEFT_PARENTHESES: 40, /* ( */
	  CHAR_RIGHT_PARENTHESES: 41, /* ) */

	  CHAR_ASTERISK: 42, /* * */

	  // Non-alphabetic chars.
	  CHAR_AMPERSAND: 38, /* & */
	  CHAR_AT: 64, /* @ */
	  CHAR_BACKWARD_SLASH: 92, /* \ */
	  CHAR_CARRIAGE_RETURN: 13, /* \r */
	  CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
	  CHAR_COLON: 58, /* : */
	  CHAR_COMMA: 44, /* , */
	  CHAR_DOT: 46, /* . */
	  CHAR_DOUBLE_QUOTE: 34, /* " */
	  CHAR_EQUAL: 61, /* = */
	  CHAR_EXCLAMATION_MARK: 33, /* ! */
	  CHAR_FORM_FEED: 12, /* \f */
	  CHAR_FORWARD_SLASH: 47, /* / */
	  CHAR_GRAVE_ACCENT: 96, /* ` */
	  CHAR_HASH: 35, /* # */
	  CHAR_HYPHEN_MINUS: 45, /* - */
	  CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
	  CHAR_LEFT_CURLY_BRACE: 123, /* { */
	  CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
	  CHAR_LINE_FEED: 10, /* \n */
	  CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
	  CHAR_PERCENT: 37, /* % */
	  CHAR_PLUS: 43, /* + */
	  CHAR_QUESTION_MARK: 63, /* ? */
	  CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
	  CHAR_RIGHT_CURLY_BRACE: 125, /* } */
	  CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
	  CHAR_SEMICOLON: 59, /* ; */
	  CHAR_SINGLE_QUOTE: 39, /* ' */
	  CHAR_SPACE: 32, /*   */
	  CHAR_TAB: 9, /* \t */
	  CHAR_UNDERSCORE: 95, /* _ */
	  CHAR_VERTICAL_LINE: 124, /* | */
	  CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */

	  SEP: path.sep,

	  /**
	   * Create EXTGLOB_CHARS
	   */

	  extglobChars(chars) {
	    return {
	      '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
	      '?': { type: 'qmark', open: '(?:', close: ')?' },
	      '+': { type: 'plus', open: '(?:', close: ')+' },
	      '*': { type: 'star', open: '(?:', close: ')*' },
	      '@': { type: 'at', open: '(?:', close: ')' }
	    };
	  },

	  /**
	   * Create GLOB_CHARS
	   */

	  globChars(win32) {
	    return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
	  }
	};
	return constants$2;
}

var hasRequiredUtils$1;

function requireUtils$1 () {
	if (hasRequiredUtils$1) return utils$1;
	hasRequiredUtils$1 = 1;
	(function (exports) {

		const path = require$$1;
		const win32 = process.platform === 'win32';
		const {
		  REGEX_BACKSLASH,
		  REGEX_REMOVE_BACKSLASH,
		  REGEX_SPECIAL_CHARS,
		  REGEX_SPECIAL_CHARS_GLOBAL
		} = requireConstants$2();

		exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
		exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
		exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
		exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
		exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');

		exports.removeBackslashes = str => {
		  return str.replace(REGEX_REMOVE_BACKSLASH, match => {
		    return match === '\\' ? '' : match;
		  });
		};

		exports.supportsLookbehinds = () => {
		  const segs = process.version.slice(1).split('.').map(Number);
		  if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
		    return true;
		  }
		  return false;
		};

		exports.isWindows = options => {
		  if (options && typeof options.windows === 'boolean') {
		    return options.windows;
		  }
		  return win32 === true || path.sep === '\\';
		};

		exports.escapeLast = (input, char, lastIdx) => {
		  const idx = input.lastIndexOf(char, lastIdx);
		  if (idx === -1) return input;
		  if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
		  return `${input.slice(0, idx)}\\${input.slice(idx)}`;
		};

		exports.removePrefix = (input, state = {}) => {
		  let output = input;
		  if (output.startsWith('./')) {
		    output = output.slice(2);
		    state.prefix = './';
		  }
		  return output;
		};

		exports.wrapOutput = (input, state = {}, options = {}) => {
		  const prepend = options.contains ? '' : '^';
		  const append = options.contains ? '' : '$';

		  let output = `${prepend}(?:${input})${append}`;
		  if (state.negated === true) {
		    output = `(?:^(?!${output}).*$)`;
		  }
		  return output;
		}; 
	} (utils$1));
	return utils$1;
}

var scan_1;
var hasRequiredScan;

function requireScan () {
	if (hasRequiredScan) return scan_1;
	hasRequiredScan = 1;

	const utils = requireUtils$1();
	const {
	  CHAR_ASTERISK,             /* * */
	  CHAR_AT,                   /* @ */
	  CHAR_BACKWARD_SLASH,       /* \ */
	  CHAR_COMMA,                /* , */
	  CHAR_DOT,                  /* . */
	  CHAR_EXCLAMATION_MARK,     /* ! */
	  CHAR_FORWARD_SLASH,        /* / */
	  CHAR_LEFT_CURLY_BRACE,     /* { */
	  CHAR_LEFT_PARENTHESES,     /* ( */
	  CHAR_LEFT_SQUARE_BRACKET,  /* [ */
	  CHAR_PLUS,                 /* + */
	  CHAR_QUESTION_MARK,        /* ? */
	  CHAR_RIGHT_CURLY_BRACE,    /* } */
	  CHAR_RIGHT_PARENTHESES,    /* ) */
	  CHAR_RIGHT_SQUARE_BRACKET  /* ] */
	} = requireConstants$2();

	const isPathSeparator = code => {
	  return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
	};

	const depth = token => {
	  if (token.isPrefix !== true) {
	    token.depth = token.isGlobstar ? Infinity : 1;
	  }
	};

	/**
	 * Quickly scans a glob pattern and returns an object with a handful of
	 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
	 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
	 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
	 *
	 * ```js
	 * const pm = require('picomatch');
	 * console.log(pm.scan('foo/bar/*.js'));
	 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
	 * ```
	 * @param {String} `str`
	 * @param {Object} `options`
	 * @return {Object} Returns an object with tokens and regex source string.
	 * @api public
	 */

	const scan = (input, options) => {
	  const opts = options || {};

	  const length = input.length - 1;
	  const scanToEnd = opts.parts === true || opts.scanToEnd === true;
	  const slashes = [];
	  const tokens = [];
	  const parts = [];

	  let str = input;
	  let index = -1;
	  let start = 0;
	  let lastIndex = 0;
	  let isBrace = false;
	  let isBracket = false;
	  let isGlob = false;
	  let isExtglob = false;
	  let isGlobstar = false;
	  let braceEscaped = false;
	  let backslashes = false;
	  let negated = false;
	  let negatedExtglob = false;
	  let finished = false;
	  let braces = 0;
	  let prev;
	  let code;
	  let token = { value: '', depth: 0, isGlob: false };

	  const eos = () => index >= length;
	  const peek = () => str.charCodeAt(index + 1);
	  const advance = () => {
	    prev = code;
	    return str.charCodeAt(++index);
	  };

	  while (index < length) {
	    code = advance();
	    let next;

	    if (code === CHAR_BACKWARD_SLASH) {
	      backslashes = token.backslashes = true;
	      code = advance();

	      if (code === CHAR_LEFT_CURLY_BRACE) {
	        braceEscaped = true;
	      }
	      continue;
	    }

	    if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
	      braces++;

	      while (eos() !== true && (code = advance())) {
	        if (code === CHAR_BACKWARD_SLASH) {
	          backslashes = token.backslashes = true;
	          advance();
	          continue;
	        }

	        if (code === CHAR_LEFT_CURLY_BRACE) {
	          braces++;
	          continue;
	        }

	        if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
	          isBrace = token.isBrace = true;
	          isGlob = token.isGlob = true;
	          finished = true;

	          if (scanToEnd === true) {
	            continue;
	          }

	          break;
	        }

	        if (braceEscaped !== true && code === CHAR_COMMA) {
	          isBrace = token.isBrace = true;
	          isGlob = token.isGlob = true;
	          finished = true;

	          if (scanToEnd === true) {
	            continue;
	          }

	          break;
	        }

	        if (code === CHAR_RIGHT_CURLY_BRACE) {
	          braces--;

	          if (braces === 0) {
	            braceEscaped = false;
	            isBrace = token.isBrace = true;
	            finished = true;
	            break;
	          }
	        }
	      }

	      if (scanToEnd === true) {
	        continue;
	      }

	      break;
	    }

	    if (code === CHAR_FORWARD_SLASH) {
	      slashes.push(index);
	      tokens.push(token);
	      token = { value: '', depth: 0, isGlob: false };

	      if (finished === true) continue;
	      if (prev === CHAR_DOT && index === (start + 1)) {
	        start += 2;
	        continue;
	      }

	      lastIndex = index + 1;
	      continue;
	    }

	    if (opts.noext !== true) {
	      const isExtglobChar = code === CHAR_PLUS
	        || code === CHAR_AT
	        || code === CHAR_ASTERISK
	        || code === CHAR_QUESTION_MARK
	        || code === CHAR_EXCLAMATION_MARK;

	      if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
	        isGlob = token.isGlob = true;
	        isExtglob = token.isExtglob = true;
	        finished = true;
	        if (code === CHAR_EXCLAMATION_MARK && index === start) {
	          negatedExtglob = true;
	        }

	        if (scanToEnd === true) {
	          while (eos() !== true && (code = advance())) {
	            if (code === CHAR_BACKWARD_SLASH) {
	              backslashes = token.backslashes = true;
	              code = advance();
	              continue;
	            }

	            if (code === CHAR_RIGHT_PARENTHESES) {
	              isGlob = token.isGlob = true;
	              finished = true;
	              break;
	            }
	          }
	          continue;
	        }
	        break;
	      }
	    }

	    if (code === CHAR_ASTERISK) {
	      if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
	      isGlob = token.isGlob = true;
	      finished = true;

	      if (scanToEnd === true) {
	        continue;
	      }
	      break;
	    }

	    if (code === CHAR_QUESTION_MARK) {
	      isGlob = token.isGlob = true;
	      finished = true;

	      if (scanToEnd === true) {
	        continue;
	      }
	      break;
	    }

	    if (code === CHAR_LEFT_SQUARE_BRACKET) {
	      while (eos() !== true && (next = advance())) {
	        if (next === CHAR_BACKWARD_SLASH) {
	          backslashes = token.backslashes = true;
	          advance();
	          continue;
	        }

	        if (next === CHAR_RIGHT_SQUARE_BRACKET) {
	          isBracket = token.isBracket = true;
	          isGlob = token.isGlob = true;
	          finished = true;
	          break;
	        }
	      }

	      if (scanToEnd === true) {
	        continue;
	      }

	      break;
	    }

	    if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
	      negated = token.negated = true;
	      start++;
	      continue;
	    }

	    if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
	      isGlob = token.isGlob = true;

	      if (scanToEnd === true) {
	        while (eos() !== true && (code = advance())) {
	          if (code === CHAR_LEFT_PARENTHESES) {
	            backslashes = token.backslashes = true;
	            code = advance();
	            continue;
	          }

	          if (code === CHAR_RIGHT_PARENTHESES) {
	            finished = true;
	            break;
	          }
	        }
	        continue;
	      }
	      break;
	    }

	    if (isGlob === true) {
	      finished = true;

	      if (scanToEnd === true) {
	        continue;
	      }

	      break;
	    }
	  }

	  if (opts.noext === true) {
	    isExtglob = false;
	    isGlob = false;
	  }

	  let base = str;
	  let prefix = '';
	  let glob = '';

	  if (start > 0) {
	    prefix = str.slice(0, start);
	    str = str.slice(start);
	    lastIndex -= start;
	  }

	  if (base && isGlob === true && lastIndex > 0) {
	    base = str.slice(0, lastIndex);
	    glob = str.slice(lastIndex);
	  } else if (isGlob === true) {
	    base = '';
	    glob = str;
	  } else {
	    base = str;
	  }

	  if (base && base !== '' && base !== '/' && base !== str) {
	    if (isPathSeparator(base.charCodeAt(base.length - 1))) {
	      base = base.slice(0, -1);
	    }
	  }

	  if (opts.unescape === true) {
	    if (glob) glob = utils.removeBackslashes(glob);

	    if (base && backslashes === true) {
	      base = utils.removeBackslashes(base);
	    }
	  }

	  const state = {
	    prefix,
	    input,
	    start,
	    base,
	    glob,
	    isBrace,
	    isBracket,
	    isGlob,
	    isExtglob,
	    isGlobstar,
	    negated,
	    negatedExtglob
	  };

	  if (opts.tokens === true) {
	    state.maxDepth = 0;
	    if (!isPathSeparator(code)) {
	      tokens.push(token);
	    }
	    state.tokens = tokens;
	  }

	  if (opts.parts === true || opts.tokens === true) {
	    let prevIndex;

	    for (let idx = 0; idx < slashes.length; idx++) {
	      const n = prevIndex ? prevIndex + 1 : start;
	      const i = slashes[idx];
	      const value = input.slice(n, i);
	      if (opts.tokens) {
	        if (idx === 0 && start !== 0) {
	          tokens[idx].isPrefix = true;
	          tokens[idx].value = prefix;
	        } else {
	          tokens[idx].value = value;
	        }
	        depth(tokens[idx]);
	        state.maxDepth += tokens[idx].depth;
	      }
	      if (idx !== 0 || value !== '') {
	        parts.push(value);
	      }
	      prevIndex = i;
	    }

	    if (prevIndex && prevIndex + 1 < input.length) {
	      const value = input.slice(prevIndex + 1);
	      parts.push(value);

	      if (opts.tokens) {
	        tokens[tokens.length - 1].value = value;
	        depth(tokens[tokens.length - 1]);
	        state.maxDepth += tokens[tokens.length - 1].depth;
	      }
	    }

	    state.slashes = slashes;
	    state.parts = parts;
	  }

	  return state;
	};

	scan_1 = scan;
	return scan_1;
}

var parse_1$1;
var hasRequiredParse$1;

function requireParse$1 () {
	if (hasRequiredParse$1) return parse_1$1;
	hasRequiredParse$1 = 1;

	const constants = requireConstants$2();
	const utils = requireUtils$1();

	/**
	 * Constants
	 */

	const {
	  MAX_LENGTH,
	  POSIX_REGEX_SOURCE,
	  REGEX_NON_SPECIAL_CHARS,
	  REGEX_SPECIAL_CHARS_BACKREF,
	  REPLACEMENTS
	} = constants;

	/**
	 * Helpers
	 */

	const expandRange = (args, options) => {
	  if (typeof options.expandRange === 'function') {
	    return options.expandRange(...args, options);
	  }

	  args.sort();
	  const value = `[${args.join('-')}]`;

	  try {
	    /* eslint-disable-next-line no-new */
	    new RegExp(value);
	  } catch (ex) {
	    return args.map(v => utils.escapeRegex(v)).join('..');
	  }

	  return value;
	};

	/**
	 * Create the message for a syntax error
	 */

	const syntaxError = (type, char) => {
	  return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
	};

	/**
	 * Parse the given input string.
	 * @param {String} input
	 * @param {Object} options
	 * @return {Object}
	 */

	const parse = (input, options) => {
	  if (typeof input !== 'string') {
	    throw new TypeError('Expected a string');
	  }

	  input = REPLACEMENTS[input] || input;

	  const opts = { ...options };
	  const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;

	  let len = input.length;
	  if (len > max) {
	    throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
	  }

	  const bos = { type: 'bos', value: '', output: opts.prepend || '' };
	  const tokens = [bos];

	  const capture = opts.capture ? '' : '?:';
	  const win32 = utils.isWindows(options);

	  // create constants based on platform, for windows or posix
	  const PLATFORM_CHARS = constants.globChars(win32);
	  const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);

	  const {
	    DOT_LITERAL,
	    PLUS_LITERAL,
	    SLASH_LITERAL,
	    ONE_CHAR,
	    DOTS_SLASH,
	    NO_DOT,
	    NO_DOT_SLASH,
	    NO_DOTS_SLASH,
	    QMARK,
	    QMARK_NO_DOT,
	    STAR,
	    START_ANCHOR
	  } = PLATFORM_CHARS;

	  const globstar = opts => {
	    return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
	  };

	  const nodot = opts.dot ? '' : NO_DOT;
	  const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
	  let star = opts.bash === true ? globstar(opts) : STAR;

	  if (opts.capture) {
	    star = `(${star})`;
	  }

	  // minimatch options support
	  if (typeof opts.noext === 'boolean') {
	    opts.noextglob = opts.noext;
	  }

	  const state = {
	    input,
	    index: -1,
	    start: 0,
	    dot: opts.dot === true,
	    consumed: '',
	    output: '',
	    prefix: '',
	    backtrack: false,
	    negated: false,
	    brackets: 0,
	    braces: 0,
	    parens: 0,
	    quotes: 0,
	    globstar: false,
	    tokens
	  };

	  input = utils.removePrefix(input, state);
	  len = input.length;

	  const extglobs = [];
	  const braces = [];
	  const stack = [];
	  let prev = bos;
	  let value;

	  /**
	   * Tokenizing helpers
	   */

	  const eos = () => state.index === len - 1;
	  const peek = state.peek = (n = 1) => input[state.index + n];
	  const advance = state.advance = () => input[++state.index] || '';
	  const remaining = () => input.slice(state.index + 1);
	  const consume = (value = '', num = 0) => {
	    state.consumed += value;
	    state.index += num;
	  };

	  const append = token => {
	    state.output += token.output != null ? token.output : token.value;
	    consume(token.value);
	  };

	  const negate = () => {
	    let count = 1;

	    while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {
	      advance();
	      state.start++;
	      count++;
	    }

	    if (count % 2 === 0) {
	      return false;
	    }

	    state.negated = true;
	    state.start++;
	    return true;
	  };

	  const increment = type => {
	    state[type]++;
	    stack.push(type);
	  };

	  const decrement = type => {
	    state[type]--;
	    stack.pop();
	  };

	  /**
	   * Push tokens onto the tokens array. This helper speeds up
	   * tokenizing by 1) helping us avoid backtracking as much as possible,
	   * and 2) helping us avoid creating extra tokens when consecutive
	   * characters are plain text. This improves performance and simplifies
	   * lookbehinds.
	   */

	  const push = tok => {
	    if (prev.type === 'globstar') {
	      const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');
	      const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));

	      if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {
	        state.output = state.output.slice(0, -prev.output.length);
	        prev.type = 'star';
	        prev.value = '*';
	        prev.output = star;
	        state.output += prev.output;
	      }
	    }

	    if (extglobs.length && tok.type !== 'paren') {
	      extglobs[extglobs.length - 1].inner += tok.value;
	    }

	    if (tok.value || tok.output) append(tok);
	    if (prev && prev.type === 'text' && tok.type === 'text') {
	      prev.value += tok.value;
	      prev.output = (prev.output || '') + tok.value;
	      return;
	    }

	    tok.prev = prev;
	    tokens.push(tok);
	    prev = tok;
	  };

	  const extglobOpen = (type, value) => {
	    const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };

	    token.prev = prev;
	    token.parens = state.parens;
	    token.output = state.output;
	    const output = (opts.capture ? '(' : '') + token.open;

	    increment('parens');
	    push({ type, value, output: state.output ? '' : ONE_CHAR });
	    push({ type: 'paren', extglob: true, value: advance(), output });
	    extglobs.push(token);
	  };

	  const extglobClose = token => {
	    let output = token.close + (opts.capture ? ')' : '');
	    let rest;

	    if (token.type === 'negate') {
	      let extglobStar = star;

	      if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {
	        extglobStar = globstar(opts);
	      }

	      if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {
	        output = token.close = `)$))${extglobStar}`;
	      }

	      if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
	        // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.
	        // In this case, we need to parse the string and use it in the output of the original pattern.
	        // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.
	        //
	        // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.
	        const expression = parse(rest, { ...options, fastpaths: false }).output;

	        output = token.close = `)${expression})${extglobStar})`;
	      }

	      if (token.prev.type === 'bos') {
	        state.negatedExtglob = true;
	      }
	    }

	    push({ type: 'paren', extglob: true, value, output });
	    decrement('parens');
	  };

	  /**
	   * Fast paths
	   */

	  if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
	    let backslashes = false;

	    let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
	      if (first === '\\') {
	        backslashes = true;
	        return m;
	      }

	      if (first === '?') {
	        if (esc) {
	          return esc + first + (rest ? QMARK.repeat(rest.length) : '');
	        }
	        if (index === 0) {
	          return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');
	        }
	        return QMARK.repeat(chars.length);
	      }

	      if (first === '.') {
	        return DOT_LITERAL.repeat(chars.length);
	      }

	      if (first === '*') {
	        if (esc) {
	          return esc + first + (rest ? star : '');
	        }
	        return star;
	      }
	      return esc ? m : `\\${m}`;
	    });

	    if (backslashes === true) {
	      if (opts.unescape === true) {
	        output = output.replace(/\\/g, '');
	      } else {
	        output = output.replace(/\\+/g, m => {
	          return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');
	        });
	      }
	    }

	    if (output === input && opts.contains === true) {
	      state.output = input;
	      return state;
	    }

	    state.output = utils.wrapOutput(output, state, options);
	    return state;
	  }

	  /**
	   * Tokenize input until we reach end-of-string
	   */

	  while (!eos()) {
	    value = advance();

	    if (value === '\u0000') {
	      continue;
	    }

	    /**
	     * Escaped characters
	     */

	    if (value === '\\') {
	      const next = peek();

	      if (next === '/' && opts.bash !== true) {
	        continue;
	      }

	      if (next === '.' || next === ';') {
	        continue;
	      }

	      if (!next) {
	        value += '\\';
	        push({ type: 'text', value });
	        continue;
	      }

	      // collapse slashes to reduce potential for exploits
	      const match = /^\\+/.exec(remaining());
	      let slashes = 0;

	      if (match && match[0].length > 2) {
	        slashes = match[0].length;
	        state.index += slashes;
	        if (slashes % 2 !== 0) {
	          value += '\\';
	        }
	      }

	      if (opts.unescape === true) {
	        value = advance();
	      } else {
	        value += advance();
	      }

	      if (state.brackets === 0) {
	        push({ type: 'text', value });
	        continue;
	      }
	    }

	    /**
	     * If we're inside a regex character class, continue
	     * until we reach the closing bracket.
	     */

	    if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {
	      if (opts.posix !== false && value === ':') {
	        const inner = prev.value.slice(1);
	        if (inner.includes('[')) {
	          prev.posix = true;

	          if (inner.includes(':')) {
	            const idx = prev.value.lastIndexOf('[');
	            const pre = prev.value.slice(0, idx);
	            const rest = prev.value.slice(idx + 2);
	            const posix = POSIX_REGEX_SOURCE[rest];
	            if (posix) {
	              prev.value = pre + posix;
	              state.backtrack = true;
	              advance();

	              if (!bos.output && tokens.indexOf(prev) === 1) {
	                bos.output = ONE_CHAR;
	              }
	              continue;
	            }
	          }
	        }
	      }

	      if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {
	        value = `\\${value}`;
	      }

	      if (value === ']' && (prev.value === '[' || prev.value === '[^')) {
	        value = `\\${value}`;
	      }

	      if (opts.posix === true && value === '!' && prev.value === '[') {
	        value = '^';
	      }

	      prev.value += value;
	      append({ value });
	      continue;
	    }

	    /**
	     * If we're inside a quoted string, continue
	     * until we reach the closing double quote.
	     */

	    if (state.quotes === 1 && value !== '"') {
	      value = utils.escapeRegex(value);
	      prev.value += value;
	      append({ value });
	      continue;
	    }

	    /**
	     * Double quotes
	     */

	    if (value === '"') {
	      state.quotes = state.quotes === 1 ? 0 : 1;
	      if (opts.keepQuotes === true) {
	        push({ type: 'text', value });
	      }
	      continue;
	    }

	    /**
	     * Parentheses
	     */

	    if (value === '(') {
	      increment('parens');
	      push({ type: 'paren', value });
	      continue;
	    }

	    if (value === ')') {
	      if (state.parens === 0 && opts.strictBrackets === true) {
	        throw new SyntaxError(syntaxError('opening', '('));
	      }

	      const extglob = extglobs[extglobs.length - 1];
	      if (extglob && state.parens === extglob.parens + 1) {
	        extglobClose(extglobs.pop());
	        continue;
	      }

	      push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });
	      decrement('parens');
	      continue;
	    }

	    /**
	     * Square brackets
	     */

	    if (value === '[') {
	      if (opts.nobracket === true || !remaining().includes(']')) {
	        if (opts.nobracket !== true && opts.strictBrackets === true) {
	          throw new SyntaxError(syntaxError('closing', ']'));
	        }

	        value = `\\${value}`;
	      } else {
	        increment('brackets');
	      }

	      push({ type: 'bracket', value });
	      continue;
	    }

	    if (value === ']') {
	      if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {
	        push({ type: 'text', value, output: `\\${value}` });
	        continue;
	      }

	      if (state.brackets === 0) {
	        if (opts.strictBrackets === true) {
	          throw new SyntaxError(syntaxError('opening', '['));
	        }

	        push({ type: 'text', value, output: `\\${value}` });
	        continue;
	      }

	      decrement('brackets');

	      const prevValue = prev.value.slice(1);
	      if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {
	        value = `/${value}`;
	      }

	      prev.value += value;
	      append({ value });

	      // when literal brackets are explicitly disabled
	      // assume we should match with a regex character class
	      if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) {
	        continue;
	      }

	      const escaped = utils.escapeRegex(prev.value);
	      state.output = state.output.slice(0, -prev.value.length);

	      // when literal brackets are explicitly enabled
	      // assume we should escape the brackets to match literal characters
	      if (opts.literalBrackets === true) {
	        state.output += escaped;
	        prev.value = escaped;
	        continue;
	      }

	      // when the user specifies nothing, try to match both
	      prev.value = `(${capture}${escaped}|${prev.value})`;
	      state.output += prev.value;
	      continue;
	    }

	    /**
	     * Braces
	     */

	    if (value === '{' && opts.nobrace !== true) {
	      increment('braces');

	      const open = {
	        type: 'brace',
	        value,
	        output: '(',
	        outputIndex: state.output.length,
	        tokensIndex: state.tokens.length
	      };

	      braces.push(open);
	      push(open);
	      continue;
	    }

	    if (value === '}') {
	      const brace = braces[braces.length - 1];

	      if (opts.nobrace === true || !brace) {
	        push({ type: 'text', value, output: value });
	        continue;
	      }

	      let output = ')';

	      if (brace.dots === true) {
	        const arr = tokens.slice();
	        const range = [];

	        for (let i = arr.length - 1; i >= 0; i--) {
	          tokens.pop();
	          if (arr[i].type === 'brace') {
	            break;
	          }
	          if (arr[i].type !== 'dots') {
	            range.unshift(arr[i].value);
	          }
	        }

	        output = expandRange(range, opts);
	        state.backtrack = true;
	      }

	      if (brace.comma !== true && brace.dots !== true) {
	        const out = state.output.slice(0, brace.outputIndex);
	        const toks = state.tokens.slice(brace.tokensIndex);
	        brace.value = brace.output = '\\{';
	        value = output = '\\}';
	        state.output = out;
	        for (const t of toks) {
	          state.output += (t.output || t.value);
	        }
	      }

	      push({ type: 'brace', value, output });
	      decrement('braces');
	      braces.pop();
	      continue;
	    }

	    /**
	     * Pipes
	     */

	    if (value === '|') {
	      if (extglobs.length > 0) {
	        extglobs[extglobs.length - 1].conditions++;
	      }
	      push({ type: 'text', value });
	      continue;
	    }

	    /**
	     * Commas
	     */

	    if (value === ',') {
	      let output = value;

	      const brace = braces[braces.length - 1];
	      if (brace && stack[stack.length - 1] === 'braces') {
	        brace.comma = true;
	        output = '|';
	      }

	      push({ type: 'comma', value, output });
	      continue;
	    }

	    /**
	     * Slashes
	     */

	    if (value === '/') {
	      // if the beginning of the glob is "./", advance the start
	      // to the current index, and don't add the "./" characters
	      // to the state. This greatly simplifies lookbehinds when
	      // checking for BOS characters like "!" and "." (not "./")
	      if (prev.type === 'dot' && state.index === state.start + 1) {
	        state.start = state.index + 1;
	        state.consumed = '';
	        state.output = '';
	        tokens.pop();
	        prev = bos; // reset "prev" to the first token
	        continue;
	      }

	      push({ type: 'slash', value, output: SLASH_LITERAL });
	      continue;
	    }

	    /**
	     * Dots
	     */

	    if (value === '.') {
	      if (state.braces > 0 && prev.type === 'dot') {
	        if (prev.value === '.') prev.output = DOT_LITERAL;
	        const brace = braces[braces.length - 1];
	        prev.type = 'dots';
	        prev.output += value;
	        prev.value += value;
	        brace.dots = true;
	        continue;
	      }

	      if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {
	        push({ type: 'text', value, output: DOT_LITERAL });
	        continue;
	      }

	      push({ type: 'dot', value, output: DOT_LITERAL });
	      continue;
	    }

	    /**
	     * Question marks
	     */

	    if (value === '?') {
	      const isGroup = prev && prev.value === '(';
	      if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
	        extglobOpen('qmark', value);
	        continue;
	      }

	      if (prev && prev.type === 'paren') {
	        const next = peek();
	        let output = value;

	        if (next === '<' && !utils.supportsLookbehinds()) {
	          throw new Error('Node.js v10 or higher is required for regex lookbehinds');
	        }

	        if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
	          output = `\\${value}`;
	        }

	        push({ type: 'text', value, output });
	        continue;
	      }

	      if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {
	        push({ type: 'qmark', value, output: QMARK_NO_DOT });
	        continue;
	      }

	      push({ type: 'qmark', value, output: QMARK });
	      continue;
	    }

	    /**
	     * Exclamation
	     */

	    if (value === '!') {
	      if (opts.noextglob !== true && peek() === '(') {
	        if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {
	          extglobOpen('negate', value);
	          continue;
	        }
	      }

	      if (opts.nonegate !== true && state.index === 0) {
	        negate();
	        continue;
	      }
	    }

	    /**
	     * Plus
	     */

	    if (value === '+') {
	      if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
	        extglobOpen('plus', value);
	        continue;
	      }

	      if ((prev && prev.value === '(') || opts.regex === false) {
	        push({ type: 'plus', value, output: PLUS_LITERAL });
	        continue;
	      }

	      if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {
	        push({ type: 'plus', value });
	        continue;
	      }

	      push({ type: 'plus', value: PLUS_LITERAL });
	      continue;
	    }

	    /**
	     * Plain text
	     */

	    if (value === '@') {
	      if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
	        push({ type: 'at', extglob: true, value, output: '' });
	        continue;
	      }

	      push({ type: 'text', value });
	      continue;
	    }

	    /**
	     * Plain text
	     */

	    if (value !== '*') {
	      if (value === '$' || value === '^') {
	        value = `\\${value}`;
	      }

	      const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
	      if (match) {
	        value += match[0];
	        state.index += match[0].length;
	      }

	      push({ type: 'text', value });
	      continue;
	    }

	    /**
	     * Stars
	     */

	    if (prev && (prev.type === 'globstar' || prev.star === true)) {
	      prev.type = 'star';
	      prev.star = true;
	      prev.value += value;
	      prev.output = star;
	      state.backtrack = true;
	      state.globstar = true;
	      consume(value);
	      continue;
	    }

	    let rest = remaining();
	    if (opts.noextglob !== true && /^\([^?]/.test(rest)) {
	      extglobOpen('star', value);
	      continue;
	    }

	    if (prev.type === 'star') {
	      if (opts.noglobstar === true) {
	        consume(value);
	        continue;
	      }

	      const prior = prev.prev;
	      const before = prior.prev;
	      const isStart = prior.type === 'slash' || prior.type === 'bos';
	      const afterStar = before && (before.type === 'star' || before.type === 'globstar');

	      if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {
	        push({ type: 'star', value, output: '' });
	        continue;
	      }

	      const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');
	      const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');
	      if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {
	        push({ type: 'star', value, output: '' });
	        continue;
	      }

	      // strip consecutive `/**/`
	      while (rest.slice(0, 3) === '/**') {
	        const after = input[state.index + 4];
	        if (after && after !== '/') {
	          break;
	        }
	        rest = rest.slice(3);
	        consume('/**', 3);
	      }

	      if (prior.type === 'bos' && eos()) {
	        prev.type = 'globstar';
	        prev.value += value;
	        prev.output = globstar(opts);
	        state.output = prev.output;
	        state.globstar = true;
	        consume(value);
	        continue;
	      }

	      if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {
	        state.output = state.output.slice(0, -(prior.output + prev.output).length);
	        prior.output = `(?:${prior.output}`;

	        prev.type = 'globstar';
	        prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');
	        prev.value += value;
	        state.globstar = true;
	        state.output += prior.output + prev.output;
	        consume(value);
	        continue;
	      }

	      if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {
	        const end = rest[1] !== void 0 ? '|$' : '';

	        state.output = state.output.slice(0, -(prior.output + prev.output).length);
	        prior.output = `(?:${prior.output}`;

	        prev.type = 'globstar';
	        prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
	        prev.value += value;

	        state.output += prior.output + prev.output;
	        state.globstar = true;

	        consume(value + advance());

	        push({ type: 'slash', value: '/', output: '' });
	        continue;
	      }

	      if (prior.type === 'bos' && rest[0] === '/') {
	        prev.type = 'globstar';
	        prev.value += value;
	        prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
	        state.output = prev.output;
	        state.globstar = true;
	        consume(value + advance());
	        push({ type: 'slash', value: '/', output: '' });
	        continue;
	      }

	      // remove single star from output
	      state.output = state.output.slice(0, -prev.output.length);

	      // reset previous token to globstar
	      prev.type = 'globstar';
	      prev.output = globstar(opts);
	      prev.value += value;

	      // reset output with globstar
	      state.output += prev.output;
	      state.globstar = true;
	      consume(value);
	      continue;
	    }

	    const token = { type: 'star', value, output: star };

	    if (opts.bash === true) {
	      token.output = '.*?';
	      if (prev.type === 'bos' || prev.type === 'slash') {
	        token.output = nodot + token.output;
	      }
	      push(token);
	      continue;
	    }

	    if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {
	      token.output = value;
	      push(token);
	      continue;
	    }

	    if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {
	      if (prev.type === 'dot') {
	        state.output += NO_DOT_SLASH;
	        prev.output += NO_DOT_SLASH;

	      } else if (opts.dot === true) {
	        state.output += NO_DOTS_SLASH;
	        prev.output += NO_DOTS_SLASH;

	      } else {
	        state.output += nodot;
	        prev.output += nodot;
	      }

	      if (peek() !== '*') {
	        state.output += ONE_CHAR;
	        prev.output += ONE_CHAR;
	      }
	    }

	    push(token);
	  }

	  while (state.brackets > 0) {
	    if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));
	    state.output = utils.escapeLast(state.output, '[');
	    decrement('brackets');
	  }

	  while (state.parens > 0) {
	    if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));
	    state.output = utils.escapeLast(state.output, '(');
	    decrement('parens');
	  }

	  while (state.braces > 0) {
	    if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));
	    state.output = utils.escapeLast(state.output, '{');
	    decrement('braces');
	  }

	  if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {
	    push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });
	  }

	  // rebuild the output if we had to backtrack at any point
	  if (state.backtrack === true) {
	    state.output = '';

	    for (const token of state.tokens) {
	      state.output += token.output != null ? token.output : token.value;

	      if (token.suffix) {
	        state.output += token.suffix;
	      }
	    }
	  }

	  return state;
	};

	/**
	 * Fast paths for creating regular expressions for common glob patterns.
	 * This can significantly speed up processing and has very little downside
	 * impact when none of the fast paths match.
	 */

	parse.fastpaths = (input, options) => {
	  const opts = { ...options };
	  const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
	  const len = input.length;
	  if (len > max) {
	    throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
	  }

	  input = REPLACEMENTS[input] || input;
	  const win32 = utils.isWindows(options);

	  // create constants based on platform, for windows or posix
	  const {
	    DOT_LITERAL,
	    SLASH_LITERAL,
	    ONE_CHAR,
	    DOTS_SLASH,
	    NO_DOT,
	    NO_DOTS,
	    NO_DOTS_SLASH,
	    STAR,
	    START_ANCHOR
	  } = constants.globChars(win32);

	  const nodot = opts.dot ? NO_DOTS : NO_DOT;
	  const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
	  const capture = opts.capture ? '' : '?:';
	  const state = { negated: false, prefix: '' };
	  let star = opts.bash === true ? '.*?' : STAR;

	  if (opts.capture) {
	    star = `(${star})`;
	  }

	  const globstar = opts => {
	    if (opts.noglobstar === true) return star;
	    return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
	  };

	  const create = str => {
	    switch (str) {
	      case '*':
	        return `${nodot}${ONE_CHAR}${star}`;

	      case '.*':
	        return `${DOT_LITERAL}${ONE_CHAR}${star}`;

	      case '*.*':
	        return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;

	      case '*/*':
	        return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;

	      case '**':
	        return nodot + globstar(opts);

	      case '**/*':
	        return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;

	      case '**/*.*':
	        return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;

	      case '**/.*':
	        return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;

	      default: {
	        const match = /^(.*?)\.(\w+)$/.exec(str);
	        if (!match) return;

	        const source = create(match[1]);
	        if (!source) return;

	        return source + DOT_LITERAL + match[2];
	      }
	    }
	  };

	  const output = utils.removePrefix(input, state);
	  let source = create(output);

	  if (source && opts.strictSlashes !== true) {
	    source += `${SLASH_LITERAL}?`;
	  }

	  return source;
	};

	parse_1$1 = parse;
	return parse_1$1;
}

var picomatch_1;
var hasRequiredPicomatch$1;

function requirePicomatch$1 () {
	if (hasRequiredPicomatch$1) return picomatch_1;
	hasRequiredPicomatch$1 = 1;

	const path = require$$1;
	const scan = requireScan();
	const parse = requireParse$1();
	const utils = requireUtils$1();
	const constants = requireConstants$2();
	const isObject = val => val && typeof val === 'object' && !Array.isArray(val);

	/**
	 * Creates a matcher function from one or more glob patterns. The
	 * returned function takes a string to match as its first argument,
	 * and returns true if the string is a match. The returned matcher
	 * function also takes a boolean as the second argument that, when true,
	 * returns an object with additional information.
	 *
	 * ```js
	 * const picomatch = require('picomatch');
	 * // picomatch(glob[, options]);
	 *
	 * const isMatch = picomatch('*.!(*a)');
	 * console.log(isMatch('a.a')); //=> false
	 * console.log(isMatch('a.b')); //=> true
	 * ```
	 * @name picomatch
	 * @param {String|Array} `globs` One or more glob patterns.
	 * @param {Object=} `options`
	 * @return {Function=} Returns a matcher function.
	 * @api public
	 */

	const picomatch = (glob, options, returnState = false) => {
	  if (Array.isArray(glob)) {
	    const fns = glob.map(input => picomatch(input, options, returnState));
	    const arrayMatcher = str => {
	      for (const isMatch of fns) {
	        const state = isMatch(str);
	        if (state) return state;
	      }
	      return false;
	    };
	    return arrayMatcher;
	  }

	  const isState = isObject(glob) && glob.tokens && glob.input;

	  if (glob === '' || (typeof glob !== 'string' && !isState)) {
	    throw new TypeError('Expected pattern to be a non-empty string');
	  }

	  const opts = options || {};
	  const posix = utils.isWindows(options);
	  const regex = isState
	    ? picomatch.compileRe(glob, options)
	    : picomatch.makeRe(glob, options, false, true);

	  const state = regex.state;
	  delete regex.state;

	  let isIgnored = () => false;
	  if (opts.ignore) {
	    const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
	    isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
	  }

	  const matcher = (input, returnObject = false) => {
	    const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
	    const result = { glob, state, regex, posix, input, output, match, isMatch };

	    if (typeof opts.onResult === 'function') {
	      opts.onResult(result);
	    }

	    if (isMatch === false) {
	      result.isMatch = false;
	      return returnObject ? result : false;
	    }

	    if (isIgnored(input)) {
	      if (typeof opts.onIgnore === 'function') {
	        opts.onIgnore(result);
	      }
	      result.isMatch = false;
	      return returnObject ? result : false;
	    }

	    if (typeof opts.onMatch === 'function') {
	      opts.onMatch(result);
	    }
	    return returnObject ? result : true;
	  };

	  if (returnState) {
	    matcher.state = state;
	  }

	  return matcher;
	};

	/**
	 * Test `input` with the given `regex`. This is used by the main
	 * `picomatch()` function to test the input string.
	 *
	 * ```js
	 * const picomatch = require('picomatch');
	 * // picomatch.test(input, regex[, options]);
	 *
	 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
	 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
	 * ```
	 * @param {String} `input` String to test.
	 * @param {RegExp} `regex`
	 * @return {Object} Returns an object with matching info.
	 * @api public
	 */

	picomatch.test = (input, regex, options, { glob, posix } = {}) => {
	  if (typeof input !== 'string') {
	    throw new TypeError('Expected input to be a string');
	  }

	  if (input === '') {
	    return { isMatch: false, output: '' };
	  }

	  const opts = options || {};
	  const format = opts.format || (posix ? utils.toPosixSlashes : null);
	  let match = input === glob;
	  let output = (match && format) ? format(input) : input;

	  if (match === false) {
	    output = format ? format(input) : input;
	    match = output === glob;
	  }

	  if (match === false || opts.capture === true) {
	    if (opts.matchBase === true || opts.basename === true) {
	      match = picomatch.matchBase(input, regex, options, posix);
	    } else {
	      match = regex.exec(output);
	    }
	  }

	  return { isMatch: Boolean(match), match, output };
	};

	/**
	 * Match the basename of a filepath.
	 *
	 * ```js
	 * const picomatch = require('picomatch');
	 * // picomatch.matchBase(input, glob[, options]);
	 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
	 * ```
	 * @param {String} `input` String to test.
	 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
	 * @return {Boolean}
	 * @api public
	 */

	picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
	  const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
	  return regex.test(path.basename(input));
	};

	/**
	 * Returns true if **any** of the given glob `patterns` match the specified `string`.
	 *
	 * ```js
	 * const picomatch = require('picomatch');
	 * // picomatch.isMatch(string, patterns[, options]);
	 *
	 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
	 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
	 * ```
	 * @param {String|Array} str The string to test.
	 * @param {String|Array} patterns One or more glob patterns to use for matching.
	 * @param {Object} [options] See available [options](#options).
	 * @return {Boolean} Returns true if any patterns match `str`
	 * @api public
	 */

	picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);

	/**
	 * Parse a glob pattern to create the source string for a regular
	 * expression.
	 *
	 * ```js
	 * const picomatch = require('picomatch');
	 * const result = picomatch.parse(pattern[, options]);
	 * ```
	 * @param {String} `pattern`
	 * @param {Object} `options`
	 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.
	 * @api public
	 */

	picomatch.parse = (pattern, options) => {
	  if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));
	  return parse(pattern, { ...options, fastpaths: false });
	};

	/**
	 * Scan a glob pattern to separate the pattern into segments.
	 *
	 * ```js
	 * const picomatch = require('picomatch');
	 * // picomatch.scan(input[, options]);
	 *
	 * const result = picomatch.scan('!./foo/*.js');
	 * console.log(result);
	 * { prefix: '!./',
	 *   input: '!./foo/*.js',
	 *   start: 3,
	 *   base: 'foo',
	 *   glob: '*.js',
	 *   isBrace: false,
	 *   isBracket: false,
	 *   isGlob: true,
	 *   isExtglob: false,
	 *   isGlobstar: false,
	 *   negated: true }
	 * ```
	 * @param {String} `input` Glob pattern to scan.
	 * @param {Object} `options`
	 * @return {Object} Returns an object with
	 * @api public
	 */

	picomatch.scan = (input, options) => scan(input, options);

	/**
	 * Compile a regular expression from the `state` object returned by the
	 * [parse()](#parse) method.
	 *
	 * @param {Object} `state`
	 * @param {Object} `options`
	 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
	 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
	 * @return {RegExp}
	 * @api public
	 */

	picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
	  if (returnOutput === true) {
	    return state.output;
	  }

	  const opts = options || {};
	  const prepend = opts.contains ? '' : '^';
	  const append = opts.contains ? '' : '$';

	  let source = `${prepend}(?:${state.output})${append}`;
	  if (state && state.negated === true) {
	    source = `^(?!${source}).*$`;
	  }

	  const regex = picomatch.toRegex(source, options);
	  if (returnState === true) {
	    regex.state = state;
	  }

	  return regex;
	};

	/**
	 * Create a regular expression from a parsed glob pattern.
	 *
	 * ```js
	 * const picomatch = require('picomatch');
	 * const state = picomatch.parse('*.js');
	 * // picomatch.compileRe(state[, options]);
	 *
	 * console.log(picomatch.compileRe(state));
	 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
	 * ```
	 * @param {String} `state` The object returned from the `.parse` method.
	 * @param {Object} `options`
	 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
	 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
	 * @return {RegExp} Returns a regex created from the given pattern.
	 * @api public
	 */

	picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
	  if (!input || typeof input !== 'string') {
	    throw new TypeError('Expected a non-empty string');
	  }

	  let parsed = { negated: false, fastpaths: true };

	  if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
	    parsed.output = parse.fastpaths(input, options);
	  }

	  if (!parsed.output) {
	    parsed = parse(input, options);
	  }

	  return picomatch.compileRe(parsed, options, returnOutput, returnState);
	};

	/**
	 * Create a regular expression from the given regex source string.
	 *
	 * ```js
	 * const picomatch = require('picomatch');
	 * // picomatch.toRegex(source[, options]);
	 *
	 * const { output } = picomatch.parse('*.js');
	 * console.log(picomatch.toRegex(output));
	 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
	 * ```
	 * @param {String} `source` Regular expression source string.
	 * @param {Object} `options`
	 * @return {RegExp}
	 * @api public
	 */

	picomatch.toRegex = (source, options) => {
	  try {
	    const opts = options || {};
	    return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
	  } catch (err) {
	    if (options && options.debug === true) throw err;
	    return /$^/;
	  }
	};

	/**
	 * Picomatch constants.
	 * @return {Object}
	 */

	picomatch.constants = constants;

	/**
	 * Expose "picomatch"
	 */

	picomatch_1 = picomatch;
	return picomatch_1;
}

var picomatch;
var hasRequiredPicomatch;

function requirePicomatch () {
	if (hasRequiredPicomatch) return picomatch;
	hasRequiredPicomatch = 1;

	picomatch = requirePicomatch$1();
	return picomatch;
}

var readdirp_1;
var hasRequiredReaddirp;

function requireReaddirp () {
	if (hasRequiredReaddirp) return readdirp_1;
	hasRequiredReaddirp = 1;

	const fs = require$$0$2;
	const { Readable } = require$$0$4;
	const sysPath = require$$1;
	const { promisify } = require$$0$5;
	const picomatch = requirePicomatch();

	const readdir = promisify(fs.readdir);
	const stat = promisify(fs.stat);
	const lstat = promisify(fs.lstat);
	const realpath = promisify(fs.realpath);

	/**
	 * @typedef {Object} EntryInfo
	 * @property {String} path
	 * @property {String} fullPath
	 * @property {fs.Stats=} stats
	 * @property {fs.Dirent=} dirent
	 * @property {String} basename
	 */

	const BANG = '!';
	const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR';
	const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]);
	const FILE_TYPE = 'files';
	const DIR_TYPE = 'directories';
	const FILE_DIR_TYPE = 'files_directories';
	const EVERYTHING_TYPE = 'all';
	const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE];

	const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code);
	const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10));
	const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5));

	const normalizeFilter = filter => {
	  if (filter === undefined) return;
	  if (typeof filter === 'function') return filter;

	  if (typeof filter === 'string') {
	    const glob = picomatch(filter.trim());
	    return entry => glob(entry.basename);
	  }

	  if (Array.isArray(filter)) {
	    const positive = [];
	    const negative = [];
	    for (const item of filter) {
	      const trimmed = item.trim();
	      if (trimmed.charAt(0) === BANG) {
	        negative.push(picomatch(trimmed.slice(1)));
	      } else {
	        positive.push(picomatch(trimmed));
	      }
	    }

	    if (negative.length > 0) {
	      if (positive.length > 0) {
	        return entry =>
	          positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename));
	      }
	      return entry => !negative.some(f => f(entry.basename));
	    }
	    return entry => positive.some(f => f(entry.basename));
	  }
	};

	class ReaddirpStream extends Readable {
	  static get defaultOptions() {
	    return {
	      root: '.',
	      /* eslint-disable no-unused-vars */
	      fileFilter: (path) => true,
	      directoryFilter: (path) => true,
	      /* eslint-enable no-unused-vars */
	      type: FILE_TYPE,
	      lstat: false,
	      depth: 2147483648,
	      alwaysStat: false
	    };
	  }

	  constructor(options = {}) {
	    super({
	      objectMode: true,
	      autoDestroy: true,
	      highWaterMark: options.highWaterMark || 4096
	    });
	    const opts = { ...ReaddirpStream.defaultOptions, ...options };
	    const { root, type } = opts;

	    this._fileFilter = normalizeFilter(opts.fileFilter);
	    this._directoryFilter = normalizeFilter(opts.directoryFilter);

	    const statMethod = opts.lstat ? lstat : stat;
	    // Use bigint stats if it's windows and stat() supports options (node 10+).
	    if (wantBigintFsStats) {
	      this._stat = path => statMethod(path, { bigint: true });
	    } else {
	      this._stat = statMethod;
	    }

	    this._maxDepth = opts.depth;
	    this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
	    this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
	    this._wantsEverything = type === EVERYTHING_TYPE;
	    this._root = sysPath.resolve(root);
	    this._isDirent = ('Dirent' in fs) && !opts.alwaysStat;
	    this._statsProp = this._isDirent ? 'dirent' : 'stats';
	    this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent };

	    // Launch stream with one parent, the root dir.
	    this.parents = [this._exploreDir(root, 1)];
	    this.reading = false;
	    this.parent = undefined;
	  }

	  async _read(batch) {
	    if (this.reading) return;
	    this.reading = true;

	    try {
	      while (!this.destroyed && batch > 0) {
	        const { path, depth, files = [] } = this.parent || {};

	        if (files.length > 0) {
	          const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path));
	          for (const entry of await Promise.all(slice)) {
	            if (this.destroyed) return;

	            const entryType = await this._getEntryType(entry);
	            if (entryType === 'directory' && this._directoryFilter(entry)) {
	              if (depth <= this._maxDepth) {
	                this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
	              }

	              if (this._wantsDir) {
	                this.push(entry);
	                batch--;
	              }
	            } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) {
	              if (this._wantsFile) {
	                this.push(entry);
	                batch--;
	              }
	            }
	          }
	        } else {
	          const parent = this.parents.pop();
	          if (!parent) {
	            this.push(null);
	            break;
	          }
	          this.parent = await parent;
	          if (this.destroyed) return;
	        }
	      }
	    } catch (error) {
	      this.destroy(error);
	    } finally {
	      this.reading = false;
	    }
	  }

	  async _exploreDir(path, depth) {
	    let files;
	    try {
	      files = await readdir(path, this._rdOptions);
	    } catch (error) {
	      this._onError(error);
	    }
	    return { files, depth, path };
	  }

	  async _formatEntry(dirent, path) {
	    let entry;
	    try {
	      const basename = this._isDirent ? dirent.name : dirent;
	      const fullPath = sysPath.resolve(sysPath.join(path, basename));
	      entry = { path: sysPath.relative(this._root, fullPath), fullPath, basename };
	      entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
	    } catch (err) {
	      this._onError(err);
	    }
	    return entry;
	  }

	  _onError(err) {
	    if (isNormalFlowError(err) && !this.destroyed) {
	      this.emit('warn', err);
	    } else {
	      this.destroy(err);
	    }
	  }

	  async _getEntryType(entry) {
	    // entry may be undefined, because a warning or an error were emitted
	    // and the statsProp is undefined
	    const stats = entry && entry[this._statsProp];
	    if (!stats) {
	      return;
	    }
	    if (stats.isFile()) {
	      return 'file';
	    }
	    if (stats.isDirectory()) {
	      return 'directory';
	    }
	    if (stats && stats.isSymbolicLink()) {
	      const full = entry.fullPath;
	      try {
	        const entryRealPath = await realpath(full);
	        const entryRealPathStats = await lstat(entryRealPath);
	        if (entryRealPathStats.isFile()) {
	          return 'file';
	        }
	        if (entryRealPathStats.isDirectory()) {
	          const len = entryRealPath.length;
	          if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath.sep) {
	            const recursiveError = new Error(
	              `Circular symlink detected: "${full}" points to "${entryRealPath}"`
	            );
	            recursiveError.code = RECURSIVE_ERROR_CODE;
	            return this._onError(recursiveError);
	          }
	          return 'directory';
	        }
	      } catch (error) {
	        this._onError(error);
	      }
	    }
	  }

	  _includeAsFile(entry) {
	    const stats = entry && entry[this._statsProp];

	    return stats && this._wantsEverything && !stats.isDirectory();
	  }
	}

	/**
	 * @typedef {Object} ReaddirpArguments
	 * @property {Function=} fileFilter
	 * @property {Function=} directoryFilter
	 * @property {String=} type
	 * @property {Number=} depth
	 * @property {String=} root
	 * @property {Boolean=} lstat
	 * @property {Boolean=} bigint
	 */

	/**
	 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
	 * @param {String} root Root directory
	 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth
	 */
	const readdirp = (root, options = {}) => {
	  let type = options.entryType || options.type;
	  if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility
	  if (type) options.type = type;
	  if (!root) {
	    throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
	  } else if (typeof root !== 'string') {
	    throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)');
	  } else if (type && !ALL_TYPES.includes(type)) {
	    throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`);
	  }

	  options.root = root;
	  return new ReaddirpStream(options);
	};

	const readdirpPromise = (root, options = {}) => {
	  return new Promise((resolve, reject) => {
	    const files = [];
	    readdirp(root, options)
	      .on('data', entry => files.push(entry))
	      .on('end', () => resolve(files))
	      .on('error', error => reject(error));
	  });
	};

	readdirp.promise = readdirpPromise;
	readdirp.ReaddirpStream = ReaddirpStream;
	readdirp.default = readdirp;

	readdirp_1 = readdirp;
	return readdirp_1;
}

var anymatch = {exports: {}};

var anymatch_1 = anymatch.exports;

var hasRequiredAnymatch;

function requireAnymatch () {
	if (hasRequiredAnymatch) return anymatch.exports;
	hasRequiredAnymatch = 1;

	Object.defineProperty(anymatch_1, "__esModule", { value: true });

	const picomatch = requirePicomatch();
	const normalizePath = requireNormalizePath();

	/**
	 * @typedef {(testString: string) => boolean} AnymatchFn
	 * @typedef {string|RegExp|AnymatchFn} AnymatchPattern
	 * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
	 */
	const BANG = '!';
	const DEFAULT_OPTIONS = {returnIndex: false};
	const arrify = (item) => Array.isArray(item) ? item : [item];

	/**
	 * @param {AnymatchPattern} matcher
	 * @param {object} options
	 * @returns {AnymatchFn}
	 */
	const createPattern = (matcher, options) => {
	  if (typeof matcher === 'function') {
	    return matcher;
	  }
	  if (typeof matcher === 'string') {
	    const glob = picomatch(matcher, options);
	    return (string) => matcher === string || glob(string);
	  }
	  if (matcher instanceof RegExp) {
	    return (string) => matcher.test(string);
	  }
	  return (string) => false;
	};

	/**
	 * @param {Array<Function>} patterns
	 * @param {Array<Function>} negPatterns
	 * @param {String|Array} args
	 * @param {Boolean} returnIndex
	 * @returns {boolean|number}
	 */
	const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
	  const isList = Array.isArray(args);
	  const _path = isList ? args[0] : args;
	  if (!isList && typeof _path !== 'string') {
	    throw new TypeError('anymatch: second argument must be a string: got ' +
	      Object.prototype.toString.call(_path))
	  }
	  const path = normalizePath(_path, false);

	  for (let index = 0; index < negPatterns.length; index++) {
	    const nglob = negPatterns[index];
	    if (nglob(path)) {
	      return returnIndex ? -1 : false;
	    }
	  }

	  const applied = isList && [path].concat(args.slice(1));
	  for (let index = 0; index < patterns.length; index++) {
	    const pattern = patterns[index];
	    if (isList ? pattern(...applied) : pattern(path)) {
	      return returnIndex ? index : true;
	    }
	  }

	  return returnIndex ? -1 : false;
	};

	/**
	 * @param {AnymatchMatcher} matchers
	 * @param {Array|string} testString
	 * @param {object} options
	 * @returns {boolean|number|Function}
	 */
	const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => {
	  if (matchers == null) {
	    throw new TypeError('anymatch: specify first argument');
	  }
	  const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
	  const returnIndex = opts.returnIndex || false;

	  // Early cache for matchers.
	  const mtchers = arrify(matchers);
	  const negatedGlobs = mtchers
	    .filter(item => typeof item === 'string' && item.charAt(0) === BANG)
	    .map(item => item.slice(1))
	    .map(item => picomatch(item, opts));
	  const patterns = mtchers
	    .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG))
	    .map(matcher => createPattern(matcher, opts));

	  if (testString == null) {
	    return (testString, ri = false) => {
	      const returnIndex = typeof ri === 'boolean' ? ri : false;
	      return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
	    }
	  }

	  return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
	};

	anymatch$1.default = anymatch$1;
	anymatch.exports = anymatch$1;
	return anymatch.exports;
}

/*!
 * is-extglob <https://github.com/jonschlinkert/is-extglob>
 *
 * Copyright (c) 2014-2016, Jon Schlinkert.
 * Licensed under the MIT License.
 */

var isExtglob;
var hasRequiredIsExtglob;

function requireIsExtglob () {
	if (hasRequiredIsExtglob) return isExtglob;
	hasRequiredIsExtglob = 1;
	isExtglob = function isExtglob(str) {
	  if (typeof str !== 'string' || str === '') {
	    return false;
	  }

	  var match;
	  while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) {
	    if (match[2]) return true;
	    str = str.slice(match.index + match[0].length);
	  }

	  return false;
	};
	return isExtglob;
}

/*!
 * is-glob <https://github.com/jonschlinkert/is-glob>
 *
 * Copyright (c) 2014-2017, Jon Schlinkert.
 * Released under the MIT License.
 */

var isGlob;
var hasRequiredIsGlob;

function requireIsGlob () {
	if (hasRequiredIsGlob) return isGlob;
	hasRequiredIsGlob = 1;
	var isExtglob = requireIsExtglob();
	var chars = { '{': '}', '(': ')', '[': ']'};
	var strictCheck = function(str) {
	  if (str[0] === '!') {
	    return true;
	  }
	  var index = 0;
	  var pipeIndex = -2;
	  var closeSquareIndex = -2;
	  var closeCurlyIndex = -2;
	  var closeParenIndex = -2;
	  var backSlashIndex = -2;
	  while (index < str.length) {
	    if (str[index] === '*') {
	      return true;
	    }

	    if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) {
	      return true;
	    }

	    if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') {
	      if (closeSquareIndex < index) {
	        closeSquareIndex = str.indexOf(']', index);
	      }
	      if (closeSquareIndex > index) {
	        if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
	          return true;
	        }
	        backSlashIndex = str.indexOf('\\', index);
	        if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
	          return true;
	        }
	      }
	    }

	    if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') {
	      closeCurlyIndex = str.indexOf('}', index);
	      if (closeCurlyIndex > index) {
	        backSlashIndex = str.indexOf('\\', index);
	        if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) {
	          return true;
	        }
	      }
	    }

	    if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') {
	      closeParenIndex = str.indexOf(')', index);
	      if (closeParenIndex > index) {
	        backSlashIndex = str.indexOf('\\', index);
	        if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
	          return true;
	        }
	      }
	    }

	    if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') {
	      if (pipeIndex < index) {
	        pipeIndex = str.indexOf('|', index);
	      }
	      if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') {
	        closeParenIndex = str.indexOf(')', pipeIndex);
	        if (closeParenIndex > pipeIndex) {
	          backSlashIndex = str.indexOf('\\', pipeIndex);
	          if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
	            return true;
	          }
	        }
	      }
	    }

	    if (str[index] === '\\') {
	      var open = str[index + 1];
	      index += 2;
	      var close = chars[open];

	      if (close) {
	        var n = str.indexOf(close, index);
	        if (n !== -1) {
	          index = n + 1;
	        }
	      }

	      if (str[index] === '!') {
	        return true;
	      }
	    } else {
	      index++;
	    }
	  }
	  return false;
	};

	var relaxedCheck = function(str) {
	  if (str[0] === '!') {
	    return true;
	  }
	  var index = 0;
	  while (index < str.length) {
	    if (/[*?{}()[\]]/.test(str[index])) {
	      return true;
	    }

	    if (str[index] === '\\') {
	      var open = str[index + 1];
	      index += 2;
	      var close = chars[open];

	      if (close) {
	        var n = str.indexOf(close, index);
	        if (n !== -1) {
	          index = n + 1;
	        }
	      }

	      if (str[index] === '!') {
	        return true;
	      }
	    } else {
	      index++;
	    }
	  }
	  return false;
	};

	isGlob = function isGlob(str, options) {
	  if (typeof str !== 'string' || str === '') {
	    return false;
	  }

	  if (isExtglob(str)) {
	    return true;
	  }

	  var check = strictCheck;

	  // optionally relax check
	  if (options && options.strict === false) {
	    check = relaxedCheck;
	  }

	  return check(str);
	};
	return isGlob;
}

var globParent;
var hasRequiredGlobParent;

function requireGlobParent () {
	if (hasRequiredGlobParent) return globParent;
	hasRequiredGlobParent = 1;

	var isGlob = requireIsGlob();
	var pathPosixDirname = require$$1.posix.dirname;
	var isWin32 = require$$3.platform() === 'win32';

	var slash = '/';
	var backslash = /\\/g;
	var enclosure = /[\{\[].*[\}\]]$/;
	var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/;
	var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g;

	/**
	 * @param {string} str
	 * @param {Object} opts
	 * @param {boolean} [opts.flipBackslashes=true]
	 * @returns {string}
	 */
	globParent = function globParent(str, opts) {
	  var options = Object.assign({ flipBackslashes: true }, opts);

	  // flip windows path separators
	  if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) {
	    str = str.replace(backslash, slash);
	  }

	  // special case for strings ending in enclosure containing path separator
	  if (enclosure.test(str)) {
	    str += slash;
	  }

	  // preserves full path in case of trailing path separator
	  str += 'a';

	  // remove path parts that are globby
	  do {
	    str = pathPosixDirname(str);
	  } while (isGlob(str) || globby.test(str));

	  // remove escape chars and return result
	  return str.replace(escaped, '$1');
	};
	return globParent;
}

var utils = {};

var hasRequiredUtils;

function requireUtils () {
	if (hasRequiredUtils) return utils;
	hasRequiredUtils = 1;
	(function (exports) {

		exports.isInteger = num => {
		  if (typeof num === 'number') {
		    return Number.isInteger(num);
		  }
		  if (typeof num === 'string' && num.trim() !== '') {
		    return Number.isInteger(Number(num));
		  }
		  return false;
		};

		/**
		 * Find a node of the given type
		 */

		exports.find = (node, type) => node.nodes.find(node => node.type === type);

		/**
		 * Find a node of the given type
		 */

		exports.exceedsLimit = (min, max, step = 1, limit) => {
		  if (limit === false) return false;
		  if (!exports.isInteger(min) || !exports.isInteger(max)) return false;
		  return ((Number(max) - Number(min)) / Number(step)) >= limit;
		};

		/**
		 * Escape the given node with '\\' before node.value
		 */

		exports.escapeNode = (block, n = 0, type) => {
		  const node = block.nodes[n];
		  if (!node) return;

		  if ((type && node.type === type) || node.type === 'open' || node.type === 'close') {
		    if (node.escaped !== true) {
		      node.value = '\\' + node.value;
		      node.escaped = true;
		    }
		  }
		};

		/**
		 * Returns true if the given brace node should be enclosed in literal braces
		 */

		exports.encloseBrace = node => {
		  if (node.type !== 'brace') return false;
		  if ((node.commas >> 0 + node.ranges >> 0) === 0) {
		    node.invalid = true;
		    return true;
		  }
		  return false;
		};

		/**
		 * Returns true if a brace node is invalid.
		 */

		exports.isInvalidBrace = block => {
		  if (block.type !== 'brace') return false;
		  if (block.invalid === true || block.dollar) return true;
		  if ((block.commas >> 0 + block.ranges >> 0) === 0) {
		    block.invalid = true;
		    return true;
		  }
		  if (block.open !== true || block.close !== true) {
		    block.invalid = true;
		    return true;
		  }
		  return false;
		};

		/**
		 * Returns true if a node is an open or close node
		 */

		exports.isOpenOrClose = node => {
		  if (node.type === 'open' || node.type === 'close') {
		    return true;
		  }
		  return node.open === true || node.close === true;
		};

		/**
		 * Reduce an array of text nodes.
		 */

		exports.reduce = nodes => nodes.reduce((acc, node) => {
		  if (node.type === 'text') acc.push(node.value);
		  if (node.type === 'range') node.type = 'text';
		  return acc;
		}, []);

		/**
		 * Flatten an array
		 */

		exports.flatten = (...args) => {
		  const result = [];

		  const flat = arr => {
		    for (let i = 0; i < arr.length; i++) {
		      const ele = arr[i];

		      if (Array.isArray(ele)) {
		        flat(ele);
		        continue;
		      }

		      if (ele !== undefined) {
		        result.push(ele);
		      }
		    }
		    return result;
		  };

		  flat(args);
		  return result;
		}; 
	} (utils));
	return utils;
}

var stringify;
var hasRequiredStringify;

function requireStringify () {
	if (hasRequiredStringify) return stringify;
	hasRequiredStringify = 1;

	const utils = requireUtils();

	stringify = (ast, options = {}) => {
	  const stringify = (node, parent = {}) => {
	    const invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
	    const invalidNode = node.invalid === true && options.escapeInvalid === true;
	    let output = '';

	    if (node.value) {
	      if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
	        return '\\' + node.value;
	      }
	      return node.value;
	    }

	    if (node.value) {
	      return node.value;
	    }

	    if (node.nodes) {
	      for (const child of node.nodes) {
	        output += stringify(child);
	      }
	    }
	    return output;
	  };

	  return stringify(ast);
	};
	return stringify;
}

/*!
 * is-number <https://github.com/jonschlinkert/is-number>
 *
 * Copyright (c) 2014-present, Jon Schlinkert.
 * Released under the MIT License.
 */

var isNumber;
var hasRequiredIsNumber;

function requireIsNumber () {
	if (hasRequiredIsNumber) return isNumber;
	hasRequiredIsNumber = 1;

	isNumber = function(num) {
	  if (typeof num === 'number') {
	    return num - num === 0;
	  }
	  if (typeof num === 'string' && num.trim() !== '') {
	    return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
	  }
	  return false;
	};
	return isNumber;
}

/*!
 * to-regex-range <https://github.com/micromatch/to-regex-range>
 *
 * Copyright (c) 2015-present, Jon Schlinkert.
 * Released under the MIT License.
 */

var toRegexRange_1;
var hasRequiredToRegexRange;

function requireToRegexRange () {
	if (hasRequiredToRegexRange) return toRegexRange_1;
	hasRequiredToRegexRange = 1;

	const isNumber = requireIsNumber();

	const toRegexRange = (min, max, options) => {
	  if (isNumber(min) === false) {
	    throw new TypeError('toRegexRange: expected the first argument to be a number');
	  }

	  if (max === void 0 || min === max) {
	    return String(min);
	  }

	  if (isNumber(max) === false) {
	    throw new TypeError('toRegexRange: expected the second argument to be a number.');
	  }

	  let opts = { relaxZeros: true, ...options };
	  if (typeof opts.strictZeros === 'boolean') {
	    opts.relaxZeros = opts.strictZeros === false;
	  }

	  let relax = String(opts.relaxZeros);
	  let shorthand = String(opts.shorthand);
	  let capture = String(opts.capture);
	  let wrap = String(opts.wrap);
	  let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap;

	  if (toRegexRange.cache.hasOwnProperty(cacheKey)) {
	    return toRegexRange.cache[cacheKey].result;
	  }

	  let a = Math.min(min, max);
	  let b = Math.max(min, max);

	  if (Math.abs(a - b) === 1) {
	    let result = min + '|' + max;
	    if (opts.capture) {
	      return `(${result})`;
	    }
	    if (opts.wrap === false) {
	      return result;
	    }
	    return `(?:${result})`;
	  }

	  let isPadded = hasPadding(min) || hasPadding(max);
	  let state = { min, max, a, b };
	  let positives = [];
	  let negatives = [];

	  if (isPadded) {
	    state.isPadded = isPadded;
	    state.maxLen = String(state.max).length;
	  }

	  if (a < 0) {
	    let newMin = b < 0 ? Math.abs(b) : 1;
	    negatives = splitToPatterns(newMin, Math.abs(a), state, opts);
	    a = state.a = 0;
	  }

	  if (b >= 0) {
	    positives = splitToPatterns(a, b, state, opts);
	  }

	  state.negatives = negatives;
	  state.positives = positives;
	  state.result = collatePatterns(negatives, positives);

	  if (opts.capture === true) {
	    state.result = `(${state.result})`;
	  } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) {
	    state.result = `(?:${state.result})`;
	  }

	  toRegexRange.cache[cacheKey] = state;
	  return state.result;
	};

	function collatePatterns(neg, pos, options) {
	  let onlyNegative = filterPatterns(neg, pos, '-', false) || [];
	  let onlyPositive = filterPatterns(pos, neg, '', false) || [];
	  let intersected = filterPatterns(neg, pos, '-?', true) || [];
	  let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive);
	  return subpatterns.join('|');
	}

	function splitToRanges(min, max) {
	  let nines = 1;
	  let zeros = 1;

	  let stop = countNines(min, nines);
	  let stops = new Set([max]);

	  while (min <= stop && stop <= max) {
	    stops.add(stop);
	    nines += 1;
	    stop = countNines(min, nines);
	  }

	  stop = countZeros(max + 1, zeros) - 1;

	  while (min < stop && stop <= max) {
	    stops.add(stop);
	    zeros += 1;
	    stop = countZeros(max + 1, zeros) - 1;
	  }

	  stops = [...stops];
	  stops.sort(compare);
	  return stops;
	}

	/**
	 * Convert a range to a regex pattern
	 * @param {Number} `start`
	 * @param {Number} `stop`
	 * @return {String}
	 */

	function rangeToPattern(start, stop, options) {
	  if (start === stop) {
	    return { pattern: start, count: [], digits: 0 };
	  }

	  let zipped = zip(start, stop);
	  let digits = zipped.length;
	  let pattern = '';
	  let count = 0;

	  for (let i = 0; i < digits; i++) {
	    let [startDigit, stopDigit] = zipped[i];

	    if (startDigit === stopDigit) {
	      pattern += startDigit;

	    } else if (startDigit !== '0' || stopDigit !== '9') {
	      pattern += toCharacterClass(startDigit, stopDigit);

	    } else {
	      count++;
	    }
	  }

	  if (count) {
	    pattern += options.shorthand === true ? '\\d' : '[0-9]';
	  }

	  return { pattern, count: [count], digits };
	}

	function splitToPatterns(min, max, tok, options) {
	  let ranges = splitToRanges(min, max);
	  let tokens = [];
	  let start = min;
	  let prev;

	  for (let i = 0; i < ranges.length; i++) {
	    let max = ranges[i];
	    let obj = rangeToPattern(String(start), String(max), options);
	    let zeros = '';

	    if (!tok.isPadded && prev && prev.pattern === obj.pattern) {
	      if (prev.count.length > 1) {
	        prev.count.pop();
	      }

	      prev.count.push(obj.count[0]);
	      prev.string = prev.pattern + toQuantifier(prev.count);
	      start = max + 1;
	      continue;
	    }

	    if (tok.isPadded) {
	      zeros = padZeros(max, tok, options);
	    }

	    obj.string = zeros + obj.pattern + toQuantifier(obj.count);
	    tokens.push(obj);
	    start = max + 1;
	    prev = obj;
	  }

	  return tokens;
	}

	function filterPatterns(arr, comparison, prefix, intersection, options) {
	  let result = [];

	  for (let ele of arr) {
	    let { string } = ele;

	    // only push if _both_ are negative...
	    if (!intersection && !contains(comparison, 'string', string)) {
	      result.push(prefix + string);
	    }

	    // or _both_ are positive
	    if (intersection && contains(comparison, 'string', string)) {
	      result.push(prefix + string);
	    }
	  }
	  return result;
	}

	/**
	 * Zip strings
	 */

	function zip(a, b) {
	  let arr = [];
	  for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]);
	  return arr;
	}

	function compare(a, b) {
	  return a > b ? 1 : b > a ? -1 : 0;
	}

	function contains(arr, key, val) {
	  return arr.some(ele => ele[key] === val);
	}

	function countNines(min, len) {
	  return Number(String(min).slice(0, -len) + '9'.repeat(len));
	}

	function countZeros(integer, zeros) {
	  return integer - (integer % Math.pow(10, zeros));
	}

	function toQuantifier(digits) {
	  let [start = 0, stop = ''] = digits;
	  if (stop || start > 1) {
	    return `{${start + (stop ? ',' + stop : '')}}`;
	  }
	  return '';
	}

	function toCharacterClass(a, b, options) {
	  return `[${a}${(b - a === 1) ? '' : '-'}${b}]`;
	}

	function hasPadding(str) {
	  return /^-?(0+)\d/.test(str);
	}

	function padZeros(value, tok, options) {
	  if (!tok.isPadded) {
	    return value;
	  }

	  let diff = Math.abs(tok.maxLen - String(value).length);
	  let relax = options.relaxZeros !== false;

	  switch (diff) {
	    case 0:
	      return '';
	    case 1:
	      return relax ? '0?' : '0';
	    case 2:
	      return relax ? '0{0,2}' : '00';
	    default: {
	      return relax ? `0{0,${diff}}` : `0{${diff}}`;
	    }
	  }
	}

	/**
	 * Cache
	 */

	toRegexRange.cache = {};
	toRegexRange.clearCache = () => (toRegexRange.cache = {});

	/**
	 * Expose `toRegexRange`
	 */

	toRegexRange_1 = toRegexRange;
	return toRegexRange_1;
}

/*!
 * fill-range <https://github.com/jonschlinkert/fill-range>
 *
 * Copyright (c) 2014-present, Jon Schlinkert.
 * Licensed under the MIT License.
 */

var fillRange;
var hasRequiredFillRange;

function requireFillRange () {
	if (hasRequiredFillRange) return fillRange;
	hasRequiredFillRange = 1;

	const util = require$$0$5;
	const toRegexRange = requireToRegexRange();

	const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);

	const transform = toNumber => {
	  return value => toNumber === true ? Number(value) : String(value);
	};

	const isValidValue = value => {
	  return typeof value === 'number' || (typeof value === 'string' && value !== '');
	};

	const isNumber = num => Number.isInteger(+num);

	const zeros = input => {
	  let value = `${input}`;
	  let index = -1;
	  if (value[0] === '-') value = value.slice(1);
	  if (value === '0') return false;
	  while (value[++index] === '0');
	  return index > 0;
	};

	const stringify = (start, end, options) => {
	  if (typeof start === 'string' || typeof end === 'string') {
	    return true;
	  }
	  return options.stringify === true;
	};

	const pad = (input, maxLength, toNumber) => {
	  if (maxLength > 0) {
	    let dash = input[0] === '-' ? '-' : '';
	    if (dash) input = input.slice(1);
	    input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'));
	  }
	  if (toNumber === false) {
	    return String(input);
	  }
	  return input;
	};

	const toMaxLen = (input, maxLength) => {
	  let negative = input[0] === '-' ? '-' : '';
	  if (negative) {
	    input = input.slice(1);
	    maxLength--;
	  }
	  while (input.length < maxLength) input = '0' + input;
	  return negative ? ('-' + input) : input;
	};

	const toSequence = (parts, options, maxLen) => {
	  parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
	  parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);

	  let prefix = options.capture ? '' : '?:';
	  let positives = '';
	  let negatives = '';
	  let result;

	  if (parts.positives.length) {
	    positives = parts.positives.map(v => toMaxLen(String(v), maxLen)).join('|');
	  }

	  if (parts.negatives.length) {
	    negatives = `-(${prefix}${parts.negatives.map(v => toMaxLen(String(v), maxLen)).join('|')})`;
	  }

	  if (positives && negatives) {
	    result = `${positives}|${negatives}`;
	  } else {
	    result = positives || negatives;
	  }

	  if (options.wrap) {
	    return `(${prefix}${result})`;
	  }

	  return result;
	};

	const toRange = (a, b, isNumbers, options) => {
	  if (isNumbers) {
	    return toRegexRange(a, b, { wrap: false, ...options });
	  }

	  let start = String.fromCharCode(a);
	  if (a === b) return start;

	  let stop = String.fromCharCode(b);
	  return `[${start}-${stop}]`;
	};

	const toRegex = (start, end, options) => {
	  if (Array.isArray(start)) {
	    let wrap = options.wrap === true;
	    let prefix = options.capture ? '' : '?:';
	    return wrap ? `(${prefix}${start.join('|')})` : start.join('|');
	  }
	  return toRegexRange(start, end, options);
	};

	const rangeError = (...args) => {
	  return new RangeError('Invalid range arguments: ' + util.inspect(...args));
	};

	const invalidRange = (start, end, options) => {
	  if (options.strictRanges === true) throw rangeError([start, end]);
	  return [];
	};

	const invalidStep = (step, options) => {
	  if (options.strictRanges === true) {
	    throw new TypeError(`Expected step "${step}" to be a number`);
	  }
	  return [];
	};

	const fillNumbers = (start, end, step = 1, options = {}) => {
	  let a = Number(start);
	  let b = Number(end);

	  if (!Number.isInteger(a) || !Number.isInteger(b)) {
	    if (options.strictRanges === true) throw rangeError([start, end]);
	    return [];
	  }

	  // fix negative zero
	  if (a === 0) a = 0;
	  if (b === 0) b = 0;

	  let descending = a > b;
	  let startString = String(start);
	  let endString = String(end);
	  let stepString = String(step);
	  step = Math.max(Math.abs(step), 1);

	  let padded = zeros(startString) || zeros(endString) || zeros(stepString);
	  let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
	  let toNumber = padded === false && stringify(start, end, options) === false;
	  let format = options.transform || transform(toNumber);

	  if (options.toRegex && step === 1) {
	    return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
	  }

	  let parts = { negatives: [], positives: [] };
	  let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));
	  let range = [];
	  let index = 0;

	  while (descending ? a >= b : a <= b) {
	    if (options.toRegex === true && step > 1) {
	      push(a);
	    } else {
	      range.push(pad(format(a, index), maxLen, toNumber));
	    }
	    a = descending ? a - step : a + step;
	    index++;
	  }

	  if (options.toRegex === true) {
	    return step > 1
	      ? toSequence(parts, options, maxLen)
	      : toRegex(range, null, { wrap: false, ...options });
	  }

	  return range;
	};

	const fillLetters = (start, end, step = 1, options = {}) => {
	  if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) {
	    return invalidRange(start, end, options);
	  }

	  let format = options.transform || (val => String.fromCharCode(val));
	  let a = `${start}`.charCodeAt(0);
	  let b = `${end}`.charCodeAt(0);

	  let descending = a > b;
	  let min = Math.min(a, b);
	  let max = Math.max(a, b);

	  if (options.toRegex && step === 1) {
	    return toRange(min, max, false, options);
	  }

	  let range = [];
	  let index = 0;

	  while (descending ? a >= b : a <= b) {
	    range.push(format(a, index));
	    a = descending ? a - step : a + step;
	    index++;
	  }

	  if (options.toRegex === true) {
	    return toRegex(range, null, { wrap: false, options });
	  }

	  return range;
	};

	const fill = (start, end, step, options = {}) => {
	  if (end == null && isValidValue(start)) {
	    return [start];
	  }

	  if (!isValidValue(start) || !isValidValue(end)) {
	    return invalidRange(start, end, options);
	  }

	  if (typeof step === 'function') {
	    return fill(start, end, 1, { transform: step });
	  }

	  if (isObject(step)) {
	    return fill(start, end, 0, step);
	  }

	  let opts = { ...options };
	  if (opts.capture === true) opts.wrap = true;
	  step = step || opts.step || 1;

	  if (!isNumber(step)) {
	    if (step != null && !isObject(step)) return invalidStep(step, opts);
	    return fill(start, end, 1, step);
	  }

	  if (isNumber(start) && isNumber(end)) {
	    return fillNumbers(start, end, step, opts);
	  }

	  return fillLetters(start, end, Math.max(Math.abs(step), 1), opts);
	};

	fillRange = fill;
	return fillRange;
}

var compile_1;
var hasRequiredCompile;

function requireCompile () {
	if (hasRequiredCompile) return compile_1;
	hasRequiredCompile = 1;

	const fill = requireFillRange();
	const utils = requireUtils();

	const compile = (ast, options = {}) => {
	  const walk = (node, parent = {}) => {
	    const invalidBlock = utils.isInvalidBrace(parent);
	    const invalidNode = node.invalid === true && options.escapeInvalid === true;
	    const invalid = invalidBlock === true || invalidNode === true;
	    const prefix = options.escapeInvalid === true ? '\\' : '';
	    let output = '';

	    if (node.isOpen === true) {
	      return prefix + node.value;
	    }

	    if (node.isClose === true) {
	      console.log('node.isClose', prefix, node.value);
	      return prefix + node.value;
	    }

	    if (node.type === 'open') {
	      return invalid ? prefix + node.value : '(';
	    }

	    if (node.type === 'close') {
	      return invalid ? prefix + node.value : ')';
	    }

	    if (node.type === 'comma') {
	      return node.prev.type === 'comma' ? '' : invalid ? node.value : '|';
	    }

	    if (node.value) {
	      return node.value;
	    }

	    if (node.nodes && node.ranges > 0) {
	      const args = utils.reduce(node.nodes);
	      const range = fill(...args, { ...options, wrap: false, toRegex: true, strictZeros: true });

	      if (range.length !== 0) {
	        return args.length > 1 && range.length > 1 ? `(${range})` : range;
	      }
	    }

	    if (node.nodes) {
	      for (const child of node.nodes) {
	        output += walk(child, node);
	      }
	    }

	    return output;
	  };

	  return walk(ast);
	};

	compile_1 = compile;
	return compile_1;
}

var expand_1;
var hasRequiredExpand;

function requireExpand () {
	if (hasRequiredExpand) return expand_1;
	hasRequiredExpand = 1;

	const fill = requireFillRange();
	const stringify = requireStringify();
	const utils = requireUtils();

	const append = (queue = '', stash = '', enclose = false) => {
	  const result = [];

	  queue = [].concat(queue);
	  stash = [].concat(stash);

	  if (!stash.length) return queue;
	  if (!queue.length) {
	    return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
	  }

	  for (const item of queue) {
	    if (Array.isArray(item)) {
	      for (const value of item) {
	        result.push(append(value, stash, enclose));
	      }
	    } else {
	      for (let ele of stash) {
	        if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
	        result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele);
	      }
	    }
	  }
	  return utils.flatten(result);
	};

	const expand = (ast, options = {}) => {
	  const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit;

	  const walk = (node, parent = {}) => {
	    node.queue = [];

	    let p = parent;
	    let q = parent.queue;

	    while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
	      p = p.parent;
	      q = p.queue;
	    }

	    if (node.invalid || node.dollar) {
	      q.push(append(q.pop(), stringify(node, options)));
	      return;
	    }

	    if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
	      q.push(append(q.pop(), ['{}']));
	      return;
	    }

	    if (node.nodes && node.ranges > 0) {
	      const args = utils.reduce(node.nodes);

	      if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
	        throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
	      }

	      let range = fill(...args, options);
	      if (range.length === 0) {
	        range = stringify(node, options);
	      }

	      q.push(append(q.pop(), range));
	      node.nodes = [];
	      return;
	    }

	    const enclose = utils.encloseBrace(node);
	    let queue = node.queue;
	    let block = node;

	    while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
	      block = block.parent;
	      queue = block.queue;
	    }

	    for (let i = 0; i < node.nodes.length; i++) {
	      const child = node.nodes[i];

	      if (child.type === 'comma' && node.type === 'brace') {
	        if (i === 1) queue.push('');
	        queue.push('');
	        continue;
	      }

	      if (child.type === 'close') {
	        q.push(append(q.pop(), queue, enclose));
	        continue;
	      }

	      if (child.value && child.type !== 'open') {
	        queue.push(append(queue.pop(), child.value));
	        continue;
	      }

	      if (child.nodes) {
	        walk(child, node);
	      }
	    }

	    return queue;
	  };

	  return utils.flatten(walk(ast));
	};

	expand_1 = expand;
	return expand_1;
}

var constants$1;
var hasRequiredConstants$1;

function requireConstants$1 () {
	if (hasRequiredConstants$1) return constants$1;
	hasRequiredConstants$1 = 1;

	constants$1 = {
	  MAX_LENGTH: 10000,

	  // Digits
	  CHAR_0: '0', /* 0 */
	  CHAR_9: '9', /* 9 */

	  // Alphabet chars.
	  CHAR_UPPERCASE_A: 'A', /* A */
	  CHAR_LOWERCASE_A: 'a', /* a */
	  CHAR_UPPERCASE_Z: 'Z', /* Z */
	  CHAR_LOWERCASE_Z: 'z', /* z */

	  CHAR_LEFT_PARENTHESES: '(', /* ( */
	  CHAR_RIGHT_PARENTHESES: ')', /* ) */

	  CHAR_ASTERISK: '*', /* * */

	  // Non-alphabetic chars.
	  CHAR_AMPERSAND: '&', /* & */
	  CHAR_AT: '@', /* @ */
	  CHAR_BACKSLASH: '\\', /* \ */
	  CHAR_BACKTICK: '`', /* ` */
	  CHAR_CARRIAGE_RETURN: '\r', /* \r */
	  CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */
	  CHAR_COLON: ':', /* : */
	  CHAR_COMMA: ',', /* , */
	  CHAR_DOLLAR: '$', /* . */
	  CHAR_DOT: '.', /* . */
	  CHAR_DOUBLE_QUOTE: '"', /* " */
	  CHAR_EQUAL: '=', /* = */
	  CHAR_EXCLAMATION_MARK: '!', /* ! */
	  CHAR_FORM_FEED: '\f', /* \f */
	  CHAR_FORWARD_SLASH: '/', /* / */
	  CHAR_HASH: '#', /* # */
	  CHAR_HYPHEN_MINUS: '-', /* - */
	  CHAR_LEFT_ANGLE_BRACKET: '<', /* < */
	  CHAR_LEFT_CURLY_BRACE: '{', /* { */
	  CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */
	  CHAR_LINE_FEED: '\n', /* \n */
	  CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */
	  CHAR_PERCENT: '%', /* % */
	  CHAR_PLUS: '+', /* + */
	  CHAR_QUESTION_MARK: '?', /* ? */
	  CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */
	  CHAR_RIGHT_CURLY_BRACE: '}', /* } */
	  CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */
	  CHAR_SEMICOLON: ';', /* ; */
	  CHAR_SINGLE_QUOTE: '\'', /* ' */
	  CHAR_SPACE: ' ', /*   */
	  CHAR_TAB: '\t', /* \t */
	  CHAR_UNDERSCORE: '_', /* _ */
	  CHAR_VERTICAL_LINE: '|', /* | */
	  CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */
	};
	return constants$1;
}

var parse_1;
var hasRequiredParse;

function requireParse () {
	if (hasRequiredParse) return parse_1;
	hasRequiredParse = 1;

	const stringify = requireStringify();

	/**
	 * Constants
	 */

	const {
	  MAX_LENGTH,
	  CHAR_BACKSLASH, /* \ */
	  CHAR_BACKTICK, /* ` */
	  CHAR_COMMA, /* , */
	  CHAR_DOT, /* . */
	  CHAR_LEFT_PARENTHESES, /* ( */
	  CHAR_RIGHT_PARENTHESES, /* ) */
	  CHAR_LEFT_CURLY_BRACE, /* { */
	  CHAR_RIGHT_CURLY_BRACE, /* } */
	  CHAR_LEFT_SQUARE_BRACKET, /* [ */
	  CHAR_RIGHT_SQUARE_BRACKET, /* ] */
	  CHAR_DOUBLE_QUOTE, /* " */
	  CHAR_SINGLE_QUOTE, /* ' */
	  CHAR_NO_BREAK_SPACE,
	  CHAR_ZERO_WIDTH_NOBREAK_SPACE
	} = requireConstants$1();

	/**
	 * parse
	 */

	const parse = (input, options = {}) => {
	  if (typeof input !== 'string') {
	    throw new TypeError('Expected a string');
	  }

	  const opts = options || {};
	  const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
	  if (input.length > max) {
	    throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
	  }

	  const ast = { type: 'root', input, nodes: [] };
	  const stack = [ast];
	  let block = ast;
	  let prev = ast;
	  let brackets = 0;
	  const length = input.length;
	  let index = 0;
	  let depth = 0;
	  let value;

	  /**
	   * Helpers
	   */

	  const advance = () => input[index++];
	  const push = node => {
	    if (node.type === 'text' && prev.type === 'dot') {
	      prev.type = 'text';
	    }

	    if (prev && prev.type === 'text' && node.type === 'text') {
	      prev.value += node.value;
	      return;
	    }

	    block.nodes.push(node);
	    node.parent = block;
	    node.prev = prev;
	    prev = node;
	    return node;
	  };

	  push({ type: 'bos' });

	  while (index < length) {
	    block = stack[stack.length - 1];
	    value = advance();

	    /**
	     * Invalid chars
	     */

	    if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) {
	      continue;
	    }

	    /**
	     * Escaped chars
	     */

	    if (value === CHAR_BACKSLASH) {
	      push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() });
	      continue;
	    }

	    /**
	     * Right square bracket (literal): ']'
	     */

	    if (value === CHAR_RIGHT_SQUARE_BRACKET) {
	      push({ type: 'text', value: '\\' + value });
	      continue;
	    }

	    /**
	     * Left square bracket: '['
	     */

	    if (value === CHAR_LEFT_SQUARE_BRACKET) {
	      brackets++;

	      let next;

	      while (index < length && (next = advance())) {
	        value += next;

	        if (next === CHAR_LEFT_SQUARE_BRACKET) {
	          brackets++;
	          continue;
	        }

	        if (next === CHAR_BACKSLASH) {
	          value += advance();
	          continue;
	        }

	        if (next === CHAR_RIGHT_SQUARE_BRACKET) {
	          brackets--;

	          if (brackets === 0) {
	            break;
	          }
	        }
	      }

	      push({ type: 'text', value });
	      continue;
	    }

	    /**
	     * Parentheses
	     */

	    if (value === CHAR_LEFT_PARENTHESES) {
	      block = push({ type: 'paren', nodes: [] });
	      stack.push(block);
	      push({ type: 'text', value });
	      continue;
	    }

	    if (value === CHAR_RIGHT_PARENTHESES) {
	      if (block.type !== 'paren') {
	        push({ type: 'text', value });
	        continue;
	      }
	      block = stack.pop();
	      push({ type: 'text', value });
	      block = stack[stack.length - 1];
	      continue;
	    }

	    /**
	     * Quotes: '|"|`
	     */

	    if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
	      const open = value;
	      let next;

	      if (options.keepQuotes !== true) {
	        value = '';
	      }

	      while (index < length && (next = advance())) {
	        if (next === CHAR_BACKSLASH) {
	          value += next + advance();
	          continue;
	        }

	        if (next === open) {
	          if (options.keepQuotes === true) value += next;
	          break;
	        }

	        value += next;
	      }

	      push({ type: 'text', value });
	      continue;
	    }

	    /**
	     * Left curly brace: '{'
	     */

	    if (value === CHAR_LEFT_CURLY_BRACE) {
	      depth++;

	      const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
	      const brace = {
	        type: 'brace',
	        open: true,
	        close: false,
	        dollar,
	        depth,
	        commas: 0,
	        ranges: 0,
	        nodes: []
	      };

	      block = push(brace);
	      stack.push(block);
	      push({ type: 'open', value });
	      continue;
	    }

	    /**
	     * Right curly brace: '}'
	     */

	    if (value === CHAR_RIGHT_CURLY_BRACE) {
	      if (block.type !== 'brace') {
	        push({ type: 'text', value });
	        continue;
	      }

	      const type = 'close';
	      block = stack.pop();
	      block.close = true;

	      push({ type, value });
	      depth--;

	      block = stack[stack.length - 1];
	      continue;
	    }

	    /**
	     * Comma: ','
	     */

	    if (value === CHAR_COMMA && depth > 0) {
	      if (block.ranges > 0) {
	        block.ranges = 0;
	        const open = block.nodes.shift();
	        block.nodes = [open, { type: 'text', value: stringify(block) }];
	      }

	      push({ type: 'comma', value });
	      block.commas++;
	      continue;
	    }

	    /**
	     * Dot: '.'
	     */

	    if (value === CHAR_DOT && depth > 0 && block.commas === 0) {
	      const siblings = block.nodes;

	      if (depth === 0 || siblings.length === 0) {
	        push({ type: 'text', value });
	        continue;
	      }

	      if (prev.type === 'dot') {
	        block.range = [];
	        prev.value += value;
	        prev.type = 'range';

	        if (block.nodes.length !== 3 && block.nodes.length !== 5) {
	          block.invalid = true;
	          block.ranges = 0;
	          prev.type = 'text';
	          continue;
	        }

	        block.ranges++;
	        block.args = [];
	        continue;
	      }

	      if (prev.type === 'range') {
	        siblings.pop();

	        const before = siblings[siblings.length - 1];
	        before.value += prev.value + value;
	        prev = before;
	        block.ranges--;
	        continue;
	      }

	      push({ type: 'dot', value });
	      continue;
	    }

	    /**
	     * Text
	     */

	    push({ type: 'text', value });
	  }

	  // Mark imbalanced braces and brackets as invalid
	  do {
	    block = stack.pop();

	    if (block.type !== 'root') {
	      block.nodes.forEach(node => {
	        if (!node.nodes) {
	          if (node.type === 'open') node.isOpen = true;
	          if (node.type === 'close') node.isClose = true;
	          if (!node.nodes) node.type = 'text';
	          node.invalid = true;
	        }
	      });

	      // get the location of the block on parent.nodes (block's siblings)
	      const parent = stack[stack.length - 1];
	      const index = parent.nodes.indexOf(block);
	      // replace the (invalid) block with it's nodes
	      parent.nodes.splice(index, 1, ...block.nodes);
	    }
	  } while (stack.length > 0);

	  push({ type: 'eos' });
	  return ast;
	};

	parse_1 = parse;
	return parse_1;
}

var braces_1;
var hasRequiredBraces;

function requireBraces () {
	if (hasRequiredBraces) return braces_1;
	hasRequiredBraces = 1;

	const stringify = requireStringify();
	const compile = requireCompile();
	const expand = requireExpand();
	const parse = requireParse();

	/**
	 * Expand the given pattern or create a regex-compatible string.
	 *
	 * ```js
	 * const braces = require('braces');
	 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
	 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
	 * ```
	 * @param {String} `str`
	 * @param {Object} `options`
	 * @return {String}
	 * @api public
	 */

	const braces = (input, options = {}) => {
	  let output = [];

	  if (Array.isArray(input)) {
	    for (const pattern of input) {
	      const result = braces.create(pattern, options);
	      if (Array.isArray(result)) {
	        output.push(...result);
	      } else {
	        output.push(result);
	      }
	    }
	  } else {
	    output = [].concat(braces.create(input, options));
	  }

	  if (options && options.expand === true && options.nodupes === true) {
	    output = [...new Set(output)];
	  }
	  return output;
	};

	/**
	 * Parse the given `str` with the given `options`.
	 *
	 * ```js
	 * // braces.parse(pattern, [, options]);
	 * const ast = braces.parse('a/{b,c}/d');
	 * console.log(ast);
	 * ```
	 * @param {String} pattern Brace pattern to parse
	 * @param {Object} options
	 * @return {Object} Returns an AST
	 * @api public
	 */

	braces.parse = (input, options = {}) => parse(input, options);

	/**
	 * Creates a braces string from an AST, or an AST node.
	 *
	 * ```js
	 * const braces = require('braces');
	 * let ast = braces.parse('foo/{a,b}/bar');
	 * console.log(stringify(ast.nodes[2])); //=> '{a,b}'
	 * ```
	 * @param {String} `input` Brace pattern or AST.
	 * @param {Object} `options`
	 * @return {Array} Returns an array of expanded values.
	 * @api public
	 */

	braces.stringify = (input, options = {}) => {
	  if (typeof input === 'string') {
	    return stringify(braces.parse(input, options), options);
	  }
	  return stringify(input, options);
	};

	/**
	 * Compiles a brace pattern into a regex-compatible, optimized string.
	 * This method is called by the main [braces](#braces) function by default.
	 *
	 * ```js
	 * const braces = require('braces');
	 * console.log(braces.compile('a/{b,c}/d'));
	 * //=> ['a/(b|c)/d']
	 * ```
	 * @param {String} `input` Brace pattern or AST.
	 * @param {Object} `options`
	 * @return {Array} Returns an array of expanded values.
	 * @api public
	 */

	braces.compile = (input, options = {}) => {
	  if (typeof input === 'string') {
	    input = braces.parse(input, options);
	  }
	  return compile(input, options);
	};

	/**
	 * Expands a brace pattern into an array. This method is called by the
	 * main [braces](#braces) function when `options.expand` is true. Before
	 * using this method it's recommended that you read the [performance notes](#performance))
	 * and advantages of using [.compile](#compile) instead.
	 *
	 * ```js
	 * const braces = require('braces');
	 * console.log(braces.expand('a/{b,c}/d'));
	 * //=> ['a/b/d', 'a/c/d'];
	 * ```
	 * @param {String} `pattern` Brace pattern
	 * @param {Object} `options`
	 * @return {Array} Returns an array of expanded values.
	 * @api public
	 */

	braces.expand = (input, options = {}) => {
	  if (typeof input === 'string') {
	    input = braces.parse(input, options);
	  }

	  let result = expand(input, options);

	  // filter out empty strings if specified
	  if (options.noempty === true) {
	    result = result.filter(Boolean);
	  }

	  // filter out duplicates if specified
	  if (options.nodupes === true) {
	    result = [...new Set(result)];
	  }

	  return result;
	};

	/**
	 * Processes a brace pattern and returns either an expanded array
	 * (if `options.expand` is true), a highly optimized regex-compatible string.
	 * This method is called by the main [braces](#braces) function.
	 *
	 * ```js
	 * const braces = require('braces');
	 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
	 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
	 * ```
	 * @param {String} `pattern` Brace pattern
	 * @param {Object} `options`
	 * @return {Array} Returns an array of expanded values.
	 * @api public
	 */

	braces.create = (input, options = {}) => {
	  if (input === '' || input.length < 3) {
	    return [input];
	  }

	  return options.expand !== true
	    ? braces.compile(input, options)
	    : braces.expand(input, options);
	};

	/**
	 * Expose "braces"
	 */

	braces_1 = braces;
	return braces_1;
}

var require$$0 = [
	"3dm",
	"3ds",
	"3g2",
	"3gp",
	"7z",
	"a",
	"aac",
	"adp",
	"afdesign",
	"afphoto",
	"afpub",
	"ai",
	"aif",
	"aiff",
	"alz",
	"ape",
	"apk",
	"appimage",
	"ar",
	"arj",
	"asf",
	"au",
	"avi",
	"bak",
	"baml",
	"bh",
	"bin",
	"bk",
	"bmp",
	"btif",
	"bz2",
	"bzip2",
	"cab",
	"caf",
	"cgm",
	"class",
	"cmx",
	"cpio",
	"cr2",
	"cur",
	"dat",
	"dcm",
	"deb",
	"dex",
	"djvu",
	"dll",
	"dmg",
	"dng",
	"doc",
	"docm",
	"docx",
	"dot",
	"dotm",
	"dra",
	"DS_Store",
	"dsk",
	"dts",
	"dtshd",
	"dvb",
	"dwg",
	"dxf",
	"ecelp4800",
	"ecelp7470",
	"ecelp9600",
	"egg",
	"eol",
	"eot",
	"epub",
	"exe",
	"f4v",
	"fbs",
	"fh",
	"fla",
	"flac",
	"flatpak",
	"fli",
	"flv",
	"fpx",
	"fst",
	"fvt",
	"g3",
	"gh",
	"gif",
	"graffle",
	"gz",
	"gzip",
	"h261",
	"h263",
	"h264",
	"icns",
	"ico",
	"ief",
	"img",
	"ipa",
	"iso",
	"jar",
	"jpeg",
	"jpg",
	"jpgv",
	"jpm",
	"jxr",
	"key",
	"ktx",
	"lha",
	"lib",
	"lvp",
	"lz",
	"lzh",
	"lzma",
	"lzo",
	"m3u",
	"m4a",
	"m4v",
	"mar",
	"mdi",
	"mht",
	"mid",
	"midi",
	"mj2",
	"mka",
	"mkv",
	"mmr",
	"mng",
	"mobi",
	"mov",
	"movie",
	"mp3",
	"mp4",
	"mp4a",
	"mpeg",
	"mpg",
	"mpga",
	"mxu",
	"nef",
	"npx",
	"numbers",
	"nupkg",
	"o",
	"odp",
	"ods",
	"odt",
	"oga",
	"ogg",
	"ogv",
	"otf",
	"ott",
	"pages",
	"pbm",
	"pcx",
	"pdb",
	"pdf",
	"pea",
	"pgm",
	"pic",
	"png",
	"pnm",
	"pot",
	"potm",
	"potx",
	"ppa",
	"ppam",
	"ppm",
	"pps",
	"ppsm",
	"ppsx",
	"ppt",
	"pptm",
	"pptx",
	"psd",
	"pya",
	"pyc",
	"pyo",
	"pyv",
	"qt",
	"rar",
	"ras",
	"raw",
	"resources",
	"rgb",
	"rip",
	"rlc",
	"rmf",
	"rmvb",
	"rpm",
	"rtf",
	"rz",
	"s3m",
	"s7z",
	"scpt",
	"sgi",
	"shar",
	"snap",
	"sil",
	"sketch",
	"slk",
	"smv",
	"snk",
	"so",
	"stl",
	"suo",
	"sub",
	"swf",
	"tar",
	"tbz",
	"tbz2",
	"tga",
	"tgz",
	"thmx",
	"tif",
	"tiff",
	"tlz",
	"ttc",
	"ttf",
	"txz",
	"udf",
	"uvh",
	"uvi",
	"uvm",
	"uvp",
	"uvs",
	"uvu",
	"viv",
	"vob",
	"war",
	"wav",
	"wax",
	"wbmp",
	"wdp",
	"weba",
	"webm",
	"webp",
	"whl",
	"wim",
	"wm",
	"wma",
	"wmv",
	"wmx",
	"woff",
	"woff2",
	"wrm",
	"wvx",
	"xbm",
	"xif",
	"xla",
	"xlam",
	"xls",
	"xlsb",
	"xlsm",
	"xlsx",
	"xlt",
	"xltm",
	"xltx",
	"xm",
	"xmind",
	"xpi",
	"xpm",
	"xwd",
	"xz",
	"z",
	"zip",
	"zipx"
];

var binaryExtensions;
var hasRequiredBinaryExtensions;

function requireBinaryExtensions () {
	if (hasRequiredBinaryExtensions) return binaryExtensions;
	hasRequiredBinaryExtensions = 1;
	binaryExtensions = require$$0;
	return binaryExtensions;
}

var isBinaryPath;
var hasRequiredIsBinaryPath;

function requireIsBinaryPath () {
	if (hasRequiredIsBinaryPath) return isBinaryPath;
	hasRequiredIsBinaryPath = 1;
	const path = require$$1;
	const binaryExtensions = requireBinaryExtensions();

	const extensions = new Set(binaryExtensions);

	isBinaryPath = filePath => extensions.has(path.extname(filePath).slice(1).toLowerCase());
	return isBinaryPath;
}

var constants = {};

var hasRequiredConstants;

function requireConstants () {
	if (hasRequiredConstants) return constants;
	hasRequiredConstants = 1;
	(function (exports) {

		const {sep} = require$$1;
		const {platform} = process;
		const os = require$$3;

		exports.EV_ALL = 'all';
		exports.EV_READY = 'ready';
		exports.EV_ADD = 'add';
		exports.EV_CHANGE = 'change';
		exports.EV_ADD_DIR = 'addDir';
		exports.EV_UNLINK = 'unlink';
		exports.EV_UNLINK_DIR = 'unlinkDir';
		exports.EV_RAW = 'raw';
		exports.EV_ERROR = 'error';

		exports.STR_DATA = 'data';
		exports.STR_END = 'end';
		exports.STR_CLOSE = 'close';

		exports.FSEVENT_CREATED = 'created';
		exports.FSEVENT_MODIFIED = 'modified';
		exports.FSEVENT_DELETED = 'deleted';
		exports.FSEVENT_MOVED = 'moved';
		exports.FSEVENT_CLONED = 'cloned';
		exports.FSEVENT_UNKNOWN = 'unknown';
		exports.FSEVENT_FLAG_MUST_SCAN_SUBDIRS = 1;
		exports.FSEVENT_TYPE_FILE = 'file';
		exports.FSEVENT_TYPE_DIRECTORY = 'directory';
		exports.FSEVENT_TYPE_SYMLINK = 'symlink';

		exports.KEY_LISTENERS = 'listeners';
		exports.KEY_ERR = 'errHandlers';
		exports.KEY_RAW = 'rawEmitters';
		exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW];

		exports.DOT_SLASH = `.${sep}`;

		exports.BACK_SLASH_RE = /\\/g;
		exports.DOUBLE_SLASH_RE = /\/\//;
		exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/;
		exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
		exports.REPLACER_RE = /^\.[/\\]/;

		exports.SLASH = '/';
		exports.SLASH_SLASH = '//';
		exports.BRACE_START = '{';
		exports.BANG = '!';
		exports.ONE_DOT = '.';
		exports.TWO_DOTS = '..';
		exports.STAR = '*';
		exports.GLOBSTAR = '**';
		exports.ROOT_GLOBSTAR = '/**/*';
		exports.SLASH_GLOBSTAR = '/**';
		exports.DIR_SUFFIX = 'Dir';
		exports.ANYMATCH_OPTS = {dot: true};
		exports.STRING_TYPE = 'string';
		exports.FUNCTION_TYPE = 'function';
		exports.EMPTY_STR = '';
		exports.EMPTY_FN = () => {};
		exports.IDENTITY_FN = val => val;

		exports.isWindows = platform === 'win32';
		exports.isMacos = platform === 'darwin';
		exports.isLinux = platform === 'linux';
		exports.isIBMi = os.type() === 'OS400'; 
	} (constants));
	return constants;
}

var nodefsHandler;
var hasRequiredNodefsHandler;

function requireNodefsHandler () {
	if (hasRequiredNodefsHandler) return nodefsHandler;
	hasRequiredNodefsHandler = 1;

	const fs = require$$0$2;
	const sysPath = require$$1;
	const { promisify } = require$$0$5;
	const isBinaryPath = requireIsBinaryPath();
	const {
	  isWindows,
	  isLinux,
	  EMPTY_FN,
	  EMPTY_STR,
	  KEY_LISTENERS,
	  KEY_ERR,
	  KEY_RAW,
	  HANDLER_KEYS,
	  EV_CHANGE,
	  EV_ADD,
	  EV_ADD_DIR,
	  EV_ERROR,
	  STR_DATA,
	  STR_END,
	  BRACE_START,
	  STAR
	} = requireConstants();

	const THROTTLE_MODE_WATCH = 'watch';

	const open = promisify(fs.open);
	const stat = promisify(fs.stat);
	const lstat = promisify(fs.lstat);
	const close = promisify(fs.close);
	const fsrealpath = promisify(fs.realpath);

	const statMethods = { lstat, stat };

	// TODO: emit errors properly. Example: EMFILE on Macos.
	const foreach = (val, fn) => {
	  if (val instanceof Set) {
	    val.forEach(fn);
	  } else {
	    fn(val);
	  }
	};

	const addAndConvert = (main, prop, item) => {
	  let container = main[prop];
	  if (!(container instanceof Set)) {
	    main[prop] = container = new Set([container]);
	  }
	  container.add(item);
	};

	const clearItem = cont => key => {
	  const set = cont[key];
	  if (set instanceof Set) {
	    set.clear();
	  } else {
	    delete cont[key];
	  }
	};

	const delFromSet = (main, prop, item) => {
	  const container = main[prop];
	  if (container instanceof Set) {
	    container.delete(item);
	  } else if (container === item) {
	    delete main[prop];
	  }
	};

	const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;

	/**
	 * @typedef {String} Path
	 */

	// fs_watch helpers

	// object to hold per-process fs_watch instances
	// (may be shared across chokidar FSWatcher instances)

	/**
	 * @typedef {Object} FsWatchContainer
	 * @property {Set} listeners
	 * @property {Set} errHandlers
	 * @property {Set} rawEmitters
	 * @property {fs.FSWatcher=} watcher
	 * @property {Boolean=} watcherUnusable
	 */

	/**
	 * @type {Map<String,FsWatchContainer>}
	 */
	const FsWatchInstances = new Map();

	/**
	 * Instantiates the fs_watch interface
	 * @param {String} path to be watched
	 * @param {Object} options to be passed to fs_watch
	 * @param {Function} listener main event handler
	 * @param {Function} errHandler emits info about errors
	 * @param {Function} emitRaw emits raw event data
	 * @returns {fs.FSWatcher} new fsevents instance
	 */
	function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
	  const handleEvent = (rawEvent, evPath) => {
	    listener(path);
	    emitRaw(rawEvent, evPath, {watchedPath: path});

	    // emit based on events occurring for files from a directory's watcher in
	    // case the file's watcher misses it (and rely on throttling to de-dupe)
	    if (evPath && path !== evPath) {
	      fsWatchBroadcast(
	        sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath)
	      );
	    }
	  };
	  try {
	    return fs.watch(path, options, handleEvent);
	  } catch (error) {
	    errHandler(error);
	  }
	}

	/**
	 * Helper for passing fs_watch event data to a collection of listeners
	 * @param {Path} fullPath absolute path bound to fs_watch instance
	 * @param {String} type listener type
	 * @param {*=} val1 arguments to be passed to listeners
	 * @param {*=} val2
	 * @param {*=} val3
	 */
	const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => {
	  const cont = FsWatchInstances.get(fullPath);
	  if (!cont) return;
	  foreach(cont[type], (listener) => {
	    listener(val1, val2, val3);
	  });
	};

	/**
	 * Instantiates the fs_watch interface or binds listeners
	 * to an existing one covering the same file system entry
	 * @param {String} path
	 * @param {String} fullPath absolute path
	 * @param {Object} options to be passed to fs_watch
	 * @param {Object} handlers container for event listener functions
	 */
	const setFsWatchListener = (path, fullPath, options, handlers) => {
	  const {listener, errHandler, rawEmitter} = handlers;
	  let cont = FsWatchInstances.get(fullPath);

	  /** @type {fs.FSWatcher=} */
	  let watcher;
	  if (!options.persistent) {
	    watcher = createFsWatchInstance(
	      path, options, listener, errHandler, rawEmitter
	    );
	    return watcher.close.bind(watcher);
	  }
	  if (cont) {
	    addAndConvert(cont, KEY_LISTENERS, listener);
	    addAndConvert(cont, KEY_ERR, errHandler);
	    addAndConvert(cont, KEY_RAW, rawEmitter);
	  } else {
	    watcher = createFsWatchInstance(
	      path,
	      options,
	      fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
	      errHandler, // no need to use broadcast here
	      fsWatchBroadcast.bind(null, fullPath, KEY_RAW)
	    );
	    if (!watcher) return;
	    watcher.on(EV_ERROR, async (error) => {
	      const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
	      cont.watcherUnusable = true; // documented since Node 10.4.1
	      // Workaround for https://github.com/joyent/node/issues/4337
	      if (isWindows && error.code === 'EPERM') {
	        try {
	          const fd = await open(path, 'r');
	          await close(fd);
	          broadcastErr(error);
	        } catch (err) {}
	      } else {
	        broadcastErr(error);
	      }
	    });
	    cont = {
	      listeners: listener,
	      errHandlers: errHandler,
	      rawEmitters: rawEmitter,
	      watcher
	    };
	    FsWatchInstances.set(fullPath, cont);
	  }
	  // const index = cont.listeners.indexOf(listener);

	  // removes this instance's listeners and closes the underlying fs_watch
	  // instance if there are no more listeners left
	  return () => {
	    delFromSet(cont, KEY_LISTENERS, listener);
	    delFromSet(cont, KEY_ERR, errHandler);
	    delFromSet(cont, KEY_RAW, rawEmitter);
	    if (isEmptySet(cont.listeners)) {
	      // Check to protect against issue gh-730.
	      // if (cont.watcherUnusable) {
	      cont.watcher.close();
	      // }
	      FsWatchInstances.delete(fullPath);
	      HANDLER_KEYS.forEach(clearItem(cont));
	      cont.watcher = undefined;
	      Object.freeze(cont);
	    }
	  };
	};

	// fs_watchFile helpers

	// object to hold per-process fs_watchFile instances
	// (may be shared across chokidar FSWatcher instances)
	const FsWatchFileInstances = new Map();

	/**
	 * Instantiates the fs_watchFile interface or binds listeners
	 * to an existing one covering the same file system entry
	 * @param {String} path to be watched
	 * @param {String} fullPath absolute path
	 * @param {Object} options options to be passed to fs_watchFile
	 * @param {Object} handlers container for event listener functions
	 * @returns {Function} closer
	 */
	const setFsWatchFileListener = (path, fullPath, options, handlers) => {
	  const {listener, rawEmitter} = handlers;
	  let cont = FsWatchFileInstances.get(fullPath);

	  const copts = cont && cont.options;
	  if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
	    // "Upgrade" the watcher to persistence or a quicker interval.
	    // This creates some unlikely edge case issues if the user mixes
	    // settings in a very weird way, but solving for those cases
	    // doesn't seem worthwhile for the added complexity.
	    cont.listeners;
	    cont.rawEmitters;
	    fs.unwatchFile(fullPath);
	    cont = undefined;
	  }

	  /* eslint-enable no-unused-vars, prefer-destructuring */

	  if (cont) {
	    addAndConvert(cont, KEY_LISTENERS, listener);
	    addAndConvert(cont, KEY_RAW, rawEmitter);
	  } else {
	    // TODO
	    // listeners.add(listener);
	    // rawEmitters.add(rawEmitter);
	    cont = {
	      listeners: listener,
	      rawEmitters: rawEmitter,
	      options,
	      watcher: fs.watchFile(fullPath, options, (curr, prev) => {
	        foreach(cont.rawEmitters, (rawEmitter) => {
	          rawEmitter(EV_CHANGE, fullPath, {curr, prev});
	        });
	        const currmtime = curr.mtimeMs;
	        if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
	          foreach(cont.listeners, (listener) => listener(path, curr));
	        }
	      })
	    };
	    FsWatchFileInstances.set(fullPath, cont);
	  }
	  // const index = cont.listeners.indexOf(listener);

	  // Removes this instance's listeners and closes the underlying fs_watchFile
	  // instance if there are no more listeners left.
	  return () => {
	    delFromSet(cont, KEY_LISTENERS, listener);
	    delFromSet(cont, KEY_RAW, rawEmitter);
	    if (isEmptySet(cont.listeners)) {
	      FsWatchFileInstances.delete(fullPath);
	      fs.unwatchFile(fullPath);
	      cont.options = cont.watcher = undefined;
	      Object.freeze(cont);
	    }
	  };
	};

	/**
	 * @mixin
	 */
	class NodeFsHandler {

	/**
	 * @param {import("../index").FSWatcher} fsW
	 */
	constructor(fsW) {
	  this.fsw = fsW;
	  this._boundHandleError = (error) => fsW._handleError(error);
	}

	/**
	 * Watch file for changes with fs_watchFile or fs_watch.
	 * @param {String} path to file or dir
	 * @param {Function} listener on fs change
	 * @returns {Function} closer for the watcher instance
	 */
	_watchWithNodeFs(path, listener) {
	  const opts = this.fsw.options;
	  const directory = sysPath.dirname(path);
	  const basename = sysPath.basename(path);
	  const parent = this.fsw._getWatchedDir(directory);
	  parent.add(basename);
	  const absolutePath = sysPath.resolve(path);
	  const options = {persistent: opts.persistent};
	  if (!listener) listener = EMPTY_FN;

	  let closer;
	  if (opts.usePolling) {
	    options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ?
	      opts.binaryInterval : opts.interval;
	    closer = setFsWatchFileListener(path, absolutePath, options, {
	      listener,
	      rawEmitter: this.fsw._emitRaw
	    });
	  } else {
	    closer = setFsWatchListener(path, absolutePath, options, {
	      listener,
	      errHandler: this._boundHandleError,
	      rawEmitter: this.fsw._emitRaw
	    });
	  }
	  return closer;
	}

	/**
	 * Watch a file and emit add event if warranted.
	 * @param {Path} file Path
	 * @param {fs.Stats} stats result of fs_stat
	 * @param {Boolean} initialAdd was the file added at watch instantiation?
	 * @returns {Function} closer for the watcher instance
	 */
	_handleFile(file, stats, initialAdd) {
	  if (this.fsw.closed) {
	    return;
	  }
	  const dirname = sysPath.dirname(file);
	  const basename = sysPath.basename(file);
	  const parent = this.fsw._getWatchedDir(dirname);
	  // stats is always present
	  let prevStats = stats;

	  // if the file is already being watched, do nothing
	  if (parent.has(basename)) return;

	  const listener = async (path, newStats) => {
	    if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return;
	    if (!newStats || newStats.mtimeMs === 0) {
	      try {
	        const newStats = await stat(file);
	        if (this.fsw.closed) return;
	        // Check that change event was not fired because of changed only accessTime.
	        const at = newStats.atimeMs;
	        const mt = newStats.mtimeMs;
	        if (!at || at <= mt || mt !== prevStats.mtimeMs) {
	          this.fsw._emit(EV_CHANGE, file, newStats);
	        }
	        if (isLinux && prevStats.ino !== newStats.ino) {
	          this.fsw._closeFile(path);
	          prevStats = newStats;
	          this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener));
	        } else {
	          prevStats = newStats;
	        }
	      } catch (error) {
	        // Fix issues where mtime is null but file is still present
	        this.fsw._remove(dirname, basename);
	      }
	      // add is about to be emitted if file not already tracked in parent
	    } else if (parent.has(basename)) {
	      // Check that change event was not fired because of changed only accessTime.
	      const at = newStats.atimeMs;
	      const mt = newStats.mtimeMs;
	      if (!at || at <= mt || mt !== prevStats.mtimeMs) {
	        this.fsw._emit(EV_CHANGE, file, newStats);
	      }
	      prevStats = newStats;
	    }
	  };
	  // kick off the watcher
	  const closer = this._watchWithNodeFs(file, listener);

	  // emit an add event if we're supposed to
	  if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
	    if (!this.fsw._throttle(EV_ADD, file, 0)) return;
	    this.fsw._emit(EV_ADD, file, stats);
	  }

	  return closer;
	}

	/**
	 * Handle symlinks encountered while reading a dir.
	 * @param {Object} entry returned by readdirp
	 * @param {String} directory path of dir being read
	 * @param {String} path of this item
	 * @param {String} item basename of this item
	 * @returns {Promise<Boolean>} true if no more processing is needed for this entry.
	 */
	async _handleSymlink(entry, directory, path, item) {
	  if (this.fsw.closed) {
	    return;
	  }
	  const full = entry.fullPath;
	  const dir = this.fsw._getWatchedDir(directory);

	  if (!this.fsw.options.followSymlinks) {
	    // watch symlink directly (don't follow) and detect changes
	    this.fsw._incrReadyCount();

	    let linkPath;
	    try {
	      linkPath = await fsrealpath(path);
	    } catch (e) {
	      this.fsw._emitReady();
	      return true;
	    }

	    if (this.fsw.closed) return;
	    if (dir.has(item)) {
	      if (this.fsw._symlinkPaths.get(full) !== linkPath) {
	        this.fsw._symlinkPaths.set(full, linkPath);
	        this.fsw._emit(EV_CHANGE, path, entry.stats);
	      }
	    } else {
	      dir.add(item);
	      this.fsw._symlinkPaths.set(full, linkPath);
	      this.fsw._emit(EV_ADD, path, entry.stats);
	    }
	    this.fsw._emitReady();
	    return true;
	  }

	  // don't follow the same symlink more than once
	  if (this.fsw._symlinkPaths.has(full)) {
	    return true;
	  }

	  this.fsw._symlinkPaths.set(full, true);
	}

	_handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
	  // Normalize the directory name on Windows
	  directory = sysPath.join(directory, EMPTY_STR);

	  if (!wh.hasGlob) {
	    throttler = this.fsw._throttle('readdir', directory, 1000);
	    if (!throttler) return;
	  }

	  const previous = this.fsw._getWatchedDir(wh.path);
	  const current = new Set();

	  let stream = this.fsw._readdirp(directory, {
	    fileFilter: entry => wh.filterPath(entry),
	    directoryFilter: entry => wh.filterDir(entry),
	    depth: 0
	  }).on(STR_DATA, async (entry) => {
	    if (this.fsw.closed) {
	      stream = undefined;
	      return;
	    }
	    const item = entry.path;
	    let path = sysPath.join(directory, item);
	    current.add(item);

	    if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) {
	      return;
	    }

	    if (this.fsw.closed) {
	      stream = undefined;
	      return;
	    }
	    // Files that present in current directory snapshot
	    // but absent in previous are added to watch list and
	    // emit `add` event.
	    if (item === target || !target && !previous.has(item)) {
	      this.fsw._incrReadyCount();

	      // ensure relativeness of path is preserved in case of watcher reuse
	      path = sysPath.join(dir, sysPath.relative(dir, path));

	      this._addToNodeFs(path, initialAdd, wh, depth + 1);
	    }
	  }).on(EV_ERROR, this._boundHandleError);

	  return new Promise(resolve =>
	    stream.once(STR_END, () => {
	      if (this.fsw.closed) {
	        stream = undefined;
	        return;
	      }
	      const wasThrottled = throttler ? throttler.clear() : false;

	      resolve();

	      // Files that absent in current directory snapshot
	      // but present in previous emit `remove` event
	      // and are removed from @watched[directory].
	      previous.getChildren().filter((item) => {
	        return item !== directory &&
	          !current.has(item) &&
	          // in case of intersecting globs;
	          // a path may have been filtered out of this readdir, but
	          // shouldn't be removed because it matches a different glob
	          (!wh.hasGlob || wh.filterPath({
	            fullPath: sysPath.resolve(directory, item)
	          }));
	      }).forEach((item) => {
	        this.fsw._remove(directory, item);
	      });

	      stream = undefined;

	      // one more time for any missed in case changes came in extremely quickly
	      if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler);
	    })
	  );
	}

	/**
	 * Read directory to add / remove files from `@watched` list and re-read it on change.
	 * @param {String} dir fs path
	 * @param {fs.Stats} stats
	 * @param {Boolean} initialAdd
	 * @param {Number} depth relative to user-supplied path
	 * @param {String} target child path targeted for watch
	 * @param {Object} wh Common watch helpers for this path
	 * @param {String} realpath
	 * @returns {Promise<Function>} closer for the watcher instance.
	 */
	async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) {
	  const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir));
	  const tracked = parentDir.has(sysPath.basename(dir));
	  if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
	    if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR, dir, stats);
	  }

	  // ensure dir is tracked (harmless if redundant)
	  parentDir.add(sysPath.basename(dir));
	  this.fsw._getWatchedDir(dir);
	  let throttler;
	  let closer;

	  const oDepth = this.fsw.options.depth;
	  if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) {
	    if (!target) {
	      await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
	      if (this.fsw.closed) return;
	    }

	    closer = this._watchWithNodeFs(dir, (dirPath, stats) => {
	      // if current directory is removed, do nothing
	      if (stats && stats.mtimeMs === 0) return;

	      this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
	    });
	  }
	  return closer;
	}

	/**
	 * Handle added file, directory, or glob pattern.
	 * Delegates call to _handleFile / _handleDir after checks.
	 * @param {String} path to file or ir
	 * @param {Boolean} initialAdd was the file added at watch instantiation?
	 * @param {Object} priorWh depth relative to user-supplied path
	 * @param {Number} depth Child path actually targeted for watch
	 * @param {String=} target Child path actually targeted for watch
	 * @returns {Promise}
	 */
	async _addToNodeFs(path, initialAdd, priorWh, depth, target) {
	  const ready = this.fsw._emitReady;
	  if (this.fsw._isIgnored(path) || this.fsw.closed) {
	    ready();
	    return false;
	  }

	  const wh = this.fsw._getWatchHelpers(path, depth);
	  if (!wh.hasGlob && priorWh) {
	    wh.hasGlob = priorWh.hasGlob;
	    wh.globFilter = priorWh.globFilter;
	    wh.filterPath = entry => priorWh.filterPath(entry);
	    wh.filterDir = entry => priorWh.filterDir(entry);
	  }

	  // evaluate what is at the path we're being asked to watch
	  try {
	    const stats = await statMethods[wh.statMethod](wh.watchPath);
	    if (this.fsw.closed) return;
	    if (this.fsw._isIgnored(wh.watchPath, stats)) {
	      ready();
	      return false;
	    }

	    const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START);
	    let closer;
	    if (stats.isDirectory()) {
	      const absPath = sysPath.resolve(path);
	      const targetPath = follow ? await fsrealpath(path) : path;
	      if (this.fsw.closed) return;
	      closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
	      if (this.fsw.closed) return;
	      // preserve this symlink's target path
	      if (absPath !== targetPath && targetPath !== undefined) {
	        this.fsw._symlinkPaths.set(absPath, targetPath);
	      }
	    } else if (stats.isSymbolicLink()) {
	      const targetPath = follow ? await fsrealpath(path) : path;
	      if (this.fsw.closed) return;
	      const parent = sysPath.dirname(wh.watchPath);
	      this.fsw._getWatchedDir(parent).add(wh.watchPath);
	      this.fsw._emit(EV_ADD, wh.watchPath, stats);
	      closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath);
	      if (this.fsw.closed) return;

	      // preserve this symlink's target path
	      if (targetPath !== undefined) {
	        this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath);
	      }
	    } else {
	      closer = this._handleFile(wh.watchPath, stats, initialAdd);
	    }
	    ready();

	    this.fsw._addPathCloser(path, closer);
	    return false;

	  } catch (error) {
	    if (this.fsw._handleError(error)) {
	      ready();
	      return path;
	    }
	  }
	}

	}

	nodefsHandler = NodeFsHandler;
	return nodefsHandler;
}

var fseventsHandler = {exports: {}};

var hasRequiredFseventsHandler;

function requireFseventsHandler () {
	if (hasRequiredFseventsHandler) return fseventsHandler.exports;
	hasRequiredFseventsHandler = 1;

	const fs = require$$0$2;
	const sysPath = require$$1;
	const { promisify } = require$$0$5;

	let fsevents;
	try {
	  fsevents = require('fsevents');
	} catch (error) {
	  if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error);
	}

	if (fsevents) {
	  // TODO: real check
	  const mtch = process.version.match(/v(\d+)\.(\d+)/);
	  if (mtch && mtch[1] && mtch[2]) {
	    const maj = Number.parseInt(mtch[1], 10);
	    const min = Number.parseInt(mtch[2], 10);
	    if (maj === 8 && min < 16) {
	      fsevents = undefined;
	    }
	  }
	}

	const {
	  EV_ADD,
	  EV_CHANGE,
	  EV_ADD_DIR,
	  EV_UNLINK,
	  EV_ERROR,
	  STR_DATA,
	  STR_END,
	  FSEVENT_CREATED,
	  FSEVENT_MODIFIED,
	  FSEVENT_DELETED,
	  FSEVENT_MOVED,
	  // FSEVENT_CLONED,
	  FSEVENT_UNKNOWN,
	  FSEVENT_FLAG_MUST_SCAN_SUBDIRS,
	  FSEVENT_TYPE_FILE,
	  FSEVENT_TYPE_DIRECTORY,
	  FSEVENT_TYPE_SYMLINK,

	  ROOT_GLOBSTAR,
	  DIR_SUFFIX,
	  DOT_SLASH,
	  FUNCTION_TYPE,
	  EMPTY_FN,
	  IDENTITY_FN
	} = requireConstants();

	const Depth = (value) => isNaN(value) ? {} : {depth: value};

	const stat = promisify(fs.stat);
	const lstat = promisify(fs.lstat);
	const realpath = promisify(fs.realpath);

	const statMethods = { stat, lstat };

	/**
	 * @typedef {String} Path
	 */

	/**
	 * @typedef {Object} FsEventsWatchContainer
	 * @property {Set<Function>} listeners
	 * @property {Function} rawEmitter
	 * @property {{stop: Function}} watcher
	 */

	// fsevents instance helper functions
	/**
	 * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances)
	 * @type {Map<Path,FsEventsWatchContainer>}
	 */
	const FSEventsWatchers = new Map();

	// Threshold of duplicate path prefixes at which to start
	// consolidating going forward
	const consolidateThreshhold = 10;

	const wrongEventFlags = new Set([
	  69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912
	]);

	/**
	 * Instantiates the fsevents interface
	 * @param {Path} path path to be watched
	 * @param {Function} callback called when fsevents is bound and ready
	 * @returns {{stop: Function}} new fsevents instance
	 */
	const createFSEventsInstance = (path, callback) => {
	  const stop = fsevents.watch(path, callback);
	  return {stop};
	};

	/**
	 * Instantiates the fsevents interface or binds listeners to an existing one covering
	 * the same file tree.
	 * @param {Path} path           - to be watched
	 * @param {Path} realPath       - real path for symlinks
	 * @param {Function} listener   - called when fsevents emits events
	 * @param {Function} rawEmitter - passes data to listeners of the 'raw' event
	 * @returns {Function} closer
	 */
	function setFSEventsListener(path, realPath, listener, rawEmitter) {
	  let watchPath = sysPath.extname(realPath) ? sysPath.dirname(realPath) : realPath;

	  const parentPath = sysPath.dirname(watchPath);
	  let cont = FSEventsWatchers.get(watchPath);

	  // If we've accumulated a substantial number of paths that
	  // could have been consolidated by watching one directory
	  // above the current one, create a watcher on the parent
	  // path instead, so that we do consolidate going forward.
	  if (couldConsolidate(parentPath)) {
	    watchPath = parentPath;
	  }

	  const resolvedPath = sysPath.resolve(path);
	  const hasSymlink = resolvedPath !== realPath;

	  const filteredListener = (fullPath, flags, info) => {
	    if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath);
	    if (
	      fullPath === resolvedPath ||
	      !fullPath.indexOf(resolvedPath + sysPath.sep)
	    ) listener(fullPath, flags, info);
	  };

	  // check if there is already a watcher on a parent path
	  // modifies `watchPath` to the parent path when it finds a match
	  let watchedParent = false;
	  for (const watchedPath of FSEventsWatchers.keys()) {
	    if (realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep) === 0) {
	      watchPath = watchedPath;
	      cont = FSEventsWatchers.get(watchPath);
	      watchedParent = true;
	      break;
	    }
	  }

	  if (cont || watchedParent) {
	    cont.listeners.add(filteredListener);
	  } else {
	    cont = {
	      listeners: new Set([filteredListener]),
	      rawEmitter,
	      watcher: createFSEventsInstance(watchPath, (fullPath, flags) => {
	        if (!cont.listeners.size) return;
	        if (flags & FSEVENT_FLAG_MUST_SCAN_SUBDIRS) return;
	        const info = fsevents.getInfo(fullPath, flags);
	        cont.listeners.forEach(list => {
	          list(fullPath, flags, info);
	        });

	        cont.rawEmitter(info.event, fullPath, info);
	      })
	    };
	    FSEventsWatchers.set(watchPath, cont);
	  }

	  // removes this instance's listeners and closes the underlying fsevents
	  // instance if there are no more listeners left
	  return () => {
	    const lst = cont.listeners;

	    lst.delete(filteredListener);
	    if (!lst.size) {
	      FSEventsWatchers.delete(watchPath);
	      if (cont.watcher) return cont.watcher.stop().then(() => {
	        cont.rawEmitter = cont.watcher = undefined;
	        Object.freeze(cont);
	      });
	    }
	  };
	}

	// Decide whether or not we should start a new higher-level
	// parent watcher
	const couldConsolidate = (path) => {
	  let count = 0;
	  for (const watchPath of FSEventsWatchers.keys()) {
	    if (watchPath.indexOf(path) === 0) {
	      count++;
	      if (count >= consolidateThreshhold) {
	        return true;
	      }
	    }
	  }

	  return false;
	};

	// returns boolean indicating whether fsevents can be used
	const canUse = () => fsevents && FSEventsWatchers.size < 128;

	// determines subdirectory traversal levels from root to path
	const calcDepth = (path, root) => {
	  let i = 0;
	  while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++;
	  return i;
	};

	// returns boolean indicating whether the fsevents' event info has the same type
	// as the one returned by fs.stat
	const sameTypes = (info, stats) => (
	  info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() ||
	  info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() ||
	  info.type === FSEVENT_TYPE_FILE && stats.isFile()
	);

	/**
	 * @mixin
	 */
	class FsEventsHandler {

	/**
	 * @param {import('../index').FSWatcher} fsw
	 */
	constructor(fsw) {
	  this.fsw = fsw;
	}
	checkIgnored(path, stats) {
	  const ipaths = this.fsw._ignoredPaths;
	  if (this.fsw._isIgnored(path, stats)) {
	    ipaths.add(path);
	    if (stats && stats.isDirectory()) {
	      ipaths.add(path + ROOT_GLOBSTAR);
	    }
	    return true;
	  }

	  ipaths.delete(path);
	  ipaths.delete(path + ROOT_GLOBSTAR);
	}

	addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) {
	  const event = watchedDir.has(item) ? EV_CHANGE : EV_ADD;
	  this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts);
	}

	async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) {
	  try {
	    const stats = await stat(path);
	    if (this.fsw.closed) return;
	    if (sameTypes(info, stats)) {
	      this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
	    } else {
	      this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
	    }
	  } catch (error) {
	    if (error.code === 'EACCES') {
	      this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
	    } else {
	      this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
	    }
	  }
	}

	handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) {
	  if (this.fsw.closed || this.checkIgnored(path)) return;

	  if (event === EV_UNLINK) {
	    const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY;
	    // suppress unlink events on never before seen files
	    if (isDirectory || watchedDir.has(item)) {
	      this.fsw._remove(parent, item, isDirectory);
	    }
	  } else {
	    if (event === EV_ADD) {
	      // track new directories
	      if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path);

	      if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) {
	        // push symlinks back to the top of the stack to get handled
	        const curDepth = opts.depth === undefined ?
	          undefined : calcDepth(fullPath, realPath) + 1;
	        return this._addToFsEvents(path, false, true, curDepth);
	      }

	      // track new paths
	      // (other than symlinks being followed, which will be tracked soon)
	      this.fsw._getWatchedDir(parent).add(item);
	    }
	    /**
	     * @type {'add'|'addDir'|'unlink'|'unlinkDir'}
	     */
	    const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event;
	    this.fsw._emit(eventName, path);
	    if (eventName === EV_ADD_DIR) this._addToFsEvents(path, false, true);
	  }
	}

	/**
	 * Handle symlinks encountered during directory scan
	 * @param {String} watchPath  - file/dir path to be watched with fsevents
	 * @param {String} realPath   - real path (in case of symlinks)
	 * @param {Function} transform  - path transformer
	 * @param {Function} globFilter - path filter in case a glob pattern was provided
	 * @returns {Function} closer for the watcher instance
	*/
	_watchWithFsEvents(watchPath, realPath, transform, globFilter) {
	  if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return;
	  const opts = this.fsw.options;
	  const watchCallback = async (fullPath, flags, info) => {
	    if (this.fsw.closed) return;
	    if (
	      opts.depth !== undefined &&
	      calcDepth(fullPath, realPath) > opts.depth
	    ) return;
	    const path = transform(sysPath.join(
	      watchPath, sysPath.relative(watchPath, fullPath)
	    ));
	    if (globFilter && !globFilter(path)) return;
	    // ensure directories are tracked
	    const parent = sysPath.dirname(path);
	    const item = sysPath.basename(path);
	    const watchedDir = this.fsw._getWatchedDir(
	      info.type === FSEVENT_TYPE_DIRECTORY ? path : parent
	    );

	    // correct for wrong events emitted
	    if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) {
	      if (typeof opts.ignored === FUNCTION_TYPE) {
	        let stats;
	        try {
	          stats = await stat(path);
	        } catch (error) {}
	        if (this.fsw.closed) return;
	        if (this.checkIgnored(path, stats)) return;
	        if (sameTypes(info, stats)) {
	          this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
	        } else {
	          this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
	        }
	      } else {
	        this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts);
	      }
	    } else {
	      switch (info.event) {
	      case FSEVENT_CREATED:
	      case FSEVENT_MODIFIED:
	        return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
	      case FSEVENT_DELETED:
	      case FSEVENT_MOVED:
	        return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts);
	      }
	    }
	  };

	  const closer = setFSEventsListener(
	    watchPath,
	    realPath,
	    watchCallback,
	    this.fsw._emitRaw
	  );

	  this.fsw._emitReady();
	  return closer;
	}

	/**
	 * Handle symlinks encountered during directory scan
	 * @param {String} linkPath path to symlink
	 * @param {String} fullPath absolute path to the symlink
	 * @param {Function} transform pre-existing path transformer
	 * @param {Number} curDepth level of subdirectories traversed to where symlink is
	 * @returns {Promise<void>}
	 */
	async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) {
	  // don't follow the same symlink more than once
	  if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return;

	  this.fsw._symlinkPaths.set(fullPath, true);
	  this.fsw._incrReadyCount();

	  try {
	    const linkTarget = await realpath(linkPath);
	    if (this.fsw.closed) return;
	    if (this.fsw._isIgnored(linkTarget)) {
	      return this.fsw._emitReady();
	    }

	    this.fsw._incrReadyCount();

	    // add the linkTarget for watching with a wrapper for transform
	    // that causes emitted paths to incorporate the link's path
	    this._addToFsEvents(linkTarget || linkPath, (path) => {
	      let aliasedPath = linkPath;
	      if (linkTarget && linkTarget !== DOT_SLASH) {
	        aliasedPath = path.replace(linkTarget, linkPath);
	      } else if (path !== DOT_SLASH) {
	        aliasedPath = sysPath.join(linkPath, path);
	      }
	      return transform(aliasedPath);
	    }, false, curDepth);
	  } catch(error) {
	    if (this.fsw._handleError(error)) {
	      return this.fsw._emitReady();
	    }
	  }
	}

	/**
	 *
	 * @param {Path} newPath
	 * @param {fs.Stats} stats
	 */
	emitAdd(newPath, stats, processPath, opts, forceAdd) {
	  const pp = processPath(newPath);
	  const isDir = stats.isDirectory();
	  const dirObj = this.fsw._getWatchedDir(sysPath.dirname(pp));
	  const base = sysPath.basename(pp);

	  // ensure empty dirs get tracked
	  if (isDir) this.fsw._getWatchedDir(pp);
	  if (dirObj.has(base)) return;
	  dirObj.add(base);

	  if (!opts.ignoreInitial || forceAdd === true) {
	    this.fsw._emit(isDir ? EV_ADD_DIR : EV_ADD, pp, stats);
	  }
	}

	initWatch(realPath, path, wh, processPath) {
	  if (this.fsw.closed) return;
	  const closer = this._watchWithFsEvents(
	    wh.watchPath,
	    sysPath.resolve(realPath || wh.watchPath),
	    processPath,
	    wh.globFilter
	  );
	  this.fsw._addPathCloser(path, closer);
	}

	/**
	 * Handle added path with fsevents
	 * @param {String} path file/dir path or glob pattern
	 * @param {Function|Boolean=} transform converts working path to what the user expects
	 * @param {Boolean=} forceAdd ensure add is emitted
	 * @param {Number=} priorDepth Level of subdirectories already traversed.
	 * @returns {Promise<void>}
	 */
	async _addToFsEvents(path, transform, forceAdd, priorDepth) {
	  if (this.fsw.closed) {
	    return;
	  }
	  const opts = this.fsw.options;
	  const processPath = typeof transform === FUNCTION_TYPE ? transform : IDENTITY_FN;

	  const wh = this.fsw._getWatchHelpers(path);

	  // evaluate what is at the path we're being asked to watch
	  try {
	    const stats = await statMethods[wh.statMethod](wh.watchPath);
	    if (this.fsw.closed) return;
	    if (this.fsw._isIgnored(wh.watchPath, stats)) {
	      throw null;
	    }
	    if (stats.isDirectory()) {
	      // emit addDir unless this is a glob parent
	      if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd);

	      // don't recurse further if it would exceed depth setting
	      if (priorDepth && priorDepth > opts.depth) return;

	      // scan the contents of the dir
	      this.fsw._readdirp(wh.watchPath, {
	        fileFilter: entry => wh.filterPath(entry),
	        directoryFilter: entry => wh.filterDir(entry),
	        ...Depth(opts.depth - (priorDepth || 0))
	      }).on(STR_DATA, (entry) => {
	        // need to check filterPath on dirs b/c filterDir is less restrictive
	        if (this.fsw.closed) {
	          return;
	        }
	        if (entry.stats.isDirectory() && !wh.filterPath(entry)) return;

	        const joinedPath = sysPath.join(wh.watchPath, entry.path);
	        const {fullPath} = entry;

	        if (wh.followSymlinks && entry.stats.isSymbolicLink()) {
	          // preserve the current depth here since it can't be derived from
	          // real paths past the symlink
	          const curDepth = opts.depth === undefined ?
	            undefined : calcDepth(joinedPath, sysPath.resolve(wh.watchPath)) + 1;

	          this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth);
	        } else {
	          this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd);
	        }
	      }).on(EV_ERROR, EMPTY_FN).on(STR_END, () => {
	        this.fsw._emitReady();
	      });
	    } else {
	      this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd);
	      this.fsw._emitReady();
	    }
	  } catch (error) {
	    if (!error || this.fsw._handleError(error)) {
	      // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__-
	      this.fsw._emitReady();
	      this.fsw._emitReady();
	    }
	  }

	  if (opts.persistent && forceAdd !== true) {
	    if (typeof transform === FUNCTION_TYPE) {
	      // realpath has already been resolved
	      this.initWatch(undefined, path, wh, processPath);
	    } else {
	      let realPath;
	      try {
	        realPath = await realpath(wh.watchPath);
	      } catch (e) {}
	      this.initWatch(realPath, path, wh, processPath);
	    }
	  }
	}

	}

	fseventsHandler.exports = FsEventsHandler;
	fseventsHandler.exports.canUse = canUse;
	return fseventsHandler.exports;
}

var hasRequiredChokidar;

function requireChokidar () {
	if (hasRequiredChokidar) return chokidar;
	hasRequiredChokidar = 1;

	const { EventEmitter } = require$$0$1;
	const fs = require$$0$2;
	const sysPath = require$$1;
	const { promisify } = require$$0$5;
	const readdirp = requireReaddirp();
	const anymatch = requireAnymatch().default;
	const globParent = requireGlobParent();
	const isGlob = requireIsGlob();
	const braces = requireBraces();
	const normalizePath = requireNormalizePath();

	const NodeFsHandler = requireNodefsHandler();
	const FsEventsHandler = requireFseventsHandler();
	const {
	  EV_ALL,
	  EV_READY,
	  EV_ADD,
	  EV_CHANGE,
	  EV_UNLINK,
	  EV_ADD_DIR,
	  EV_UNLINK_DIR,
	  EV_RAW,
	  EV_ERROR,

	  STR_CLOSE,
	  STR_END,

	  BACK_SLASH_RE,
	  DOUBLE_SLASH_RE,
	  SLASH_OR_BACK_SLASH_RE,
	  DOT_RE,
	  REPLACER_RE,

	  SLASH,
	  SLASH_SLASH,
	  BRACE_START,
	  BANG,
	  ONE_DOT,
	  TWO_DOTS,
	  GLOBSTAR,
	  SLASH_GLOBSTAR,
	  ANYMATCH_OPTS,
	  STRING_TYPE,
	  FUNCTION_TYPE,
	  EMPTY_STR,
	  EMPTY_FN,

	  isWindows,
	  isMacos,
	  isIBMi
	} = requireConstants();

	const stat = promisify(fs.stat);
	const readdir = promisify(fs.readdir);

	/**
	 * @typedef {String} Path
	 * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName
	 * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType
	 */

	/**
	 *
	 * @typedef {Object} WatchHelpers
	 * @property {Boolean} followSymlinks
	 * @property {'stat'|'lstat'} statMethod
	 * @property {Path} path
	 * @property {Path} watchPath
	 * @property {Function} entryPath
	 * @property {Boolean} hasGlob
	 * @property {Object} globFilter
	 * @property {Function} filterPath
	 * @property {Function} filterDir
	 */

	const arrify = (value = []) => Array.isArray(value) ? value : [value];
	const flatten = (list, result = []) => {
	  list.forEach(item => {
	    if (Array.isArray(item)) {
	      flatten(item, result);
	    } else {
	      result.push(item);
	    }
	  });
	  return result;
	};

	const unifyPaths = (paths_) => {
	  /**
	   * @type {Array<String>}
	   */
	  const paths = flatten(arrify(paths_));
	  if (!paths.every(p => typeof p === STRING_TYPE)) {
	    throw new TypeError(`Non-string provided as watch path: ${paths}`);
	  }
	  return paths.map(normalizePathToUnix);
	};

	// If SLASH_SLASH occurs at the beginning of path, it is not replaced
	//     because "//StoragePC/DrivePool/Movies" is a valid network path
	const toUnix = (string) => {
	  let str = string.replace(BACK_SLASH_RE, SLASH);
	  let prepend = false;
	  if (str.startsWith(SLASH_SLASH)) {
	    prepend = true;
	  }
	  while (str.match(DOUBLE_SLASH_RE)) {
	    str = str.replace(DOUBLE_SLASH_RE, SLASH);
	  }
	  if (prepend) {
	    str = SLASH + str;
	  }
	  return str;
	};

	// Our version of upath.normalize
	// TODO: this is not equal to path-normalize module - investigate why
	const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path)));

	const normalizeIgnored = (cwd = EMPTY_STR) => (path) => {
	  if (typeof path !== STRING_TYPE) return path;
	  return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path));
	};

	const getAbsolutePath = (path, cwd) => {
	  if (sysPath.isAbsolute(path)) {
	    return path;
	  }
	  if (path.startsWith(BANG)) {
	    return BANG + sysPath.join(cwd, path.slice(1));
	  }
	  return sysPath.join(cwd, path);
	};

	const undef = (opts, key) => opts[key] === undefined;

	/**
	 * Directory entry.
	 * @property {Path} path
	 * @property {Set<Path>} items
	 */
	class DirEntry {
	  /**
	   * @param {Path} dir
	   * @param {Function} removeWatcher
	   */
	  constructor(dir, removeWatcher) {
	    this.path = dir;
	    this._removeWatcher = removeWatcher;
	    /** @type {Set<Path>} */
	    this.items = new Set();
	  }

	  add(item) {
	    const {items} = this;
	    if (!items) return;
	    if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item);
	  }

	  async remove(item) {
	    const {items} = this;
	    if (!items) return;
	    items.delete(item);
	    if (items.size > 0) return;

	    const dir = this.path;
	    try {
	      await readdir(dir);
	    } catch (err) {
	      if (this._removeWatcher) {
	        this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir));
	      }
	    }
	  }

	  has(item) {
	    const {items} = this;
	    if (!items) return;
	    return items.has(item);
	  }

	  /**
	   * @returns {Array<String>}
	   */
	  getChildren() {
	    const {items} = this;
	    if (!items) return;
	    return [...items.values()];
	  }

	  dispose() {
	    this.items.clear();
	    delete this.path;
	    delete this._removeWatcher;
	    delete this.items;
	    Object.freeze(this);
	  }
	}

	const STAT_METHOD_F = 'stat';
	const STAT_METHOD_L = 'lstat';
	class WatchHelper {
	  constructor(path, watchPath, follow, fsw) {
	    this.fsw = fsw;
	    this.path = path = path.replace(REPLACER_RE, EMPTY_STR);
	    this.watchPath = watchPath;
	    this.fullWatchPath = sysPath.resolve(watchPath);
	    this.hasGlob = watchPath !== path;
	    /** @type {object|boolean} */
	    if (path === EMPTY_STR) this.hasGlob = false;
	    this.globSymlink = this.hasGlob && follow ? undefined : false;
	    this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false;
	    this.dirParts = this.getDirParts(path);
	    this.dirParts.forEach((parts) => {
	      if (parts.length > 1) parts.pop();
	    });
	    this.followSymlinks = follow;
	    this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
	  }

	  checkGlobSymlink(entry) {
	    // only need to resolve once
	    // first entry should always have entry.parentDir === EMPTY_STR
	    if (this.globSymlink === undefined) {
	      this.globSymlink = entry.fullParentDir === this.fullWatchPath ?
	        false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath};
	    }

	    if (this.globSymlink) {
	      return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath);
	    }

	    return entry.fullPath;
	  }

	  entryPath(entry) {
	    return sysPath.join(this.watchPath,
	      sysPath.relative(this.watchPath, this.checkGlobSymlink(entry))
	    );
	  }

	  filterPath(entry) {
	    const {stats} = entry;
	    if (stats && stats.isSymbolicLink()) return this.filterDir(entry);
	    const resolvedPath = this.entryPath(entry);
	    const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ?
	      this.globFilter(resolvedPath) : true;
	    return matchesGlob &&
	      this.fsw._isntIgnored(resolvedPath, stats) &&
	      this.fsw._hasReadPermissions(stats);
	  }

	  getDirParts(path) {
	    if (!this.hasGlob) return [];
	    const parts = [];
	    const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path];
	    expandedPath.forEach((path) => {
	      parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE));
	    });
	    return parts;
	  }

	  filterDir(entry) {
	    if (this.hasGlob) {
	      const entryParts = this.getDirParts(this.checkGlobSymlink(entry));
	      let globstar = false;
	      this.unmatchedGlob = !this.dirParts.some((parts) => {
	        return parts.every((part, i) => {
	          if (part === GLOBSTAR) globstar = true;
	          return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS);
	        });
	      });
	    }
	    return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
	  }
	}

	/**
	 * Watches files & directories for changes. Emitted events:
	 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
	 *
	 *     new FSWatcher()
	 *       .add(directories)
	 *       .on('add', path => log('File', path, 'was added'))
	 */
	class FSWatcher extends EventEmitter {
	// Not indenting methods for history sake; for now.
	constructor(_opts) {
	  super();

	  const opts = {};
	  if (_opts) Object.assign(opts, _opts); // for frozen objects

	  /** @type {Map<String, DirEntry>} */
	  this._watched = new Map();
	  /** @type {Map<String, Array>} */
	  this._closers = new Map();
	  /** @type {Set<String>} */
	  this._ignoredPaths = new Set();

	  /** @type {Map<ThrottleType, Map>} */
	  this._throttled = new Map();

	  /** @type {Map<Path, String|Boolean>} */
	  this._symlinkPaths = new Map();

	  this._streams = new Set();
	  this.closed = false;

	  // Set up default options.
	  if (undef(opts, 'persistent')) opts.persistent = true;
	  if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false;
	  if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false;
	  if (undef(opts, 'interval')) opts.interval = 100;
	  if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300;
	  if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false;
	  opts.enableBinaryInterval = opts.binaryInterval !== opts.interval;

	  // Enable fsevents on OS X when polling isn't explicitly enabled.
	  if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling;

	  // If we can't use fsevents, ensure the options reflect it's disabled.
	  const canUseFsEvents = FsEventsHandler.canUse();
	  if (!canUseFsEvents) opts.useFsEvents = false;

	  // Use polling on Mac if not using fsevents.
	  // Other platforms use non-polling fs_watch.
	  if (undef(opts, 'usePolling') && !opts.useFsEvents) {
	    opts.usePolling = isMacos;
	  }

	  // Always default to polling on IBM i because fs.watch() is not available on IBM i.
	  if(isIBMi) {
	    opts.usePolling = true;
	  }

	  // Global override (useful for end-developers that need to force polling for all
	  // instances of chokidar, regardless of usage/dependency depth)
	  const envPoll = process.env.CHOKIDAR_USEPOLLING;
	  if (envPoll !== undefined) {
	    const envLower = envPoll.toLowerCase();

	    if (envLower === 'false' || envLower === '0') {
	      opts.usePolling = false;
	    } else if (envLower === 'true' || envLower === '1') {
	      opts.usePolling = true;
	    } else {
	      opts.usePolling = !!envLower;
	    }
	  }
	  const envInterval = process.env.CHOKIDAR_INTERVAL;
	  if (envInterval) {
	    opts.interval = Number.parseInt(envInterval, 10);
	  }

	  // Editor atomic write normalization enabled by default with fs.watch
	  if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
	  if (opts.atomic) this._pendingUnlinks = new Map();

	  if (undef(opts, 'followSymlinks')) opts.followSymlinks = true;

	  if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false;
	  if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
	  const awf = opts.awaitWriteFinish;
	  if (awf) {
	    if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
	    if (!awf.pollInterval) awf.pollInterval = 100;
	    this._pendingWrites = new Map();
	  }
	  if (opts.ignored) opts.ignored = arrify(opts.ignored);

	  let readyCalls = 0;
	  this._emitReady = () => {
	    readyCalls++;
	    if (readyCalls >= this._readyCount) {
	      this._emitReady = EMPTY_FN;
	      this._readyEmitted = true;
	      // use process.nextTick to allow time for listener to be bound
	      process.nextTick(() => this.emit(EV_READY));
	    }
	  };
	  this._emitRaw = (...args) => this.emit(EV_RAW, ...args);
	  this._readyEmitted = false;
	  this.options = opts;

	  // Initialize with proper watcher.
	  if (opts.useFsEvents) {
	    this._fsEventsHandler = new FsEventsHandler(this);
	  } else {
	    this._nodeFsHandler = new NodeFsHandler(this);
	  }

	  // You’re frozen when your heart’s not open.
	  Object.freeze(opts);
	}

	// Public methods

	/**
	 * Adds paths to be watched on an existing FSWatcher instance
	 * @param {Path|Array<Path>} paths_
	 * @param {String=} _origAdd private; for handling non-existent paths to be watched
	 * @param {Boolean=} _internal private; indicates a non-user add
	 * @returns {FSWatcher} for chaining
	 */
	add(paths_, _origAdd, _internal) {
	  const {cwd, disableGlobbing} = this.options;
	  this.closed = false;
	  let paths = unifyPaths(paths_);
	  if (cwd) {
	    paths = paths.map((path) => {
	      const absPath = getAbsolutePath(path, cwd);

	      // Check `path` instead of `absPath` because the cwd portion can't be a glob
	      if (disableGlobbing || !isGlob(path)) {
	        return absPath;
	      }
	      return normalizePath(absPath);
	    });
	  }

	  // set aside negated glob strings
	  paths = paths.filter((path) => {
	    if (path.startsWith(BANG)) {
	      this._ignoredPaths.add(path.slice(1));
	      return false;
	    }

	    // if a path is being added that was previously ignored, stop ignoring it
	    this._ignoredPaths.delete(path);
	    this._ignoredPaths.delete(path + SLASH_GLOBSTAR);

	    // reset the cached userIgnored anymatch fn
	    // to make ignoredPaths changes effective
	    this._userIgnored = undefined;

	    return true;
	  });

	  if (this.options.useFsEvents && this._fsEventsHandler) {
	    if (!this._readyCount) this._readyCount = paths.length;
	    if (this.options.persistent) this._readyCount += paths.length;
	    paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path));
	  } else {
	    if (!this._readyCount) this._readyCount = 0;
	    this._readyCount += paths.length;
	    Promise.all(
	      paths.map(async path => {
	        const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd);
	        if (res) this._emitReady();
	        return res;
	      })
	    ).then(results => {
	      if (this.closed) return;
	      results.filter(item => item).forEach(item => {
	        this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
	      });
	    });
	  }

	  return this;
	}

	/**
	 * Close watchers or start ignoring events from specified paths.
	 * @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs
	 * @returns {FSWatcher} for chaining
	*/
	unwatch(paths_) {
	  if (this.closed) return this;
	  const paths = unifyPaths(paths_);
	  const {cwd} = this.options;

	  paths.forEach((path) => {
	    // convert to absolute path unless relative path already matches
	    if (!sysPath.isAbsolute(path) && !this._closers.has(path)) {
	      if (cwd) path = sysPath.join(cwd, path);
	      path = sysPath.resolve(path);
	    }

	    this._closePath(path);

	    this._ignoredPaths.add(path);
	    if (this._watched.has(path)) {
	      this._ignoredPaths.add(path + SLASH_GLOBSTAR);
	    }

	    // reset the cached userIgnored anymatch fn
	    // to make ignoredPaths changes effective
	    this._userIgnored = undefined;
	  });

	  return this;
	}

	/**
	 * Close watchers and remove all listeners from watched paths.
	 * @returns {Promise<void>}.
	*/
	close() {
	  if (this.closed) return this._closePromise;
	  this.closed = true;

	  // Memory management.
	  this.removeAllListeners();
	  const closers = [];
	  this._closers.forEach(closerList => closerList.forEach(closer => {
	    const promise = closer();
	    if (promise instanceof Promise) closers.push(promise);
	  }));
	  this._streams.forEach(stream => stream.destroy());
	  this._userIgnored = undefined;
	  this._readyCount = 0;
	  this._readyEmitted = false;
	  this._watched.forEach(dirent => dirent.dispose());
	  ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => {
	    this[`_${key}`].clear();
	  });

	  this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve();
	  return this._closePromise;
	}

	/**
	 * Expose list of watched paths
	 * @returns {Object} for chaining
	*/
	getWatched() {
	  const watchList = {};
	  this._watched.forEach((entry, dir) => {
	    const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;
	    watchList[key || ONE_DOT] = entry.getChildren().sort();
	  });
	  return watchList;
	}

	emitWithAll(event, args) {
	  this.emit(...args);
	  if (event !== EV_ERROR) this.emit(EV_ALL, ...args);
	}

	// Common helpers
	// --------------

	/**
	 * Normalize and emit events.
	 * Calling _emit DOES NOT MEAN emit() would be called!
	 * @param {EventName} event Type of event
	 * @param {Path} path File or directory path
	 * @param {*=} val1 arguments to be passed with event
	 * @param {*=} val2
	 * @param {*=} val3
	 * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
	 */
	async _emit(event, path, val1, val2, val3) {
	  if (this.closed) return;

	  const opts = this.options;
	  if (isWindows) path = sysPath.normalize(path);
	  if (opts.cwd) path = sysPath.relative(opts.cwd, path);
	  /** @type Array<any> */
	  const args = [event, path];
	  if (val3 !== undefined) args.push(val1, val2, val3);
	  else if (val2 !== undefined) args.push(val1, val2);
	  else if (val1 !== undefined) args.push(val1);

	  const awf = opts.awaitWriteFinish;
	  let pw;
	  if (awf && (pw = this._pendingWrites.get(path))) {
	    pw.lastChange = new Date();
	    return this;
	  }

	  if (opts.atomic) {
	    if (event === EV_UNLINK) {
	      this._pendingUnlinks.set(path, args);
	      setTimeout(() => {
	        this._pendingUnlinks.forEach((entry, path) => {
	          this.emit(...entry);
	          this.emit(EV_ALL, ...entry);
	          this._pendingUnlinks.delete(path);
	        });
	      }, typeof opts.atomic === 'number' ? opts.atomic : 100);
	      return this;
	    }
	    if (event === EV_ADD && this._pendingUnlinks.has(path)) {
	      event = args[0] = EV_CHANGE;
	      this._pendingUnlinks.delete(path);
	    }
	  }

	  if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) {
	    const awfEmit = (err, stats) => {
	      if (err) {
	        event = args[0] = EV_ERROR;
	        args[1] = err;
	        this.emitWithAll(event, args);
	      } else if (stats) {
	        // if stats doesn't exist the file must have been deleted
	        if (args.length > 2) {
	          args[2] = stats;
	        } else {
	          args.push(stats);
	        }
	        this.emitWithAll(event, args);
	      }
	    };

	    this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
	    return this;
	  }

	  if (event === EV_CHANGE) {
	    const isThrottled = !this._throttle(EV_CHANGE, path, 50);
	    if (isThrottled) return this;
	  }

	  if (opts.alwaysStat && val1 === undefined &&
	    (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE)
	  ) {
	    const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path;
	    let stats;
	    try {
	      stats = await stat(fullPath);
	    } catch (err) {}
	    // Suppress event when fs_stat fails, to avoid sending undefined 'stat'
	    if (!stats || this.closed) return;
	    args.push(stats);
	  }
	  this.emitWithAll(event, args);

	  return this;
	}

	/**
	 * Common handler for errors
	 * @param {Error} error
	 * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag
	 */
	_handleError(error) {
	  const code = error && error.code;
	  if (error && code !== 'ENOENT' && code !== 'ENOTDIR' &&
	    (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES'))
	  ) {
	    this.emit(EV_ERROR, error);
	  }
	  return error || this.closed;
	}

	/**
	 * Helper utility for throttling
	 * @param {ThrottleType} actionType type being throttled
	 * @param {Path} path being acted upon
	 * @param {Number} timeout duration of time to suppress duplicate actions
	 * @returns {Object|false} tracking object or false if action should be suppressed
	 */
	_throttle(actionType, path, timeout) {
	  if (!this._throttled.has(actionType)) {
	    this._throttled.set(actionType, new Map());
	  }

	  /** @type {Map<Path, Object>} */
	  const action = this._throttled.get(actionType);
	  /** @type {Object} */
	  const actionPath = action.get(path);

	  if (actionPath) {
	    actionPath.count++;
	    return false;
	  }

	  let timeoutObject;
	  const clear = () => {
	    const item = action.get(path);
	    const count = item ? item.count : 0;
	    action.delete(path);
	    clearTimeout(timeoutObject);
	    if (item) clearTimeout(item.timeoutObject);
	    return count;
	  };
	  timeoutObject = setTimeout(clear, timeout);
	  const thr = {timeoutObject, clear, count: 0};
	  action.set(path, thr);
	  return thr;
	}

	_incrReadyCount() {
	  return this._readyCount++;
	}

	/**
	 * Awaits write operation to finish.
	 * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.
	 * @param {Path} path being acted upon
	 * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished
	 * @param {EventName} event
	 * @param {Function} awfEmit Callback to be called when ready for event to be emitted.
	 */
	_awaitWriteFinish(path, threshold, event, awfEmit) {
	  let timeoutHandler;

	  let fullPath = path;
	  if (this.options.cwd && !sysPath.isAbsolute(path)) {
	    fullPath = sysPath.join(this.options.cwd, path);
	  }

	  const now = new Date();

	  const awaitWriteFinish = (prevStat) => {
	    fs.stat(fullPath, (err, curStat) => {
	      if (err || !this._pendingWrites.has(path)) {
	        if (err && err.code !== 'ENOENT') awfEmit(err);
	        return;
	      }

	      const now = Number(new Date());

	      if (prevStat && curStat.size !== prevStat.size) {
	        this._pendingWrites.get(path).lastChange = now;
	      }
	      const pw = this._pendingWrites.get(path);
	      const df = now - pw.lastChange;

	      if (df >= threshold) {
	        this._pendingWrites.delete(path);
	        awfEmit(undefined, curStat);
	      } else {
	        timeoutHandler = setTimeout(
	          awaitWriteFinish,
	          this.options.awaitWriteFinish.pollInterval,
	          curStat
	        );
	      }
	    });
	  };

	  if (!this._pendingWrites.has(path)) {
	    this._pendingWrites.set(path, {
	      lastChange: now,
	      cancelWait: () => {
	        this._pendingWrites.delete(path);
	        clearTimeout(timeoutHandler);
	        return event;
	      }
	    });
	    timeoutHandler = setTimeout(
	      awaitWriteFinish,
	      this.options.awaitWriteFinish.pollInterval
	    );
	  }
	}

	_getGlobIgnored() {
	  return [...this._ignoredPaths.values()];
	}

	/**
	 * Determines whether user has asked to ignore this path.
	 * @param {Path} path filepath or dir
	 * @param {fs.Stats=} stats result of fs.stat
	 * @returns {Boolean}
	 */
	_isIgnored(path, stats) {
	  if (this.options.atomic && DOT_RE.test(path)) return true;
	  if (!this._userIgnored) {
	    const {cwd} = this.options;
	    const ign = this.options.ignored;

	    const ignored = ign && ign.map(normalizeIgnored(cwd));
	    const paths = arrify(ignored)
	      .filter((path) => typeof path === STRING_TYPE && !isGlob(path))
	      .map((path) => path + SLASH_GLOBSTAR);
	    const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths);
	    this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS);
	  }

	  return this._userIgnored([path, stats]);
	}

	_isntIgnored(path, stat) {
	  return !this._isIgnored(path, stat);
	}

	/**
	 * Provides a set of common helpers and properties relating to symlink and glob handling.
	 * @param {Path} path file, directory, or glob pattern being watched
	 * @param {Number=} depth at any depth > 0, this isn't a glob
	 * @returns {WatchHelper} object containing helpers for this path
	 */
	_getWatchHelpers(path, depth) {
	  const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
	  const follow = this.options.followSymlinks;

	  return new WatchHelper(path, watchPath, follow, this);
	}

	// Directory helpers
	// -----------------

	/**
	 * Provides directory tracking objects
	 * @param {String} directory path of the directory
	 * @returns {DirEntry} the directory's tracking object
	 */
	_getWatchedDir(directory) {
	  if (!this._boundRemove) this._boundRemove = this._remove.bind(this);
	  const dir = sysPath.resolve(directory);
	  if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove));
	  return this._watched.get(dir);
	}

	// File helpers
	// ------------

	/**
	 * Check for read permissions.
	 * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405
	 * @param {fs.Stats} stats - object, result of fs_stat
	 * @returns {Boolean} indicates whether the file can be read
	*/
	_hasReadPermissions(stats) {
	  if (this.options.ignorePermissionErrors) return true;

	  // stats.mode may be bigint
	  const md = stats && Number.parseInt(stats.mode, 10);
	  const st = md & 0o777;
	  const it = Number.parseInt(st.toString(8)[0], 10);
	  return Boolean(4 & it);
	}

	/**
	 * Handles emitting unlink events for
	 * files and directories, and via recursion, for
	 * files and directories within directories that are unlinked
	 * @param {String} directory within which the following item is located
	 * @param {String} item      base path of item/directory
	 * @returns {void}
	*/
	_remove(directory, item, isDirectory) {
	  // if what is being deleted is a directory, get that directory's paths
	  // for recursive deleting and cleaning of watched object
	  // if it is not a directory, nestedDirectoryChildren will be empty array
	  const path = sysPath.join(directory, item);
	  const fullPath = sysPath.resolve(path);
	  isDirectory = isDirectory != null
	    ? isDirectory
	    : this._watched.has(path) || this._watched.has(fullPath);

	  // prevent duplicate handling in case of arriving here nearly simultaneously
	  // via multiple paths (such as _handleFile and _handleDir)
	  if (!this._throttle('remove', path, 100)) return;

	  // if the only watched file is removed, watch for its return
	  if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) {
	    this.add(directory, item, true);
	  }

	  // This will create a new entry in the watched object in either case
	  // so we got to do the directory check beforehand
	  const wp = this._getWatchedDir(path);
	  const nestedDirectoryChildren = wp.getChildren();

	  // Recursively remove children directories / files.
	  nestedDirectoryChildren.forEach(nested => this._remove(path, nested));

	  // Check if item was on the watched list and remove it
	  const parent = this._getWatchedDir(directory);
	  const wasTracked = parent.has(item);
	  parent.remove(item);

	  // Fixes issue #1042 -> Relative paths were detected and added as symlinks
	  // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612),
	  // but never removed from the map in case the path was deleted.
	  // This leads to an incorrect state if the path was recreated:
	  // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553
	  if (this._symlinkPaths.has(fullPath)) {
	    this._symlinkPaths.delete(fullPath);
	  }

	  // If we wait for this file to be fully written, cancel the wait.
	  let relPath = path;
	  if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path);
	  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
	    const event = this._pendingWrites.get(relPath).cancelWait();
	    if (event === EV_ADD) return;
	  }

	  // The Entry will either be a directory that just got removed
	  // or a bogus entry to a file, in either case we have to remove it
	  this._watched.delete(path);
	  this._watched.delete(fullPath);
	  const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK;
	  if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);

	  // Avoid conflicts if we later create another file with the same name
	  if (!this.options.useFsEvents) {
	    this._closePath(path);
	  }
	}

	/**
	 * Closes all watchers for a path
	 * @param {Path} path
	 */
	_closePath(path) {
	  this._closeFile(path);
	  const dir = sysPath.dirname(path);
	  this._getWatchedDir(dir).remove(sysPath.basename(path));
	}

	/**
	 * Closes only file-specific watchers
	 * @param {Path} path
	 */
	_closeFile(path) {
	  const closers = this._closers.get(path);
	  if (!closers) return;
	  closers.forEach(closer => closer());
	  this._closers.delete(path);
	}

	/**
	 *
	 * @param {Path} path
	 * @param {Function} closer
	 */
	_addPathCloser(path, closer) {
	  if (!closer) return;
	  let list = this._closers.get(path);
	  if (!list) {
	    list = [];
	    this._closers.set(path, list);
	  }
	  list.push(closer);
	}

	_readdirp(root, opts) {
	  if (this.closed) return;
	  const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts};
	  let stream = readdirp(root, options);
	  this._streams.add(stream);
	  stream.once(STR_CLOSE, () => {
	    stream = undefined;
	  });
	  stream.once(STR_END, () => {
	    if (stream) {
	      this._streams.delete(stream);
	      stream = undefined;
	    }
	  });
	  return stream;
	}

	}

	// Export FSWatcher class
	chokidar.FSWatcher = FSWatcher;

	/**
	 * Instantiates watcher with paths to be tracked.
	 * @param {String|Array<String>} paths file/directory paths and/or globs
	 * @param {Object=} options chokidar opts
	 * @returns an instance of FSWatcher for chaining.
	 */
	const watch = (paths, options) => {
	  const watcher = new FSWatcher(options);
	  watcher.add(paths);
	  return watcher;
	};

	chokidar.watch = watch;
	return chokidar;
}

var agentCore;
var hasRequiredAgentCore;

function requireAgentCore () {
	if (hasRequiredAgentCore) return agentCore;
	hasRequiredAgentCore = 1;
	const { ProjectAnalyzer } = requireProjectAnalyzer();
	const { executeCommand } = requireSrc();
	const path = require$$1;

	class AutomatedAgent {
	  constructor(options = {}) {
	    this.options = {
	      autoFix: options.autoFix || false,
	      watchMode: options.watchMode || false,
	      aggressiveness: options.aggressiveness || "moderate", // conservative, moderate, aggressive
	      projectPath: options.projectPath || process.cwd(),
	      ...options,
	    };

	    this.analyzer = new ProjectAnalyzer(this.options.projectPath);
	    this.isRunning = false;
	    this.lastAnalysis = null;
	    this.actionHistory = [];
	  }

	  async start() {
	    console.log("[Agent] Starting automated project management...");
	    this.isRunning = true;

	    // Initial analysis
	    await this.performAnalysis();

	    // Execute initial recommendations
	    if (this.options.autoFix) {
	      await this.executeRecommendations();
	    }

	    // Start watch mode if enabled
	    if (this.options.watchMode) {
	      this.startWatching();
	    }

	    return this.lastAnalysis
	  }

	  async stop() {
	    console.log("[Agent] Stopping automated project management...");
	    this.isRunning = false;
	    if (this.watcher) {
	      this.watcher.close();
	    }
	  }

	  async performAnalysis() {
	    console.log("[Agent] Performing project analysis...");
	    this.lastAnalysis = await this.analyzer.analyzeProject();

	    const summary = this.analyzer.getAnalysisSummary();
	    console.log(`[Agent] Analysis complete - Health: ${summary.healthStatus} (${summary.healthScore}/100)`);
	    console.log(`[Agent] Found ${summary.issuesCount} issues and ${summary.recommendationsCount} recommendations`);

	    return this.lastAnalysis
	  }

	  async executeRecommendations() {
	    if (!this.lastAnalysis || !this.options.autoFix) {
	      return
	    }

	    console.log("[Agent] Executing automated fixes...");

	    for (const issue of this.lastAnalysis.issues) {
	      if (this.shouldAutoFix(issue)) {
	        await this.executeAutoFix(issue);
	      }
	    }

	    for (const recommendation of this.lastAnalysis.recommendations) {
	      if (this.shouldExecuteRecommendation(recommendation)) {
	        await this.executeRecommendation(recommendation);
	      }
	    }
	  }

	  shouldAutoFix(issue) {
	    const { aggressiveness } = this.options;

	    // Conservative: only fix critical errors
	    if (aggressiveness === "conservative") {
	      return issue.severity === "high" && issue.type === "error"
	    }

	    // Moderate: fix errors and important warnings
	    if (aggressiveness === "moderate") {
	      return issue.severity === "high" || (issue.severity === "medium" && issue.type === "error")
	    }

	    // Aggressive: fix most issues
	    if (aggressiveness === "aggressive") {
	      return issue.severity !== "low"
	    }

	    return false
	  }

	  shouldExecuteRecommendation(recommendation) {
	    const { aggressiveness } = this.options;

	    // Conservative: only security fixes
	    if (aggressiveness === "conservative") {
	      return recommendation.type === "security"
	    }

	    // Moderate: security and performance
	    if (aggressiveness === "moderate") {
	      return ["security", "performance"].includes(recommendation.type)
	    }

	    // Aggressive: all recommendations except workflow changes
	    if (aggressiveness === "aggressive") {
	      return recommendation.type !== "workflow"
	    }

	    return false
	  }

	  async executeAutoFix(issue) {
	    if (!issue.fix) return

	    console.log(`[Agent] Auto-fixing: ${issue.message}`);

	    try {
	      // Parse and execute the fix command
	      const command = issue.fix.match(/"([^"]+)"/)?.[1] || issue.fix;

	      if (
	        command.startsWith("bpack ") ||
	        command.startsWith("npm ") ||
	        command.startsWith("yarn ") ||
	        command.startsWith("pnpm ")
	      ) {
	        // Execute package management commands
	        const parts = command.split(" ");
	        const cmd = parts[0];
	        const args = parts.slice(1);

	        if (cmd === "bpack") {
	          // Use our own CLI
	          const { runCli } = requireSrc();
	          process.argv = ["node", "bpack", ...args];
	          await runCli();
	        } else {
	          // Execute external command
	          executeCommand(cmd, args);
	        }

	        this.actionHistory.push({
	          timestamp: new Date(),
	          action: "auto-fix",
	          issue: issue.message,
	          command: command,
	          status: "success",
	        });
	      }
	    } catch (error) {
	      console.error(`[Agent] Failed to auto-fix: ${issue.message}`, error.message);
	      this.actionHistory.push({
	        timestamp: new Date(),
	        action: "auto-fix",
	        issue: issue.message,
	        command: issue.fix,
	        status: "failed",
	        error: error.message,
	      });
	    }
	  }

	  async executeRecommendation(recommendation) {
	    console.log(`[Agent] Executing recommendation: ${recommendation.message}`);

	    try {
	      // Parse and execute the recommendation action
	      const command = recommendation.action.match(/"([^"]+)"/)?.[1] || recommendation.action;

	      if (command.startsWith("Run ")) {
	        const actualCommand = command.replace("Run ", "").replace(/"/g, "");
	        const parts = actualCommand.split(" ");
	        const cmd = parts[0];
	        const args = parts.slice(1);

	        if (cmd === "bpack") {
	          const { runCli } = requireSrc();
	          process.argv = ["node", "bpack", ...args];
	          await runCli();
	        } else {
	          executeCommand(cmd, args);
	        }

	        this.actionHistory.push({
	          timestamp: new Date(),
	          action: "recommendation",
	          type: recommendation.type,
	          message: recommendation.message,
	          command: actualCommand,
	          status: "success",
	        });
	      }
	    } catch (error) {
	      console.error(`[Agent] Failed to execute recommendation: ${recommendation.message}`, error.message);
	      this.actionHistory.push({
	        timestamp: new Date(),
	        action: "recommendation",
	        type: recommendation.type,
	        message: recommendation.message,
	        command: recommendation.action,
	        status: "failed",
	        error: error.message,
	      });
	    }
	  }

	  startWatching() {
	    console.log("[Agent] Starting file system monitoring...");

	    const chokidar = requireChokidar();
	    const watchPaths = [
	      path.join(this.options.projectPath, "package.json"),
	      path.join(this.options.projectPath, "package-lock.json"),
	      path.join(this.options.projectPath, "yarn.lock"),
	      path.join(this.options.projectPath, "pnpm-lock.yaml"),
	      path.join(this.options.projectPath, "bun.lockb"),
	    ];

	    this.watcher = chokidar.watch(watchPaths, {
	      ignored: /node_modules/,
	      persistent: true,
	    });

	    this.watcher.on("change", async (filePath) => {
	      console.log(`[Agent] Detected change in ${path.basename(filePath)}`);

	      // Debounce rapid changes
	      clearTimeout(this.watchTimeout);
	      this.watchTimeout = setTimeout(async () => {
	        await this.performAnalysis();
	        if (this.options.autoFix) {
	          await this.executeRecommendations();
	        }
	      }, 2000);
	    });
	  }

	  getStatus() {
	    return {
	      isRunning: this.isRunning,
	      lastAnalysis: this.lastAnalysis ? this.analyzer.getAnalysisSummary() : null,
	      actionHistory: this.actionHistory.slice(-10), // Last 10 actions
	      options: this.options,
	    }
	  }

	  async generateReport() {
	    if (!this.lastAnalysis) {
	      await this.performAnalysis();
	    }

	    const report = {
	      timestamp: new Date(),
	      project: {
	        path: this.options.projectPath,
	        type: this.lastAnalysis.structure.projectType,
	        frameworks: this.lastAnalysis.structure.frameworks,
	        buildTools: this.lastAnalysis.structure.buildTools,
	      },
	      health: this.lastAnalysis.health,
	      dependencies: {
	        total: this.lastAnalysis.dependencies.total,
	        outdated: this.lastAnalysis.dependencies.outdated.length,
	        vulnerable: this.lastAnalysis.dependencies.vulnerable.length,
	      },
	      issues: this.lastAnalysis.issues,
	      recommendations: this.lastAnalysis.recommendations,
	      actions: this.actionHistory,
	    };

	    return report
	  }
	}

	agentCore = { AutomatedAgent };
	return agentCore;
}

var aiDecisionEngine;
var hasRequiredAiDecisionEngine;

function requireAiDecisionEngine () {
	if (hasRequiredAiDecisionEngine) return aiDecisionEngine;
	hasRequiredAiDecisionEngine = 1;
	const fs = require$$0$2;
	const path = require$$1;

	class AIDecisionEngine {
	  constructor(options = {}) {
	    this.options = {
	      learningEnabled: options.learningEnabled !== false,
	      riskTolerance: options.riskTolerance || "medium", // low, medium, high
	      contextWindow: options.contextWindow || 10, // Number of past decisions to consider
	      ...options,
	    };

	    this.decisionHistory = [];
	    this.learningData = this.loadLearningData();
	    this.ruleEngine = new ProjectRuleEngine();
	  }

	  async makeDecision(analysisData, context = {}) {
	    console.log("[AI] Analyzing project state and making decisions...");

	    const decision = {
	      timestamp: new Date(),
	      context: context,
	      analysis: this.summarizeAnalysis(analysisData),
	      recommendations: [],
	      reasoning: [],
	      confidence: 0,
	      riskLevel: "unknown",
	    };

	    // Apply rule-based reasoning
	    const ruleBasedDecisions = this.ruleEngine.evaluate(analysisData, context);
	    decision.recommendations.push(...ruleBasedDecisions);

	    // Apply pattern-based learning
	    const learnedDecisions = this.applyLearning(analysisData, context);
	    decision.recommendations.push(...learnedDecisions);

	    // Prioritize and filter recommendations
	    decision.recommendations = this.prioritizeRecommendations(decision.recommendations, analysisData);

	    // Calculate confidence and risk
	    decision.confidence = this.calculateConfidence(decision.recommendations, analysisData);
	    decision.riskLevel = this.assessRisk(decision.recommendations, analysisData);

	    // Generate reasoning explanations
	    decision.reasoning = this.generateReasoning(decision.recommendations, analysisData);

	    // Store decision for learning
	    this.decisionHistory.push(decision);
	    if (this.options.learningEnabled) {
	      this.updateLearningData(decision);
	    }

	    return decision
	  }

	  summarizeAnalysis(analysisData) {
	    return {
	      healthScore: analysisData.health?.score || 0,
	      healthStatus: analysisData.health?.status || "unknown",
	      issueCount: analysisData.issues?.length || 0,
	      criticalIssues: analysisData.issues?.filter((i) => i.severity === "high").length || 0,
	      dependencyCount: analysisData.dependencies?.total || 0,
	      outdatedCount: analysisData.dependencies?.outdated?.length || 0,
	      vulnerableCount: analysisData.dependencies?.vulnerable?.length || 0,
	      projectType: analysisData.structure?.projectType || "unknown",
	      frameworks: analysisData.structure?.frameworks || [],
	    }
	  }

	  prioritizeRecommendations(recommendations, analysisData) {
	    // Score each recommendation based on impact, urgency, and risk
	    const scoredRecommendations = recommendations.map((rec) => {
	      const score = this.scoreRecommendation(rec, analysisData);
	      return { ...rec, priority: score.priority, score: score.total }
	    });

	    // Sort by score (highest first) and filter based on risk tolerance
	    return scoredRecommendations
	      .sort((a, b) => b.score - a.score)
	      .filter((rec) => this.isAcceptableRisk(rec, analysisData))
	      .slice(0, 10) // Limit to top 10 recommendations
	  }

	  scoreRecommendation(recommendation, analysisData) {
	    let impact = 0;
	    let urgency = 0;
	    let feasibility = 0;
	    let risk = 0;

	    // Score based on recommendation type
	    switch (recommendation.type) {
	      case "security":
	        impact = 10;
	        urgency = 10;
	        feasibility = 8;
	        risk = 2;
	        break
	      case "performance":
	        impact = 7;
	        urgency = 5;
	        feasibility = 6;
	        risk = 3;
	        break
	      case "maintenance":
	        impact = 5;
	        urgency = 3;
	        feasibility = 8;
	        risk = 2;
	        break
	      case "workflow":
	        impact = 4;
	        urgency = 2;
	        feasibility = 9;
	        risk = 1;
	        break
	      default:
	        impact = 3;
	        urgency = 3;
	        feasibility = 5;
	        risk = 5;
	    }

	    // Adjust based on project health
	    if (analysisData.health?.score < 50) {
	      urgency += 3;
	      impact += 2;
	    }

	    // Adjust based on issue severity
	    if (recommendation.severity === "high") {
	      urgency += 4;
	      impact += 3;
	    } else if (recommendation.severity === "medium") {
	      urgency += 2;
	      impact += 1;
	    }

	    const total = impact * 0.4 + urgency * 0.3 + feasibility * 0.2 - risk * 0.1;

	    let priority = "low";
	    if (total >= 8) priority = "critical";
	    else if (total >= 6) priority = "high";
	    else if (total >= 4) priority = "medium";

	    return { impact, urgency, feasibility, risk, total, priority }
	  }

	  isAcceptableRisk(recommendation, analysisData) {
	    const riskLevel = recommendation.risk || this.assessRecommendationRisk(recommendation);

	    switch (this.options.riskTolerance) {
	      case "low":
	        return riskLevel <= 2
	      case "medium":
	        return riskLevel <= 5
	      case "high":
	        return riskLevel <= 8
	      default:
	        return true
	    }
	  }

	  assessRecommendationRisk(recommendation) {
	    // Assess risk based on action type and project state
	    const action = recommendation.action || "";

	    if (action.includes("remove") || action.includes("delete")) return 8
	    if (action.includes("update") && action.includes("major")) return 7
	    if (action.includes("install") && recommendation.type === "security") return 3
	    if (action.includes("audit --fix")) return 4
	    if (action.includes("update")) return 5
	    if (action.includes("install")) return 3

	    return 2 // Default low risk
	  }

	  calculateConfidence(recommendations, analysisData) {
	    if (recommendations.length === 0) return 0

	    let totalConfidence = 0;
	    let factors = 0;

	    // Base confidence on data quality
	    if (analysisData.structure?.hasPackageJson) {
	      totalConfidence += 20;
	      factors++;
	    }

	    if (analysisData.structure?.hasLockfile) {
	      totalConfidence += 15;
	      factors++;
	    }

	    // Confidence based on issue clarity
	    const clearIssues = analysisData.issues?.filter((i) => i.fix).length || 0;
	    if (clearIssues > 0) {
	      totalConfidence += Math.min(30, clearIssues * 5);
	      factors++;
	    }

	    // Confidence based on learning history
	    const similarDecisions = this.findSimilarDecisions(analysisData);
	    if (similarDecisions.length > 0) {
	      const successRate = similarDecisions.filter((d) => d.outcome === "success").length / similarDecisions.length;
	      totalConfidence += successRate * 25;
	      factors++;
	    }

	    // Confidence based on recommendation consensus
	    const consensusScore = this.calculateConsensus(recommendations);
	    totalConfidence += consensusScore * 10;
	    factors++;

	    return factors > 0 ? Math.min(100, totalConfidence / factors) : 50
	  }

	  assessRisk(recommendations, analysisData) {
	    const riskScores = recommendations.map((rec) => this.assessRecommendationRisk(rec));
	    const avgRisk = riskScores.reduce((sum, risk) => sum + risk, 0) / riskScores.length;

	    if (avgRisk >= 7) return "high"
	    if (avgRisk >= 4) return "medium"
	    return "low"
	  }

	  generateReasoning(recommendations, analysisData) {
	    const reasoning = [];

	    // Health-based reasoning
	    if (analysisData.health?.score < 60) {
	      reasoning.push({
	        factor: "health",
	        explanation: `Project health score is ${analysisData.health.score}/100, indicating need for immediate attention`,
	        impact: "high",
	      });
	    }

	    // Security-based reasoning
	    const securityRecs = recommendations.filter((r) => r.type === "security");
	    if (securityRecs.length > 0) {
	      reasoning.push({
	        factor: "security",
	        explanation: `${securityRecs.length} security-related recommendations require immediate action`,
	        impact: "critical",
	      });
	    }

	    // Dependency-based reasoning
	    if (analysisData.dependencies?.outdated?.length > 5) {
	      reasoning.push({
	        factor: "maintenance",
	        explanation: `${analysisData.dependencies.outdated.length} outdated dependencies may cause compatibility issues`,
	        impact: "medium",
	      });
	    }

	    // Pattern-based reasoning from learning
	    const patterns = this.identifyPatterns(analysisData);
	    patterns.forEach((pattern) => {
	      reasoning.push({
	        factor: "pattern",
	        explanation: pattern.explanation,
	        impact: pattern.impact,
	        confidence: pattern.confidence,
	      });
	    });

	    return reasoning
	  }

	  applyLearning(analysisData, context) {
	    if (!this.options.learningEnabled || this.learningData.patterns.length === 0) {
	      return []
	    }

	    const recommendations = [];
	    const currentState = this.summarizeAnalysis(analysisData);

	    // Find matching patterns
	    for (const pattern of this.learningData.patterns) {
	      if (this.matchesPattern(currentState, pattern.conditions)) {
	        const confidence = pattern.successRate * pattern.frequency;

	        if (confidence > 0.6) {
	          // Only apply high-confidence patterns
	          recommendations.push({
	            type: "learned",
	            action: pattern.action,
	            message: `Based on similar projects: ${pattern.description}`,
	            confidence: confidence,
	            source: "learning",
	            pattern: pattern.id,
	          });
	        }
	      }
	    }

	    return recommendations
	  }

	  matchesPattern(currentState, conditions) {
	    for (const [key, value] of Object.entries(conditions)) {
	      if (typeof value === "object" && value.range) {
	        const current = currentState[key] || 0;
	        if (current < value.range.min || current > value.range.max) {
	          return false
	        }
	      } else if (currentState[key] !== value) {
	        return false
	      }
	    }
	    return true
	  }

	  identifyPatterns(analysisData) {
	    const patterns = [];
	    const state = this.summarizeAnalysis(analysisData);

	    // Common patterns based on project type and state
	    if (state.projectType === "react" && state.outdatedCount > 3) {
	      patterns.push({
	        explanation: "React projects with multiple outdated dependencies often benefit from gradual updates",
	        impact: "medium",
	        confidence: 0.8,
	      });
	    }

	    if (state.healthScore < 50 && state.criticalIssues > 2) {
	      patterns.push({
	        explanation: "Projects with low health scores and multiple critical issues require systematic fixing",
	        impact: "high",
	        confidence: 0.9,
	      });
	    }

	    return patterns
	  }

	  findSimilarDecisions(analysisData) {
	    const currentState = this.summarizeAnalysis(analysisData);

	    return this.decisionHistory.filter((decision) => {
	      const pastState = decision.analysis;

	      // Consider decisions similar if they match on key factors
	      return (
	        Math.abs(pastState.healthScore - currentState.healthScore) < 20 &&
	        pastState.projectType === currentState.projectType &&
	        Math.abs(pastState.issueCount - currentState.issueCount) < 3
	      )
	    })
	  }

	  calculateConsensus(recommendations) {
	    // Calculate how much the recommendations agree with each other
	    const types = recommendations.map((r) => r.type);
	    const uniqueTypes = [...new Set(types)];

	    // Higher consensus when recommendations are focused on fewer areas
	    return Math.max(0, 1 - uniqueTypes.length / types.length)
	  }

	  updateLearningData(decision) {
	    // This would be called after actions are executed to learn from outcomes
	    // For now, we'll simulate learning by storing patterns

	    const pattern = {
	      id: `pattern_${Date.now()}`,
	      conditions: decision.analysis,
	      action: decision.recommendations[0]?.action || "no-action",
	      description: decision.recommendations[0]?.message || "No action taken",
	      successRate: 0.5, // Would be updated based on actual outcomes
	      frequency: 1,
	      lastSeen: new Date(),
	    };

	    this.learningData.patterns.push(pattern);
	    this.saveLearningData();
	  }

	  loadLearningData() {
	    const learningPath = path.join(__dirname, "../../data/learning.json");

	    try {
	      if (fs.existsSync(learningPath)) {
	        return JSON.parse(fs.readFileSync(learningPath, "utf8"))
	      }
	    } catch (error) {
	      console.log("[AI] Could not load learning data:", error.message);
	    }

	    return {
	      patterns: [],
	      outcomes: [],
	      version: "1.0",
	    }
	  }

	  saveLearningData() {
	    const learningPath = path.join(__dirname, "../../data/learning.json");
	    const dataDir = path.dirname(learningPath);

	    try {
	      if (!fs.existsSync(dataDir)) {
	        fs.mkdirSync(dataDir, { recursive: true });
	      }

	      fs.writeFileSync(learningPath, JSON.stringify(this.learningData, null, 2));
	    } catch (error) {
	      console.log("[AI] Could not save learning data:", error.message);
	    }
	  }

	  explainDecision(decision) {
	    console.log("\n=== AI Decision Explanation ===");
	    console.log(`Confidence: ${decision.confidence.toFixed(1)}%`);
	    console.log(`Risk Level: ${decision.riskLevel}`);
	    console.log(`Recommendations: ${decision.recommendations.length}`);

	    console.log("\nReasoning:");
	    decision.reasoning.forEach((reason, index) => {
	      console.log(`${index + 1}. [${reason.factor.toUpperCase()}] ${reason.explanation}`);
	    });

	    console.log("\nTop Recommendations:");
	    decision.recommendations.slice(0, 5).forEach((rec, index) => {
	      console.log(`${index + 1}. [${rec.priority?.toUpperCase() || "MEDIUM"}] ${rec.message}`);
	      if (rec.action) {
	        console.log(`   Action: ${rec.action}`);
	      }
	    });
	  }
	}

	class ProjectRuleEngine {
	  constructor() {
	    this.rules = this.initializeRules();
	  }

	  initializeRules() {
	    return [
	      {
	        id: "critical-security",
	        condition: (analysis) => analysis.dependencies?.vulnerable?.length > 0,
	        action: (analysis) => ({
	          type: "security",
	          priority: "critical",
	          message: `${analysis.dependencies.vulnerable.length} security vulnerabilities detected`,
	          action: "bpack audit --fix",
	          severity: "high",
	        }),
	      },
	      {
	        id: "missing-dependencies",
	        condition: (analysis) => !analysis.structure?.hasNodeModules && analysis.dependencies?.total > 0,
	        action: (analysis) => ({
	          type: "setup",
	          priority: "high",
	          message: "Dependencies not installed",
	          action: "bpack install",
	          severity: "high",
	        }),
	      },
	      {
	        id: "outdated-dependencies",
	        condition: (analysis) => analysis.dependencies?.outdated?.length > 5,
	        action: (analysis) => ({
	          type: "maintenance",
	          priority: "medium",
	          message: `${analysis.dependencies.outdated.length} outdated dependencies`,
	          action: "bpack update",
	          severity: "medium",
	        }),
	      },
	      {
	        id: "no-lockfile",
	        condition: (analysis) => !analysis.structure?.hasLockfile && analysis.structure?.hasPackageJson,
	        action: (analysis) => ({
	          type: "setup",
	          priority: "medium",
	          message: "No lockfile found - dependency versions not locked",
	          action: "bpack install",
	          severity: "medium",
	        }),
	      },
	      {
	        id: "health-critical",
	        condition: (analysis) => analysis.health?.score < 40,
	        action: (analysis) => ({
	          type: "health",
	          priority: "critical",
	          message: `Project health is critical (${analysis.health.score}/100)`,
	          action: "bpack agent analyze --verbose",
	          severity: "high",
	        }),
	      },
	    ]
	  }

	  evaluate(analysisData, context) {
	    const recommendations = [];

	    for (const rule of this.rules) {
	      if (rule.condition(analysisData)) {
	        const recommendation = rule.action(analysisData);
	        recommendation.ruleId = rule.id;
	        recommendation.source = "rule-engine";
	        recommendations.push(recommendation);
	      }
	    }

	    return recommendations
	  }
	}

	aiDecisionEngine = { AIDecisionEngine, ProjectRuleEngine };
	return aiDecisionEngine;
}

var smartAgent;
var hasRequiredSmartAgent;

function requireSmartAgent () {
	if (hasRequiredSmartAgent) return smartAgent;
	hasRequiredSmartAgent = 1;
	const { AutomatedAgent } = requireAgentCore();
	const { AIDecisionEngine } = requireAiDecisionEngine();

	class SmartAutomatedAgent extends AutomatedAgent {
	  constructor(options = {}) {
	    super(options);

	    this.aiEngine = new AIDecisionEngine({
	      learningEnabled: options.learningEnabled !== false,
	      riskTolerance: options.riskTolerance || "medium",
	      ...options,
	    });

	    this.smartMode = options.smartMode !== false;
	    this.explainDecisions = options.explainDecisions || false;
	  }

	  async performAnalysis() {
	    console.log("[Smart Agent] Performing intelligent project analysis...");

	    // Get base analysis
	    this.lastAnalysis = await this.analyzer.analyzeProject();

	    // Apply AI decision making if smart mode is enabled
	    if (this.smartMode) {
	      const context = {
	        previousActions: this.actionHistory.slice(-5),
	        agentOptions: this.options,
	        timestamp: new Date(),
	      };

	      this.lastDecision = await this.aiEngine.makeDecision(this.lastAnalysis, context);

	      if (this.explainDecisions) {
	        this.aiEngine.explainDecision(this.lastDecision);
	      }

	      // Override recommendations with AI decisions
	      this.lastAnalysis.aiRecommendations = this.lastDecision.recommendations;
	      this.lastAnalysis.aiReasoning = this.lastDecision.reasoning;
	      this.lastAnalysis.aiConfidence = this.lastDecision.confidence;
	    }

	    const summary = this.analyzer.getAnalysisSummary();
	    console.log(`[Smart Agent] Analysis complete - Health: ${summary.healthStatus} (${summary.healthScore}/100)`);

	    if (this.smartMode && this.lastDecision) {
	      console.log(
	        `[Smart Agent] AI Confidence: ${this.lastDecision.confidence.toFixed(1)}% | Risk: ${this.lastDecision.riskLevel}`,
	      );
	      console.log(`[Smart Agent] Generated ${this.lastDecision.recommendations.length} intelligent recommendations`);
	    }

	    return this.lastAnalysis
	  }

	  async executeRecommendations() {
	    if (!this.lastAnalysis || !this.options.autoFix) {
	      return
	    }

	    console.log("[Smart Agent] Executing AI-powered recommendations...");

	    // Use AI recommendations if available, otherwise fall back to base recommendations
	    const recommendations = this.lastAnalysis.aiRecommendations || this.lastAnalysis.recommendations;

	    for (const recommendation of recommendations) {
	      if (this.shouldExecuteSmartRecommendation(recommendation)) {
	        await this.executeSmartRecommendation(recommendation);
	      }
	    }

	    // Update AI learning based on execution results
	    if (this.smartMode && this.lastDecision) {
	      await this.updateAILearning();
	    }
	  }

	  shouldExecuteSmartRecommendation(recommendation) {
	    // Enhanced decision making using AI confidence and risk assessment
	    if (!this.smartMode) {
	      return super.shouldExecuteRecommendation(recommendation)
	    }

	    const { aggressiveness } = this.options;
	    const confidence = this.lastDecision?.confidence || 50;
	    const riskLevel = this.lastDecision?.riskLevel || "medium";

	    // Don't execute if confidence is too low
	    if (confidence < 60 && aggressiveness !== "aggressive") {
	      console.log(`[Smart Agent] Skipping recommendation due to low confidence: ${confidence.toFixed(1)}%`);
	      return false
	    }

	    // Consider risk level
	    if (riskLevel === "high" && aggressiveness === "conservative") {
	      console.log(`[Smart Agent] Skipping high-risk recommendation in conservative mode`);
	      return false
	    }

	    // Priority-based execution
	    if (recommendation.priority === "critical") return true
	    if (recommendation.priority === "high" && aggressiveness !== "conservative") return true
	    if (recommendation.priority === "medium" && aggressiveness === "aggressive") return true

	    return false
	  }

	  async executeSmartRecommendation(recommendation) {
	    console.log(`[Smart Agent] Executing AI recommendation: ${recommendation.message}`);
	    console.log(`[Smart Agent] Priority: ${recommendation.priority} | Source: ${recommendation.source}`);

	    try {
	      // Execute the recommendation
	      await this.executeRecommendation(recommendation);

	      // Record successful execution
	      this.actionHistory.push({
	        timestamp: new Date(),
	        action: "smart-recommendation",
	        recommendation: recommendation,
	        status: "success",
	        aiConfidence: this.lastDecision?.confidence,
	        riskLevel: this.lastDecision?.riskLevel,
	      });
	    } catch (error) {
	      console.error(`[Smart Agent] Failed to execute recommendation: ${recommendation.message}`, error.message);

	      // Record failed execution for learning
	      this.actionHistory.push({
	        timestamp: new Date(),
	        action: "smart-recommendation",
	        recommendation: recommendation,
	        status: "failed",
	        error: error.message,
	        aiConfidence: this.lastDecision?.confidence,
	        riskLevel: this.lastDecision?.riskLevel,
	      });
	    }
	  }

	  async updateAILearning() {
	    // Update AI learning based on execution outcomes
	    const recentActions = this.actionHistory.slice(-5);
	    const successfulActions = recentActions.filter((a) => a.status === "success").length;
	    const successRate = recentActions.length > 0 ? successfulActions / recentActions.length : 0.5;

	    console.log(`[Smart Agent] Updating AI learning - Recent success rate: ${(successRate * 100).toFixed(1)}%`);

	    // This would feed back into the AI engine's learning system
	    // For now, we'll just log the learning update
	  }

	  getSmartStatus() {
	    const baseStatus = super.getStatus();

	    return {
	      ...baseStatus,
	      smartMode: this.smartMode,
	      aiEngine: {
	        enabled: this.smartMode,
	        lastDecision: this.lastDecision
	          ? {
	              confidence: this.lastDecision.confidence,
	              riskLevel: this.lastDecision.riskLevel,
	              recommendationCount: this.lastDecision.recommendations.length,
	              timestamp: this.lastDecision.timestamp,
	            }
	          : null,
	        learningEnabled: this.aiEngine.options.learningEnabled,
	        riskTolerance: this.aiEngine.options.riskTolerance,
	      },
	    }
	  }

	  async generateSmartReport() {
	    const baseReport = await super.generateReport();

	    if (this.smartMode && this.lastDecision) {
	      baseReport.aiDecision = {
	        confidence: this.lastDecision.confidence,
	        riskLevel: this.lastDecision.riskLevel,
	        reasoning: this.lastDecision.reasoning,
	        recommendations: this.lastDecision.recommendations.map((rec) => ({
	          type: rec.type,
	          priority: rec.priority,
	          message: rec.message,
	          source: rec.source,
	        })),
	      };
	    }

	    return baseReport
	  }
	}

	smartAgent = { SmartAutomatedAgent };
	return smartAgent;
}

var interactiveBuilder;
var hasRequiredInteractiveBuilder;

function requireInteractiveBuilder () {
	if (hasRequiredInteractiveBuilder) return interactiveBuilder;
	hasRequiredInteractiveBuilder = 1;
	const readline = require$$0$8;
	const fs = require$$0$2;
	const path = require$$1;
	const { spawn, spawnSync } = require$$2$2;
	const { ProjectAnalyzer } = requireProjectAnalyzer();
	const { SmartAgent } = requireSmartAgent();

	class InteractiveProjectBuilder {
	  constructor() {
	    this.rl = readline.createInterface({
	      input: process.stdin,
	      output: process.stdout,
	    });
	    this.analyzer = new ProjectAnalyzer();
	    this.agent = new SmartAgent();
	    this.projectConfig = {
	      name: "",
	      type: "",
	      framework: "",
	      features: [],
	      dependencies: [],
	      structure: {},
	    };
	  }

	  async start() {
	    console.log("\nšŸš€ Welcome to BetterPack Interactive Project Builder!");
	    console.log("I'll help you create and manage your project using natural language.\n");

	    await this.gatherProjectInfo();
	    await this.analyzeAndSetup();
	    await this.enterInteractiveMode();
	  }

	  async gatherProjectInfo() {
	    console.log("Let's start by understanding what you want to build...\n");

	    this.projectConfig.name = await this.ask("What's your project name? ");

	    const projectType = await this.ask("What type of project? (web app, api, cli tool, library, mobile app, etc.) ");
	    this.projectConfig.type = projectType.toLowerCase();

	    const description = await this.ask("Describe your project in a few sentences: ");
	    this.projectConfig.description = description;

	    // AI-powered framework recommendation
	    const recommendation = await this.getFrameworkRecommendation(projectType, description);
	    console.log(`\nšŸ¤– Based on your description, I recommend: ${recommendation.framework}`);
	    console.log(`Reason: ${recommendation.reason}\n`);

	    const useRecommended = await this.ask(`Use ${recommendation.framework}? (y/n) `);
	    if (useRecommended.toLowerCase().startsWith("y")) {
	      this.projectConfig.framework = recommendation.framework;
	    } else {
	      this.projectConfig.framework = await this.ask("Which framework would you prefer? ");
	    }

	    const features = await this.ask("What features do you need? (authentication, database, api, testing, etc.) ");
	    this.projectConfig.features = features.split(",").map((f) => f.trim());
	  }

	  async getFrameworkRecommendation(projectType, description) {
	    const recommendations = {
	      "web app": {
	        framework: "Next.js",
	        reason: "Full-stack React framework with SSR, API routes, and excellent developer experience",
	      },
	      api: {
	        framework: "Express.js",
	        reason: "Lightweight and flexible Node.js framework perfect for REST APIs",
	      },
	      "cli tool": {
	        framework: "Node.js with Commander.js",
	        reason: "Native Node.js with command-line parsing library for robust CLI tools",
	      },
	      library: {
	        framework: "TypeScript with Rollup",
	        reason: "Type-safe development with optimized bundling for library distribution",
	      },
	      "mobile app": {
	        framework: "React Native",
	        reason: "Cross-platform mobile development with React",
	      },
	    };

	    // Simple keyword-based enhancement
	    if (description.includes("react") || description.includes("component")) {
	      return {
	        framework: "Next.js",
	        reason: "React-based framework detected from description",
	      }
	    }

	    if (description.includes("vue")) {
	      return {
	        framework: "Nuxt.js",
	        reason: "Vue.js framework detected from description",
	      }
	    }

	    return (
	      recommendations[projectType] || {
	        framework: "Next.js",
	        reason: "Versatile full-stack framework suitable for most projects",
	      }
	    )
	  }

	  async analyzeAndSetup() {
	    console.log("\nšŸ“Š Analyzing project requirements...");

	    // Generate project structure
	    const structure = this.generateProjectStructure();
	    this.projectConfig.structure = structure;

	    // Determine dependencies
	    const dependencies = this.determineDependencies();
	    this.projectConfig.dependencies = dependencies;

	    console.log("\nšŸ“‹ Project Plan:");
	    console.log(`Name: ${this.projectConfig.name}`);
	    console.log(`Framework: ${this.projectConfig.framework}`);
	    console.log(`Features: ${this.projectConfig.features.join(", ")}`);
	    console.log(`Dependencies: ${dependencies.join(", ")}`);

	    const proceed = await this.ask("\nProceed with project creation? (y/n) ");
	    if (proceed.toLowerCase().startsWith("y")) {
	      await this.createProject();
	    }
	  }

	  generateProjectStructure() {
	    const framework = this.projectConfig.framework.toLowerCase();

	    if (framework.includes("next")) {
	      return {
	        "app/": "Next.js app directory",
	        "components/": "React components",
	        "lib/": "Utility functions",
	        "public/": "Static assets",
	        "styles/": "CSS and styling files",
	      }
	    } else if (framework.includes("express")) {
	      return {
	        "src/": "Source code",
	        "routes/": "API routes",
	        "middleware/": "Express middleware",
	        "models/": "Data models",
	        "config/": "Configuration files",
	      }
	    } else {
	      return {
	        "src/": "Source code",
	        "dist/": "Build output",
	        "tests/": "Test files",
	        "docs/": "Documentation",
	      }
	    }
	  }

	  determineDependencies() {
	    const deps = [];
	    const framework = this.projectConfig.framework.toLowerCase();

	    // Framework dependencies
	    if (framework.includes("next")) {
	      deps.push("next", "react", "react-dom");
	    } else if (framework.includes("express")) {
	      deps.push("express", "cors", "helmet");
	    } else if (framework.includes("commander")) {
	      deps.push("commander", "chalk", "inquirer");
	    }

	    // Feature-based dependencies
	    this.projectConfig.features.forEach((feature) => {
	      const f = feature.toLowerCase();
	      if (f.includes("auth")) deps.push("jsonwebtoken", "bcrypt");
	      if (f.includes("database")) deps.push("mongoose", "prisma");
	      if (f.includes("test")) deps.push("jest", "supertest");
	      if (f.includes("typescript")) deps.push("typescript", "@types/node");
	    });

	    return [...new Set(deps)] // Remove duplicates
	  }

	  async createProject() {
	    console.log("\nšŸ—ļø  Creating project structure...");

	    const projectPath = path.join(process.cwd(), this.projectConfig.name);

	    // Create project directory
	    if (!fs.existsSync(projectPath)) {
	      fs.mkdirSync(projectPath, { recursive: true });
	    }

	    process.chdir(projectPath);

	    // Initialize package.json
	    const packageJson = {
	      name: this.projectConfig.name,
	      version: "1.0.0",
	      description: this.projectConfig.description,
	      main: "index.js",
	      scripts: this.generateScripts(),
	      dependencies: {},
	      devDependencies: {},
	    };

	    fs.writeFileSync("package.json", JSON.stringify(packageJson, null, 2));

	    // Create directory structure
	    Object.keys(this.projectConfig.structure).forEach((dir) => {
	      const dirPath = path.join(projectPath, dir);
	      if (!fs.existsSync(dirPath)) {
	        fs.mkdirSync(dirPath, { recursive: true });
	      }
	    });

	    // Install dependencies
	    if (this.projectConfig.dependencies.length > 0) {
	      console.log("šŸ“¦ Installing dependencies...");
	      const installCmd = this.detectPackageManager();
	      const result = spawnSync(installCmd, ["add", ...this.projectConfig.dependencies], {
	        stdio: "inherit",
	        shell: true,
	      });

	      if (result.status !== 0) {
	        console.error("āŒ Failed to install dependencies");
	      } else {
	        console.log("āœ… Dependencies installed successfully");
	      }
	    }

	    // Generate initial files
	    await this.generateInitialFiles(projectPath);

	    console.log(`\nšŸŽ‰ Project "${this.projectConfig.name}" created successfully!`);
	    console.log(`šŸ“ Location: ${projectPath}`);
	  }

	  generateScripts() {
	    const framework = this.projectConfig.framework.toLowerCase();

	    if (framework.includes("next")) {
	      return {
	        dev: "next dev",
	        build: "next build",
	        start: "next start",
	        lint: "next lint",
	      }
	    } else if (framework.includes("express")) {
	      return {
	        start: "node src/index.js",
	        dev: "nodemon src/index.js",
	        test: "jest",
	      }
	    } else {
	      return {
	        start: "node src/index.js",
	        build: "npm run compile",
	        test: "jest",
	      }
	    }
	  }

	  async generateInitialFiles(projectPath) {
	    const framework = this.projectConfig.framework.toLowerCase();

	    if (framework.includes("next")) {
	      // Generate Next.js files
	      const appPage = `export default function Home() {
  return (
    <main>
      <h1>Welcome to ${this.projectConfig.name}</h1>
      <p>${this.projectConfig.description}</p>
    </main>
  );
}`;
	      fs.writeFileSync(path.join(projectPath, "app/page.js"), appPage);

	      const layout = `export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}`;
	      fs.writeFileSync(path.join(projectPath, "app/layout.js"), layout);
	    } else if (framework.includes("express")) {
	      // Generate Express.js files
	      const serverCode = `const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.use(express.json());

app.get('/', (req, res) => {
  res.json({ 
    message: 'Welcome to ${this.projectConfig.name}',
    description: '${this.projectConfig.description}'
  });
});

app.listen(PORT, () => {
  console.log(\`Server running on port \${PORT}\`);
});`;
	      fs.writeFileSync(path.join(projectPath, "src/index.js"), serverCode);
	    }

	    // Generate README
	    const readme = `# ${this.projectConfig.name}

${this.projectConfig.description}

## Framework
${this.projectConfig.framework}

## Features
${this.projectConfig.features.map((f) => `- ${f}`).join("\n")}

## Getting Started

\`\`\`bash
npm install
npm run dev
\`\`\`

Generated with BetterPack Interactive Project Builder šŸš€
`;
	    fs.writeFileSync(path.join(projectPath, "README.md"), readme);
	  }

	  async enterInteractiveMode() {
	    console.log("\nšŸ’¬ Entering interactive mode. You can now use natural language to modify your project.");
	    console.log("Examples:");
	    console.log('  - "add authentication to my app"');
	    console.log('  - "create a user dashboard component"');
	    console.log('  - "add a database connection"');
	    console.log('  - "help" for more commands');
	    console.log('  - "exit" to quit\n');

	    while (true) {
	      const input = await this.ask("šŸ¤– What would you like to do? ");

	      if (input.toLowerCase() === "exit") {
	        console.log("šŸ‘‹ Goodbye! Happy coding!");
	        break
	      }

	      if (input.toLowerCase() === "help") {
	        this.showHelp();
	        continue
	      }

	      await this.processNaturalLanguageCommand(input);
	    }
	  }

	  async processNaturalLanguageCommand(input) {
	    console.log("šŸ¤” Processing your request...");

	    // Simple keyword-based processing (can be enhanced with actual AI)
	    const lowerInput = input.toLowerCase();

	    if (lowerInput.includes("add") && lowerInput.includes("component")) {
	      await this.handleAddComponent(input);
	    } else if (lowerInput.includes("add") && lowerInput.includes("auth")) {
	      await this.handleAddAuthentication();
	    } else if (lowerInput.includes("add") && lowerInput.includes("database")) {
	      await this.handleAddDatabase();
	    } else if (lowerInput.includes("analyze") || lowerInput.includes("status")) {
	      await this.handleAnalyzeProject();
	    } else if (lowerInput.includes("install") || lowerInput.includes("dependency")) {
	      await this.handleInstallDependency(input);
	    } else {
	      console.log("🤷 I'm not sure how to handle that request yet.");
	      console.log('Try being more specific or use "help" to see available commands.');
	    }
	  }

	  async handleAddComponent(input) {
	    const componentName = await this.ask("What should the component be called? ");
	    const componentType = await this.ask("What type of component? (page, form, button, etc.) ");

	    console.log(`šŸ”§ Creating ${componentType} component: ${componentName}`);

	    // Generate component based on framework
	    const framework = this.projectConfig.framework.toLowerCase();
	    let componentCode = "";

	    if (framework.includes("next") || framework.includes("react")) {
	      componentCode = `export default function ${componentName}() {
  return (
    <div>
      <h2>${componentName}</h2>
      <p>This is a ${componentType} component.</p>
    </div>
  );
}`;

	      const fileName = `${componentName.toLowerCase()}.js`;
	      const filePath = path.join("components", fileName);

	      if (!fs.existsSync("components")) {
	        fs.mkdirSync("components", { recursive: true });
	      }

	      fs.writeFileSync(filePath, componentCode);
	      console.log(`āœ… Component created: ${filePath}`);
	    }
	  }

	  async handleAddAuthentication() {
	    console.log("šŸ” Adding authentication system...");

	    await this.ask("What type of auth? (jwt, oauth, simple) ");

	    // Install auth dependencies
	    const authDeps = ["jsonwebtoken", "bcrypt"];
	    console.log("šŸ“¦ Installing authentication dependencies...");

	    const installCmd = this.detectPackageManager();
	    spawnSync(installCmd, ["add", ...authDeps], { stdio: "inherit", shell: true });

	    // Generate auth files (simplified example)
	    const authMiddleware = `const jwt = require('jsonwebtoken');

const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  
  if (!token) {
    return res.sendStatus(401);
  }
  
  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
};

module.exports = { authenticateToken };`;

	    if (!fs.existsSync("middleware")) {
	      fs.mkdirSync("middleware", { recursive: true });
	    }

	    fs.writeFileSync("middleware/auth.js", authMiddleware);
	    console.log("āœ… Authentication system added!");
	    console.log("šŸ“ Don't forget to set JWT_SECRET in your environment variables.");
	  }

	  async handleAddDatabase() {
	    console.log("šŸ—„ļø  Adding database connection...");

	    const dbType = await this.ask("What database? (mongodb, postgresql, mysql, sqlite) ");

	    let dbDeps = [];
	    if (dbType.includes("mongo")) {
	      dbDeps = ["mongoose"];
	    } else if (dbType.includes("postgres")) {
	      dbDeps = ["pg"];
	    } else if (dbType.includes("mysql")) {
	      dbDeps = ["mysql2"];
	    } else if (dbType.includes("sqlite")) {
	      dbDeps = ["sqlite3"];
	    }

	    console.log("šŸ“¦ Installing database dependencies...");
	    const installCmd = this.detectPackageManager();
	    spawnSync(installCmd, ["add", ...dbDeps], { stdio: "inherit", shell: true });

	    console.log("āœ… Database dependencies installed!");
	    console.log("šŸ“ Configure your database connection in the config folder.");
	  }

	  async handleAnalyzeProject() {
	    console.log("šŸ“Š Analyzing current project...");

	    try {
	      const analysis = await this.analyzer.analyzeProject(process.cwd());

	      console.log("\nšŸ“ˆ Project Analysis Results:");
	      console.log(`Health Score: ${analysis.healthScore}/100`);
	      console.log(`Dependencies: ${analysis.dependencies.length} packages`);
	      console.log(`Issues Found: ${analysis.issues.length}`);

	      if (analysis.issues.length > 0) {
	        console.log("\nāš ļø  Issues:");
	        analysis.issues.forEach((issue) => {
	          console.log(`  - ${issue.type}: ${issue.message}`);
	        });
	      }

	      if (analysis.recommendations.length > 0) {
	        console.log("\nšŸ’” Recommendations:");
	        analysis.recommendations.forEach((rec) => {
	          console.log(`  - ${rec.action}: ${rec.reason}`);
	        });
	      }
	    } catch (error) {
	      console.error("āŒ Failed to analyze project:", error.message);
	    }
	  }

	  async handleInstallDependency(input) {
	    const packageName = await this.ask("What package would you like to install? ");

	    console.log(`šŸ“¦ Installing ${packageName}...`);
	    const installCmd = this.detectPackageManager();
	    const result = spawnSync(installCmd, ["add", packageName], { stdio: "inherit", shell: true });

	    if (result.status === 0) {
	      console.log(`āœ… ${packageName} installed successfully!`);
	    } else {
	      console.log(`āŒ Failed to install ${packageName}`);
	    }
	  }

	  detectPackageManager() {
	    if (fs.existsSync("pnpm-lock.yaml")) return "pnpm"
	    if (fs.existsSync("yarn.lock")) return "yarn"
	    if (fs.existsSync("package-lock.json")) return "npm"
	    return "npm" // default
	  }

	  showHelp() {
	    console.log("\nšŸ“š Available Commands:");
	    console.log("  Natural Language Examples:");
	    console.log('    - "add a login component"');
	    console.log('    - "add authentication to my app"');
	    console.log('    - "add database connection"');
	    console.log('    - "install lodash package"');
	    console.log('    - "analyze my project"');
	    console.log('    - "create a user dashboard"');
	    console.log("\n  Direct Commands:");
	    console.log("    - help    - Show this help message");
	    console.log("    - exit    - Exit interactive mode");
	    console.log("    - status  - Show project analysis");
	  }

	  ask(question) {
	    return new Promise((resolve) => {
	      this.rl.question(question, (answer) => {
	        resolve(answer.trim());
	      });
	    })
	  }

	  close() {
	    this.rl.close();
	  }
	}

	interactiveBuilder = { InteractiveProjectBuilder };
	return interactiveBuilder;
}

var src;
var hasRequiredSrc;

function requireSrc () {
	if (hasRequiredSrc) return src;
	hasRequiredSrc = 1;
	const { spawn, spawnSync } = require$$2$2;
	const fs = require$$0$2;
	const path = require$$1;

	const PACKAGE_MANAGERS = {
	  npm: {
	    commands: {
	      install: "install",
	      add: "install",
	      remove: "uninstall",
	      update: "update",
	      run: "run",
	      test: "test",
	      build: "build",
	      list: "list",
	      pack: "pack",
	      cache: { cmd: "cache", args: ["clean", "--force"] },
	      ci: "ci",
	      doctor: "doctor",
	      link: "link",
	      global: { cmd: "list", args: ["-g"] },
	      outdated: "outdated",
	      search: "search",
	      start: "start",
	      audit: "audit",
	      "audit:fix": { cmd: "audit", args: ["fix"] },
	      lint: { cmd: "run", args: ["lint"] },
	      "lint:fix": { cmd: "run", args: ["lint", "--", "--fix"] },
	    },
	  },
	  yarn: {
	    commands: {
	      install: "install",
	      add: "add",
	      remove: "remove",
	      update: "upgrade",
	      run: "run",
	      test: "test",
	      build: "build",
	      list: "list",
	      pack: "pack",
	      cache: { cmd: "cache", args: ["clean"] },
	      ci: { cmd: "install", args: ["--immutable"] },
	      doctor: "doctor",
	      link: "link",
	      global: { cmd: "global", args: ["list"] },
	      outdated: "outdated",
	      search: null,
	      start: "start",
	      audit: { cmd: "npm", args: ["audit"] },
	      "audit:fix": { cmd: "npm", args: ["audit", "fix"] },
	      lint: "lint",
	      "lint:fix": { cmd: "lint", args: ["--fix"] },
	    },
	  },
	  pnpm: {
	    commands: {
	      install: "install",
	      add: "add",
	      remove: "remove",
	      update: "update",
	      run: "run",
	      test: "test",
	      build: "build",
	      list: "list",
	      pack: "pack",
	      cache: { cmd: "store", args: ["prune"] },
	      ci: { cmd: "install", args: ["--frozen-lockfile"] },
	      doctor: "doctor",
	      link: "link",
	      global: { cmd: "list", args: ["-g"] },
	      outdated: "outdated",
	      search: null,
	      start: "start",
	      audit: "audit",
	      "audit:fix": { cmd: "audit", args: ["--fix"] },
	      lint: "lint",
	      "lint:fix": { cmd: "lint", args: ["--fix"] },
	    },
	  },
	  bun: {
	    commands: {
	      install: "install",
	      add: "add",
	      remove: "remove",
	      update: "upgrade",
	      run: "run",
	      test: "test",
	      build: "build",
	      list: "list",
	      pack: "pack",
	      cache: { cmd: "cache", args: ["clean"] },
	      ci: { cmd: "install", args: ["--frozen-lockfile"] },
	      doctor: "doctor",
	      link: "link",
	      global: { cmd: "list", args: ["-g"] },
	      outdated: "outdated",
	      search: null,
	      start: "start",
	      audit: "audit",
	      "audit:fix": { cmd: "audit", args: ["--fix"] },
	      lint: "lint",
	      "lint:fix": { cmd: "lint", args: ["--fix"] },
	    },
	  },
	};

	const GLOBAL_COMMANDS = {
	  npm: { install: ["install", "-g"], update: ["update", "-g"], remove: ["uninstall", "-g"], list: ["list", "-g"] },
	  yarn: {
	    install: ["global", "add"],
	    update: ["global", "upgrade"],
	    remove: ["global", "remove"],
	    list: ["global", "list"],
	  },
	  pnpm: { install: ["add", "-g"], update: ["update", "-g"], remove: ["remove", "-g"], list: ["list", "-g"] },
	  bun: { install: ["add", "-g"], update: ["update", "-g"], remove: ["remove", "-g"], list: ["ls", "-g"] },
	};

	function getAvailablePms() {
	  const allPms = ["npm", "yarn", "pnpm", "bun"];
	  const executablesToFind = [...allPms, "node", "http-server", "npx"]; // Add node, http-server, and npx
	  const availablePms = [];
	  for (const pm of executablesToFind) {
	    // Iterate through all executables
	    // Use 'where' on Windows or 'which' on Linux/macOS to find the executable path
	    const findCmd = process.platform === "win32" ? "where" : "which";
	    const result = spawnSync(findCmd, [pm], { shell: true, encoding: "utf8" });

	    if (result.status === 0 && result.stdout) {
	      result.stdout.trim().replace(/\r/g, "").split("\n")[0]; // Get the first path if multiple and remove carriage returns
	      // On Windows, if the path doesn't have an extension, check for .cmd
	      if (allPms.includes(pm)) {
	        // Only add package managers to availablePms list
	        availablePms.push(pm);
	      }
	    } else {
	      // Fallback to just checking --version if path not found (e.g., for built-in npm)
	      // This part might need refinement for non-PM executables
	      const versionResult = spawnSync(pm, ["--version"], { shell: true, encoding: "utf8" });
	      if (versionResult.status === 0) {
	        if (allPms.includes(pm)) {
	          availablePms.push(pm);
	        }
	      }
	    }
	  }
	  return availablePms
	}

	function detectPackageManager() {
	  const cwd = process.cwd();
	  const packageJsonPath = path.join(cwd, "package.json");

	  if (fs.existsSync(packageJsonPath)) {
	    try {
	      const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
	      if (packageJson.packageManager) {
	        const pm = packageJson.packageManager.split("@")[0];
	        if (PACKAGE_MANAGERS[pm]) {
	          return pm
	        }
	      }
	    } catch (e) {
	      // Ignore error
	    }
	  }

	  if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm"
	  if (fs.existsSync(path.join(cwd, "yarn.lock"))) return "yarn"
	  if (fs.existsSync(path.join(cwd, "package-lock.json"))) return "npm"

	  // Default to pnpm if no lockfile or packageManager field is found
	  return "pnpm"
	}

	function translateCommand(pmName, universalCommand, args) {
	  if (!PACKAGE_MANAGERS[pmName]) {
	    return null
	  }

	  const pmConfig = PACKAGE_MANAGERS[pmName];
	  const translated = pmConfig.commands[universalCommand];

	  if (translated === undefined) {
	    console.warn(
	      `Warning: Universal command '${universalCommand}' is not explicitly defined for ${pmName}. Attempting to pass through.`,
	    );
	    return [pmName, universalCommand, ...args]
	  }

	  if (translated === null) {
	    console.error(`Error: Command '${universalCommand}' is not supported by ${pmName}.`);
	    if (universalCommand === "search") {
	      console.error("Suggestion: Try 'bpack manage npm search <query>' to use npm's search feature.");
	    }
	    return null
	  }

	  if (typeof translated === "string") {
	    return [pmName, translated, ...args]
	  }

	  if (typeof translated === "object") {
	    const finalArgs = [...translated.args, ...args];
	    return [pmName, translated.cmd, ...finalArgs]
	  }

	  return [pmName, universalCommand, ...args]
	}

	function findPathKey(env = process.env) {
	  if (process.platform !== "win32") {
	    return "PATH"
	  }
	  const pathKey = Object.keys(env).find((key) => key.toLowerCase() === "path");
	  return pathKey || "PATH"
	}

	function executeCommand(command, args, options = {}) {
	  if (!options.silent) {
	    console.log(`Executing: ${command} ${args.join(" ")}`);
	  }

	  const env = { ...process.env };
	  const pathKey = findPathKey(env);
	  const localBinPath = path.join(__dirname, "..", "node_modules", ".bin");

	  // Prepend local bin path
	  env[pathKey] = [localBinPath, env[pathKey]].filter(Boolean).join(path.delimiter);

	  const spawnOptions = {
	    stdio: "inherit",
	    shell: true,
	    env: env,
	  };

	  console.log(`executeCommand: Spawning command: ${command} with args: ${args.join(" ")}`);
	  const child = spawn(command, args, spawnOptions);

	  child.on("error", (err) => {
	    console.error(`Failed to start subprocess: ${err.message}`);
	  });
	}

	function executeOutdatedCommand(command, args) {
	  console.log(`Executing: ${command} ${args.join(" ")}`);

	  const env = { ...process.env };
	  const pathKey = findPathKey(env);
	  const localBinPath = path.join(__dirname, "..", "node_modules", ".bin");

	  // Prepend local bin path
	  env[pathKey] = [localBinPath, env[pathKey]].filter(Boolean).join(path.delimiter);

	  const spawnOptions = {
	    stdio: "pipe",
	    shell: true,
	    env: env,
	  };

	  const child = spawn(command, args, spawnOptions);

	  let stdout = "";
	  let stderr = "";

	  if (child.stdout) {
	    child.stdout.on("data", (data) => {
	      stdout += data.toString();
	    });
	  }
	  if (child.stderr) {
	    child.stderr.on("data", (data) => {
	      stderr += data.toString();
	    });
	  }

	  child.on("close", (code) => {
	    if (code === 0 && stdout.trim() === "" && stderr.trim() === "") {
	      console.log("All dependencies are up to date.");
	    } else {
	      if (stdout.trim()) {
	        console.log(stdout.trim());
	      }
	      if (stderr.trim()) {
	        console.error(stderr.trim());
	      }
	    }
	  });

	  child.on("error", (err) => {
	    console.error(`Failed to start subprocess: ${err.message}`);
	  });
	}

	function listversions() {
	  const scriptPath = path.join(__dirname, "..", "detectpkgmgr.ps1");
	  if (process.platform === "win32") {
	    executeCommand("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", scriptPath], {
	      silent: true,
	    });
	  } else {
	    console.log("'listversions' is only supported on Windows.");
	    process.exit(1);
	  }
	}

	function manageCommand(args) {
	  if (args[0] === "selfupdate") {
	    console.log("Attempting to self-update betterpack...");
	    const pmsToCheck = {
	      npm: ["list", "-g", "--depth=0"],
	      pnpm: ["list", "-g", "--depth=0"],
	      yarn: ["global", "list"],
	    };
	    let installedWith = null;

	    for (const pm in pmsToCheck) {
	      const result = spawnSync(pm, pmsToCheck[pm], { shell: true, encoding: "utf8" });
	      if (result.status === 0 && result.stdout && result.stdout.includes("betterpack")) {
	        installedWith = pm;
	        break
	      }
	    }

	    if (installedWith) {
	      console.log(`betterpack was installed with ${installedWith}. Attempting update...`);
	      let updateArgs;
	      switch (installedWith) {
	        case "npm":
	          updateArgs = ["install", "-g", "betterpack@latest"];
	          break
	        case "pnpm":
	          updateArgs = ["update", "-g", "betterpack"];
	          break
	        case "yarn":
	          updateArgs = ["global", "upgrade", "betterpack"];
	          break
	      }
	      executeCommand(installedWith, updateArgs);
	    } else {
	      console.error("Could not determine how betterpack was installed globally. Please update manually.");
	      process.exit(1);
	    }
	    return
	  }

	  if (args[0] === "about") {
	    const topic = args[1];
	    let url;
	    switch (topic) {
	      case "github":
	        url = "https://github.com/involvex/betterpack";
	        break
	      case "npmjs":
	        url = "https://www.npmjs.com/package/betterpack";
	        break
	      default:
	        console.error("Usage: bpack manage about <github|npmjs>");
	        process.exit(1);
	    }
	    console.log(`Opening ${url}...`);
	    const openCmd = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
	    executeCommand(openCmd, [url], { silent: true });
	    return
	  }

	  if (args[0] === "support") {
	    const url = "https://www.buymeacoffee.com/involvex";
	    console.log(`Opening ${url}...`);
	    const openCmd = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
	    executeCommand(openCmd, [url], { silent: true });
	    return
	  }

	  if (args[0] === "git" && args[1] === "autocommit") {
	    const status = args[2];
	    if (status !== "on" && status !== "off") {
	      console.error("Usage: bpack manage git autocommit <on|off>");
	      process.exit(1);
	    }
	    const configPath = path.join(require$$3.homedir(), ".bpackrc");
	    let config = {};
	    if (fs.existsSync(configPath)) {
	      config = JSON.parse(fs.readFileSync(configPath, "utf8"));
	    }
	    config.autocommit = status === "on";
	    fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
	    console.log(`Autocommit is now ${status}.`);
	    return
	  }

	  const [pkgMgr, action, ...rest] = args;
	  const availablePms = getAvailablePms();

	  if (!pkgMgr || !action) {
	    console.log("Usage: bpack manage <package-manager> <action> [args]");
	    console.log("       bpack manage selfupdate");
	    console.log("       bpack manage about <github|npmjs>");
	    console.log("       bpack manage git autocommit <on|off>");
	    console.log(`  Package Managers: ${availablePms.join(", ")}`);
	    console.log("  Actions: install, update, remove, version, list");
	    console.log("  Note: 'update' with no package name will attempt to update the manager itself.");
	    process.exit(1);
	  }

	  if (!availablePms.includes(pkgMgr)) {
	    console.error(`Error: Package manager '${pkgMgr}' not found. Available: ${availablePms.join(", ")}`);
	    process.exit(1);
	  }

	  // Special handling for updating the package manager itself
	  if (action === "update" && rest.length === 0) {
	    const updateCmd = pkgMgr;
	    let updateArgs = [];
	    switch (pkgMgr) {
	      case "npm":
	        updateArgs = ["install", "-g", "npm@latest"];
	        break
	      case "pnpm":
	        updateArgs = ["self-update"];
	        break
	      case "bun":
	        updateArgs = ["upgrade"];
	        break
	      case "yarn":
	        console.log("Attempting to set Yarn version for current project...");
	        updateArgs = ["set", "version", "stable"];
	        break
	    }
	    executeCommand(updateCmd, updateArgs);
	    return
	  }

	  if (action === "version") {
	    executeCommand(pkgMgr, ["--version"]);
	    return
	  }

	  const baseArgs = GLOBAL_COMMANDS[pkgMgr][action];
	  if (!baseArgs) {
	    console.error(`Error: Unknown action '${action}'. Supported: install, update, remove, version, list`);
	    process.exit(1);
	  }

	  const cmdArgs = [...baseArgs, ...rest];
	  executeCommand(pkgMgr, cmdArgs);
	}

	function displayHelp() {
	  console.log("\nUsage: bpack <command> [args]");
	  console.log("\n\x1b[1mUniversal Package Manager Commands:\x1b[0m");
	  const universalCommands = {
	    install: "Install project dependencies.",
	    add: "Add a new dependency to the project.",
	    remove: "Remove a dependency from the project.",
	    update: "Update project dependencies.",
	    outdated: "Check for outdated dependencies.",
	    ci: "Install dependencies from a lockfile.",
	    run: "Run a script defined in package.json.",
	    test: "Run project tests.",
	    build: "Build the project.",
	    start: "Start the project.",
	    pack: "Create a package tarball.",
	    list: "List installed packages.",
	    global: "List global packages.",
	    "cache clean": "Clear the package manager cache.",
	    doctor: "Run a health check.",
	    link: "Link a local package.",
	    search: "Search for packages (uses npm).",
	    "lint, lint --fix": "Run linter.",
	    "audit, audit --fix": "Run security audit.",
	  };
	  for (const [cmd, desc] of Object.entries(universalCommands)) {
	    console.log(`  \x1b[36m${cmd.padEnd(20)}\x1b[0m ${desc}`);
	  }

	  console.log("\n\x1b[1mBetterpack Commands:\x1b[0m");
	  const betterpackCommands = {
	    listversions: "List installed versions of all supported package managers.",
	    manage: "Manage global packages or the package managers themselves.",
	    buildexe: "Package project into an executable using nexe.",
	    bundle: "Bundle project into various formats (JS, ZIP, TAR, EXE, MSIX, SH).",
	    node: "Execute a JavaScript file using Node.js.",
	    watch: "Watch for file changes and auto-restart a process.",
	    host: "Start a web server from the current folder (default port 4020).",
	    gemini: "Start a chat with Gemini.",
	    create: "Interactive project builder with AI assistance.",
	    "build-project": "Alias for create - Interactive project builder with AI assistance.",
	  };
	  for (const [cmd, desc] of Object.entries(betterpackCommands)) {
	    console.log(`  \x1b[36m${cmd.padEnd(20)}\x1b[0m ${desc}`);
	  }
	  console.log("");
	  process.exit(0);
	}

	function runCli() {
	  let args = process.argv.slice(2);
	  getAvailablePms(); // Populate availablePmPaths at the start

	  const configPath = path.join(require$$3.homedir(), ".bpackrc");
	  if (fs.existsSync(configPath)) {
	    const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
	    if (config[args[0]]) {
	      args = config[args[0]].split(" ");
	    }
	  }

	  if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
	    displayHelp();
	    return
	  }

	  let universalCommand = args[0];
	  const commandArgs = args.slice(1);

	  const internalCommands = [
	    "listversions",
	    "manage",
	    "buildexe",
	    "bundle",
	    "node",
	    "watch",
	    "host",
	    "gemini",
	    "create",
	    "build-project",
	  ];

	  // If a command is provided and it's an internal command, check for --help in its arguments
	  if (
	    universalCommand &&
	    internalCommands.includes(universalCommand) &&
	    (commandArgs.includes("--help") || commandArgs.includes("-h"))
	  ) {
	    displayHelp();
	    return
	  }

	  // If no command is provided, display general help
	  if (!universalCommand) {
	    displayHelp();
	    return
	  }

	  const fixIndex = commandArgs.indexOf("--fix");
	  if (fixIndex !== -1) {
	    if (universalCommand === "audit" || universalCommand === "lint") {
	      universalCommand += ":fix";
	      commandArgs.splice(fixIndex, 1);
	    }
	  }

	  if (universalCommand === "bundle") {
	    const { handleBundleCommand } = requireBundler();
	    handleBundleCommand(commandArgs);
	    return
	  }

	  if (universalCommand === "create" || universalCommand === "build-project") {
	    const { InteractiveProjectBuilder } = requireInteractiveBuilder();
	    const builder = new InteractiveProjectBuilder();

	    builder
	      .start()
	      .then(() => {
	        builder.close();
	        process.exit(0);
	      })
	      .catch((error) => {
	        console.error("āŒ Error in interactive builder:", error.message);
	        builder.close();
	        process.exit(1);
	      });
	    return
	  }

	  const pmName = detectPackageManager();

	  console.log(`Detected package manager: ${pmName}`);

	  const translatedCommand = translateCommand(pmName, universalCommand, commandArgs);

	  if (translatedCommand) {
	    const [cmd, ...cmdArgs] = translatedCommand;
	    if (universalCommand === "outdated") {
	      executeOutdatedCommand(cmd, cmdArgs);
	    } else {
	      executeCommand(cmd, cmdArgs);
	    }
	  } else {
	    process.exit(1);
	  }
	}

	src = { runCli, detectPackageManager, translateCommand, executeCommand, listversions, manageCommand };
	return src;
}

var srcExports = requireSrc();
var index = /*@__PURE__*/getDefaultExportFromCjs(srcExports);

export { index as default };
//# sourceMappingURL=bpack.mjs.map