HOME


Mini Shell 1.0
Redirecting to https://devs.lapieza.net/iniciar-sesion Redirecting to https://devs.lapieza.net/iniciar-sesion.
DIR: /proc/1991108/cwd/usr/share/node_modules/lodash-cli/bin/
Upload File :
Current File : //proc/1991108/cwd/usr/share/node_modules/lodash-cli/bin/lodash
#!/usr/bin/env node
'use strict';

var _ = require('lodash'),
    glob = require('glob'),
    semver = require('semver'),
    vm = require('vm'),
    consts = require('../lib/const'),
    listing = require('../lib/listing'),
    mapping = require('../lib/mapping'),
    minify = require('../lib/minify'),
    util = require('../lib/util');

var fs = util.fs,
    Hash = util.Hash,
    path = util.path;

var buildExports = listing.buildExports,
    cwd = process.cwd(),
    floor = Math.floor,
    push = Array.prototype.push,
    stdout = process.stdout,
    uninlinables = listing.uninlinables;

/** Used to indicate whether this file is executed directly from Node.js. */
var isBin = module == require.main;

/*----------------------------------------------------------------------------*/

/**
 * Adds build `commands` to the copyright header of `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {Array} [commands=[]] An array of commands.
 * @returns {string} Returns the modified source.
 */
function addCommandsToHeader(source, commands) {
  return replace(source, getHeader(source), function(header) {
    // Add quotes to commands with spaces or equals signs.
    commands = _.map(commands, function(command) {
      var separator = /[= ]/.exec(command);
      if (separator) {
        separator = separator[0];
        var parts = command.split(separator);
        command = parts[0] + separator + '"' + parts.slice(1).join(separator) + '"';
      }
      // Escape newlines, carriage returns, multi-line comment end tokens.
      return command
        .replace(/\n/g, '\\n')
        .replace(/\r/g, '\\r')
        .replace(/\*\//g, '*\\/');
    });

    // Remove any existing custom build information.
    header = header
      .replace(' (Custom Build)', '')
      .replace(/^ *\* *Build:.+\n/m, '');

    // Add build commands to copyright header.
    return header.replace(/(\/\**\n)( \*)( *@license[\s*]+)?( *Lodash)(.*)/, function(match, prelude, indent, tag, title, postlude) {
      return (
        prelude +
        indent +
        (tag || '') +
        title + ' (Custom Build)' + postlude + '\n' +
        indent + ' Build: `lodash ' + commands.join(' ') + '`'
      );
    });
  });
}

/**
 * Creates modules based on the provided build state.
 *
 * @private
 * @param {Object} state The build state object.
 * @param {Function} [onComplete] The function called when all module builds
 *  are completed.
 */
function buildModule(state, onComplete) {
  var buildFuncs = state.buildFuncs,
      funcDepMap = state.funcDepMap,
      includeFuncs = state.includeFuncs,
      includeVars = state.includeVars,
      isAMD = state.isAMD,
      isES = state.isES,
      isNode = state.isNode,
      isNpm = state.isNpm,
      isSilent = state.isSilent,
      minusFuncs = state.minusFuncs,
      outputPath = state.outputPath,
      plusFuncs = state.plusFuncs,
      stamp = state.stamp,
      varDepMap = state.varDepMap;

  var depMap = new Hash,
      identifiers = _.without(_.union(buildFuncs, includeVars), 'main'),
      moduleCount = 0,
      removedDeps = new Hash;

  var buildCallback = function(data) {
    moduleCount++;
    data.source = cleanupSource(addCommandsToHeader(data.source, state.options));
    defaultBuildCallback(data);
  };

  var getUnusedDeps = function(source, depNames) {
    source = cleanupSource(removeStrings(removeComments(source)));
    return _.reject(depNames, function(depName) {
      return RegExp('[^.$"\'\\w]' + depName + '\\b').test(source);
    });
  };

  var toDepName = function(value) {
    var prefix = (isPrivate(value) && !_.startsWith(value, '_')) ? '_' : '',
        result = prefix + value;

    return isNpm ? ('lodash.' + result.toLowerCase()) : result;
  };

  var toDepPath = function(value) {
    return './' + toDepName(value) + (isES ? '.js' : '');
  };

  if (isNpm) {
    // Exclude "Seq" methods and most internal functions when exporting for npm.
    identifiers = _.reject(_.difference(identifiers, mapping.category.Seq), function(identifier) {
      return isPrivate(identifier) && !_.includes(uninlinables, identifier) && !_.includes(includeFuncs, identifier);
    });

    // Remove unused packages.
    var newPackages = _.map(identifiers, toDepName),
        oldPackages = _.map(glob.sync(path.join(outputPath, 'lodash.*')), _.ary(path.basename, 1)),
        unusedPackages = _.difference(oldPackages, newPackages);

    _.each(unusedPackages, function(packageName) {
      var pathname = path.join(outputPath, packageName);
      _.each(fs.readdirSync(pathname), function(identifier) {
        fs.unlinkSync(path.join(pathname, identifier));
      });
      fs.rmdirSync(pathname);
    });
  }
  // List of identifiers that keep their copyright headers.
  var includeHeaders = isNpm ? identifiers : _.difference(_.union(includeFuncs, plusFuncs), minusFuncs);
  if (_.isEmpty(includeHeaders)) {
    includeHeaders = ['main'];
  }
  // Sort identifiers so private packages with the least number of interdependent
  // dependencies are first.
  identifiers = _.orderBy(identifiers, [
    isPrivate,
    function(identifier) {
      var depNames = _.union(
        getDependencies(identifier, funcDepMap),
        getDependencies(identifier, varDepMap)
      );

      var inlinees = [identifier];

      if (isNpm) {
        var moreInlinees = _.transform(_.difference(depNames, uninlinables), function(result, identifier) {
          push.apply(result, getAllDependencies([identifier], funcDepMap, varDepMap, _.clone(uninlinables)));
          return result;
        });

        depNames = _.union(_.intersection(uninlinables, depNames), _.intersection(uninlinables, moreInlinees));
        inlinees = inlinees.concat(_.difference(moreInlinees, depNames));
      }
      // Populate `depMap`.
      depMap[identifier] = new Hash({
        'depNames': depNames,
        'inlinees': inlinees,
        'isPrivate': isPrivate(identifier)
      });
      return depNames.length;
    },
    function(identifier) {
      if (!depMap[identifier].isPrivate) {
        return true;
      }
      return _.isString(_.findKey(depMap, function(value, key) {
        var data = depMap[key];
        return data.isPrivate && _.includes(data.depNames, identifier);
      }));
    }],
    ['desc']
  );

  // Create modules for each identifier.
  _.each(identifiers, function(identifier) {
    var basename = _.get(mapping.forceAlias, identifier, identifier),
        category = getCategory(identifier),
        depData = depMap[identifier],
        depName = toDepName(basename),
        depNames = depData.depNames,
        inlinees = depData.inlinees;

    if (isNpm) {
      var inlineFuncs = _.intersection(listing.funcs, inlinees),
          inlineVars = _.intersection(listing.varDeps, inlinees);
    }
    else {
      inlineFuncs = _.includes(listing.funcs, identifier) ? inlinees : [];
      inlineVars = _.includes(listing.varDeps, identifier) ? inlinees : [];
    }
    state.outputPath = path.join(outputPath, isNpm ? (depName + '/index.js') : (depName + '.js'));
    state.buildFuncs = state.includeFuncs = inlineFuncs;
    state.includeVars = inlineVars;

    build(state, function(data) {
      var iife = [],
          source = data.source,
          unusedDeps = getUnusedDeps(source, depNames);

      // Track and remove unused dependencies.
      removedDeps[identifier] = unusedDeps;
      depNames = _.sortBy(_.difference(depNames, unusedDeps), toDepName);

      depNames = _.map(depNames, function(depName) {
        return _.get(mapping.forceAlias, depName, depName);
      }).sort();

      var depPaths = isNpm
        ? _.map(depNames, toDepName)
        : _.map(depNames, toDepPath);

      if (isAMD) {
        var depArgs = _.map(depNames, function(depName) {
          return _.get(mapping.wrapperToReal, depName, depName);
        });

        iife.push(
          'define([' + (_.isEmpty(depPaths) ? '' : "'" + depPaths.join("', '") + "'") + '], function(' + depArgs.join(', ') + ') {',
          '%output%',
          '  return ' + identifier + ';',
          '});'
        );
      }
      else if (isES) {
        iife.push(
          _.map(depPaths, function(depPath, index) {
            var depName = depNames[index],
                varName = _.get(mapping.wrapperToReal, depName, depName);

            return 'import ' + varName + " from '" + depPath + "';";
          })
          .join('\n'),
          '%output%',
          'export default ' + identifier + ';'
        );
      }
      else {
        iife.push(
          _.map(depPaths, function(depPath, index) {
            var depName = depNames[index],
                varName = _.get(mapping.wrapperToReal, depName, depName),
                lastIndex = depPaths.length - 1;

            return (index ? '' : 'var ') +
              varName + " = require('" + depPath + "')" +
              (index == lastIndex ? ';' : '');
          })
          .join(',\n    '),
          '%output%',
          'module.exports = ' + identifier + ';'
        );
      }
      if (!isAMD) {
        source = replaceIndent(source, 0, 1);
      }
      source = _.includes(includeHeaders, identifier) ? removeLicenseTag(source) : removeHeader(source);
      source = replaceIIFE(source, iife.join('\n'));

      if (isNpm) {
        var templatePath = fs.realpathSync(path.join(__dirname, '..', 'template')),
            licenseTemplate = fs.readFileSync(path.join(templatePath, 'license.jst'), 'utf8'),
            packageTemplate = fs.readFileSync(path.join(templatePath, 'package.jst'), 'utf8'),
            readmeTemplate = fs.readFileSync(path.join(templatePath, 'readme.jst'), 'utf8');

        var type = 'function',
            pkgVer = semver.parse(state.lodash.VERSION),
            pkgDepNames = _.sortBy(depNames, toDepName),
            pkgDepPaths = _.sortBy(depPaths);

        if (_.includes(listing.varDeps, identifier)) {
          type = 'variable';
        }
        var templateData = {
          'identifier': identifier,
          'name': depName,
          'type': type,
          'version': pkgVer.raw
        };

        templateData.dependencies = _.transform(pkgDepNames, function(result, depName, index) {
          var minor = '0',
              depPath = pkgDepPaths[index],
              depRange = '^' + pkgVer.major + '.0.0',
              oldDepPkgPath = path.join(path.resolve(outputPath), depPath, 'package.json');

          if (fs.existsSync(oldDepPkgPath)) {
            var oldDepPkg = JSON.parse(fs.readFileSync(oldDepPkgPath, 'utf8')),
                oldDepVer = semver.parse(oldDepPkg.version);

            depRange = '^' + oldDepVer.major + '.' + minor + '.0';
            if (oldDepVer.major > pkgVer.major) {
              pkgVer = oldDepVer;
              templateData.version = pkgVer.major + '.0.0';
            }
          }
          result[depPath] = depRange;
        }, {});

        // Independently update the package version.
        if (fs.existsSync(data.outputPath)) {
          var laxDeps = _.map(listing.laxSemVerDeps, toDepName),
              oldPkgPath = path.join(path.resolve(outputPath), depName, 'package.json'),
              oldPkg = JSON.parse(fs.readFileSync(oldPkgPath, 'utf8')),
              oldVer = oldPkg.version,
              oldDeps = _.omit(oldPkg.dependencies, laxDeps),
              pkgDeps = _.omit(templateData.dependencies, laxDeps);

          if (_.isEqual(pkgDeps, oldDeps)) {
            var oldSource = fs.readFileSync(data.outputPath, 'utf8');

            // Exit early if sources are identical.
            if (removeHeader(cleanupSource(oldSource)) === removeHeader(cleanupSource(source))) {
              return;
            }
            // Bump the `patch` version if the source has changed.
            templateData.version = cleanupSource(removeComments(oldSource)) === cleanupSource(removeComments(source))
              ? oldVer
              : semver.inc(oldVer, 'patch', true);
          }
          else {
            // Bump the `minor` version if the dependencies have changed.
            templateData.version = semver.inc(oldVer, 'minor', true);
          }
          var isSameVersion = templateData.version == oldVer;

          source = source.replace(getHeader(source), function(header) {
            // Use the old header if the package version is unchanged,
            // otherwise remove the version from the header.
            return isSameVersion
              ? getHeader(oldSource)
              : header;
          });
        }
        if (!isSameVersion) {
          var oldPath = path.join(outputPath, depName, 'LICENSE.txt');
          if (fs.existsSync(oldPath)) {
            fs.unlinkSync(oldPath);
          }
          fs.writeFileSync(path.join(outputPath, depName, 'package.json'), _.template(packageTemplate)(templateData));
          fs.writeFileSync(path.join(outputPath, depName, 'LICENSE'), _.template(licenseTemplate)(templateData));
          fs.writeFileSync(path.join(outputPath, depName, 'README.md'), _.template(readmeTemplate)(templateData));
        }
      }
      data.source = source;
      buildCallback(data);
    });
  });

  // Add alias modules.
  _.each(!isNpm && identifiers, function(identifier) {
    var basename = _.get(mapping.forceAlias, identifier, identifier),
        aliases = _.without(getAliases(identifier), basename),
        category = getCategory(identifier),
        depName = toDepName(basename),
        depPath = toDepPath(basename);

    _.each(aliases, function(alias) {
      var iife = [];
      if (isAMD) {
        iife.push(
          'define(["' + depPath + '"], function(' + depName + ') {',
          '  return ' + depName + ';',
          '});'
        );
      }
      else if (isES) {
        iife.push(
          "export { default } from '" + depPath + "'"
        );
      }
      else {
        iife.push(
          'module.exports' +
          " = require('" + depPath + "');"
        );
      }
      buildCallback({
        'outputPath': path.join(outputPath, alias + '.js'),
        'source': iife.join('\n')
      });
    });
  });

  // Create main module.
  _.times(isES ? 2 : 1, function(index) {
    var identifier = 'main';
    if (isNpm || !_.includes(buildFuncs, identifier)) {
      return;
    }
    var categories = _.uniq(_.compact(_.map(identifiers, function(identifier) {
      return getCategory(identifier);
    }))).sort();

    var categoryDeps = _.map(categories, function(category) {
      return mapping.categoryToDepName[category] || category.toLowerCase();
    });

    var categoryDepPaths = _.map(categories, function(category) {
      return toDepPath(category).toLowerCase();
    });

    var deps = _.union(
      getDependencies(identifier, funcDepMap),
      getDependencies(identifier, varDepMap)
    );

    var basename = 'lodash';
    if (isAMD) {
      basename = 'main';
    } else if (isES) {
      basename += (index ? '.default' : '');
    }
    state.buildFuncs = state.includeFuncs = [identifier];
    state.outputPath = path.join(outputPath, basename + '.js');

    build(state, function(data) {
      var source = data.source;

      // Remove unused method and alias assignments.
      _.each(_.difference(listing.funcs, buildFuncs), function(funcName) {
        source = removeMethodAssignment(source, funcName);
      });

      // Wrap `_.mixin`.
      source = source.replace(/^(?: *\/\/.*\n)* *lodash\.[$\w]+\s*=[^;]+;\n/m, function(match) {
        return [
          '  // wrap `_.mixin` so it works when provided only one argument',
          '  ' + (isES ? 'var ' : '') + 'mixin = (function(func) {',
          '    return function(object, source, options) {',
          '      if (options == null) {',
          '        var isObj = isObject(source),',
          '            props = isObj && keys(source),',
          '            methodNames = props && props.length && baseFunctions(source, props);',
          '',
          '        if (!(methodNames ? methodNames.length : isObj)) {',
          '          options = source;',
          '          source = object;',
          '          object = this;',
          '        }',
          '      }',
          '      return func(object, source, options);',
          '    };',
          '  }(' + (isES ? '_' : '') + 'mixin));',
          '',
          match
        ].join('\n');
      });

      // Add `lodash.templateSettings` and placeholder assignments.
      source = source.replace(/^ *lodash\.VERSION\b.+\n/m, function(match) {
        var code = [];
        if (_.includes(identifiers, 'templateSettings')) {
          code.push('  (lodash.templateSettings = ' + mapping.categoryToDepName.String + '.templateSettings).imports._ = lodash;');
        }
        var funcNames = _.intersection(buildFuncs, listing.placeholderFuncs);
        if (!_.isEmpty(funcNames)) {
          code.push(
            '',
            '  // Assign default placeholders.'
          );
          if (_.size(funcNames) > 1) {
            code.push(
              "  arrayEach(['" + funcNames.join("', '") + "'], function(methodName) {",
              '    lodash[methodName].placeholder = lodash;',
              '  });'
            );
          } else {
            code.push('  lodash.' + funcNames[0] + '.placeholder = lodash;');
          }
        }
        code.push('');
        return match + code.join('\n');
      });

      // Add category namespaces to each lodash function assignment.
      source = source.replace(/(lodash(?:\.prototype)?(?:\[[$\w]+\]|\.[$\w]+)\s*=\s*)(?!lodash\b)([$\w]+)/g, function(match, left, identifier) {
        if (_.includes(deps, identifier)) {
          return match;
        }
        var category = mapping.categoryToDepName[getCategory(identifier)];
        identifier = _.get(mapping.wrapperToReal, identifier, identifier);
        return left + (category ? category + '.' : '') + identifier;
      });

      // Track and remove unused dependencies.
      var unusedDeps = getUnusedDeps(source, deps);
      removedDeps[identifier] = unusedDeps;
      deps = _.difference(deps, unusedDeps);

      deps = _.map(deps, function(depName) {
        return _.get(mapping.forceAlias, depName, depName);
      }).sort();

      var depNames = categoryDeps.concat(deps);

      if (isES) {
        // Avoid a syntax error caused by reassigning `mixin` by naming the
        // dependency `_mixin` instead.
        depNames[_.indexOf(depNames, 'mixin')] = '_mixin';
      }
      var iife = [];

      var depArgs = _.map(depNames, function(depName) {
        return _.get(mapping.wrapperToReal, depName, depName);
      });

      var depPaths = categoryDepPaths.concat(_.map(deps, toDepPath));

      if (isAMD) {
        iife.push(
          'define([' + (_.isEmpty(depPaths) ? '' : "'" + depPaths.join("', '") + "'") + '], function(' + depArgs.join(', ') + ') {',
          '%output%',
          '  return lodash;',
          '});'
        );
      }
      else if (isES) {
        if (index) {
          iife.push(
            _.map(depPaths, function(depPath, index) {
              var depName = depNames[index],
                  varName = _.get(mapping.wrapperToReal, depName, depName);

              return 'import ' + varName + " from '" + depPath + "';";
            }).join('\n'),
            '%output%',
            'export default lodash;'
          );
        }
        else {
          deps = _.reject(identifiers, isPrivate);

          var depData = _.sortBy(_.transform(deps, function(result, depName) {
            var aliases = getAliases(depName),
                forceAlias = mapping.forceAlias[depName],
                dataName = forceAlias === undefined ? depName : forceAlias,
                dataPath = toDepPath(_.includes(aliases, forceAlias) ? forceAlias : dataName);

            result.push({ 'name': depName, 'path': dataPath });
            push.apply(result, _.map(aliases, function(alias) {
              return { 'name': alias, 'path': toDepPath(alias) };
            }));
          }), 'name');

          depNames = _.map(depData, 'name');
          depPaths = _.map(depData, 'path');

          iife.push(
            _.map(depPaths, function(depPath, index) {
              var depName = depNames[index];
              return 'export { default as ' + depName + " } from '" + depPath + "';";
            }).join('\n'),
            "export { default } from './lodash.default.js';"
          );
        }
      }
      else {
        iife.push(
          _.map(depPaths, function(depPath, index) {
            var depName = depNames[index],
                varName = _.get(mapping.wrapperToReal, depName, depName),
                lastIndex = depPaths.length - 1;

            return (index ? '' : 'var ') +
              varName + " = require('" + depPath + "')" +
              (index == lastIndex ? ';' : '');
          }).join(',\n    '),
          '%output%',
          'module.exports = lodash;'
        );
      }
      if (!isAMD) {
        source = replaceIndent(source, 0, 1);
      }
      if (!_.includes(includeHeaders, identifier)) {
        source = removeHeader(source);
      }
      source = replaceIIFE(source, iife.join('\n'));

      if (isNode) {
        fs.writeFileSync(path.join(outputPath, 'index.js'), "module.exports = require('./lodash');");
      }
      data.source = source;
      buildCallback(data);
    });
  });

  // Create category modules.
  _.each(!isNpm && _.uniq(_.compact(_.flatten(_.map(identifiers, getCategory)))), function(category) {
    _.times(isES ? 2 : 1, function(index) {
      var basename = category.toLowerCase(),
          deps = _.intersection(getNamesByCategory(category), identifiers);

      var depData = _.sortBy(_.transform(deps, function(result, depName) {
        var forceAlias = mapping.forceAlias[depName],
            aliases = _.without(getAliases(depName), forceAlias, mapping.wrapperToReal[depName]),
            dataName = forceAlias === undefined ? depName : forceAlias,
            dataPath = toDepPath(_.includes(aliases, forceAlias) ? forceAlias : dataName);

        dataName = _.get(mapping.wrapperToReal, dataName, dataName);

        result.push({ 'name': dataName, 'path': dataPath });
        push.apply(result, _.map(aliases, function(alias) {
          return { 'name': alias, 'path': toDepPath(alias) };
        }));
      }), 'name');

      var depNames = _.map(depData, 'name'),
          depPaths = _.map(depData, 'path'),
          iife = [];

      if (isAMD) {
        iife.push(
          "define(['" + depPaths.join("', '") + "'], function(" + depNames.join(', ') + ') {',
          '  return {',
          _.map(depNames, function(depName) {
            var key = _.get(mapping.wrapperToReal, depName, depName);
            return "    '" + key + "': " + depName;
          })
          .join(',\n'),
          '  };',
          '});'
        );
      }
      else {
        if (isES) {
          if (index) {
            iife.push(
              _.map(depNames, function(depName, index) {
                return 'import ' + depName + " from '" + depPaths[index] + "';";
              })
              .join('\n'),
              '',
              'export default {',
                _(depNames)
                  .chunk(5)
                  .map(function(chunk) { return "  " + chunk.join(', '); })
                  .join(',\n'),
              '};'
            );
          }
          else {
            iife.push(
              '',
              _.map(depNames, function(depName, index) {
                var key = _.get(mapping.wrapperToReal, depName, depName);
                return 'export { default as ' + key + " } from '" + depPaths[index] + "';";
              })
              .join('\n'),
              "export { default } from './" + basename + ".default.js';"
            );
          }
        }
        else {
          iife.push(
            'module.exports = {',
            _.map(depNames, function(depName) {
              var depPath = depPaths[_.indexOf(depNames, depName)],
                  key = _.get(mapping.wrapperToReal, depName, depName);

              return "  '" + key + "': require('" + depPath + "')";
            })
            .join(',\n'),
            '};'
          );
        }
      }
      buildCallback({
        'outputPath': path.join(outputPath, basename + (index ? '.default' : '') + '.js'),
        'source': iife.join('\n')
      });
    });
  });

  if (!isSilent) {
    // Warn of removed dependencies.
    _.forOwn(removedDeps, function(depNames, identifier) {
      if (!_.isEmpty(depNames)) {
        var plural = _.size(depNames) > 1;
        console.warn('Warning: Removed ' + (plural ? '' : 'an ') + 'unused dependenc' + (plural ? 'ies' : 'y') + ' from `' + identifier + '`: ' + depNames.sort().join(', '));
      }
    });

    console.log('Created %d modules in %d seconds.', moduleCount, (_.now() - stamp) / 1000);
  }
  if (onComplete) {
    onComplete({ 'outputPath': fs.realpathSync(outputPath) });
  }
}

/**
 * Compiles template files based on the provided build state extending
 * `_.templates` with precompiled templates named after each file's basename.
 *
 * @private
 * @param {Object} state The build state object.
 * @returns {string} Returns the compiled source.
 */
function buildTemplate(state) {
  var moduleId = state.moduleId || 'lodash',
      isStandalone = moduleId == 'none',
      pattern = state.templatePattern,
      settings = state.templateSettings;

  pattern = path.normalize(pattern || path.join(cwd, '*.jst'));

  var source = [
    ';(function() {',
    '  var undefined;',
    '',
    "  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;",
    '',
    " var freeGlobalThis = typeof globalThis == 'object' && globalThis !== null && globalThis.Object == Object && globalThis;",
    '',
    "  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;",
    '',
    "  var root = freeGlobalThis || freeGlobal || freeSelf || Function('return this')();",
    '',
    "  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;",
    '',
    "  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;",
    ''
  ];

  if (isStandalone) {
    build(['exports=none', 'include=escape', 'iife=%output%', '-d', '-s'], function(data) {
      var escapeSource = data.source;
      escapeSource = removeHeader(escapeSource);
      escapeSource = removeFunction(escapeSource, 'lodash');
      escapeSource = removeAssignments(escapeSource);
      escapeSource = cleanupSource(escapeSource);

      source.push(
        '',
        escapeSource,
        '',
        "  var _ = { 'escape': escape };",
        ''
      );
    });
  }
  else {
    source.push(
      '  var _ = root._ || {};',
      ''
    );
  }
  source.push(
    consts.hr,
    ''
  );

  var dirname = path.dirname(pattern),
      filePaths = glob.sync(pattern);

  if (dirname == '.') {
    dirname = '';
  }
  var basePath = (dirname + path.sep).replace(RegExp('(^|' + path.sepEscaped + ')\\*\\*.*$'), '$1'),
      insertAt = source.length,
      templates = new Hash;

  _.each(filePaths, function(filePath) {
    var string = fs.readFileSync(filePath, 'utf8'),
        precompiled = cleanupCompiled(getFunctionSource(_.template(string, settings), 2));

    // Glob uses *nix path separators even on Windows.
    // See https://github.com/isaacs/node-glob#windows.
    var clipped = filePath.slice(dirname ? basePath.length : 0).replace(/\..*$/, ''),
        props = clipped.split('/');

    // Create namespace objects.
    _.reduce(props, function(object, key) {
      return object[key] || (object[key] = new Hash);
    }, templates);

    // Escape namespace property names.
    props = _.map(props, function(key) {
      return "['" + key.replace(/['\n\r\t]/g, '\\$&') + "']";
    });

    // Add template assignment to `source`.
    source.push('  templates' + props.join('') + ' = ' + precompiled + ';', '');
  });

  // Add the initial `_.templates` object to `source`.
  source.splice(insertAt, 0,
    '  var templates = ' +
    JSON.stringify(templates, null, 4)
      .replace(/^ *\}$/m, '  $&')
      .replace(/'/g, "\\'")
      .replace(/([^\\])"/g, "$1'") +
    ';',
    ''
  );

  source.push(
    consts.hr,
    '',
    "  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {"
  );

  if (isStandalone) {
    source.push(
      '    define(function() {',
      '      return templates;'
    );
  }
  else {
    source.push(
      "    define(['" + moduleId + "'], function(lodash) {",
      '      _ = lodash;',
      '      lodash.templates = lodash.extend(lodash.templates || {}, templates);'
    );
  }
  source.push(
    '    });',
    '  }',
    '  else if (freeModule) {'
  );

  if (!isStandalone) {
    source.push("    _ = require('" + moduleId + "');");
  }
  source.push(
    '    (freeModule.exports = templates).templates = templates;',
    '    freeExports.templates = templates;'
  );

  if (isStandalone) {
    source.push(
      '  }',
      '  else {',
      '    root.templates = templates;',
      '  }'
    );
  }
  else {
    source.push(
      '  }',
      '  else if (_) {',
      '    _.templates = _.extend(_.templates || {}, templates);',
      '  }'
    );
  }
  source.push('}.call(this));');
  return source.join('\n');
}

/**
 * Removes unnecessary semicolons and whitespace from compiled code.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function cleanupCompiled(source) {
  return stringFree(source, function(source) {
    return source
      .replace(/\b(function)\s*(\()/g, '$1$2')
      .replace(/([{}])\s*;/g, '$1');
  });
}

/**
 * Removes unnecessary comments, and whitespace.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function cleanupSource(source) {
  return stringFree(source, function(source) {
    return source
      // Consolidate consecutive horizontal rule comment separators.
      .replace(/(?:\s*\/\*-+\*\/\s*){2,}/g, function(separators) {
        var indent = /^\s*/.exec(separators)[0];
        return indent + separators.slice(separators.lastIndexOf('/*'));
      })
      // Remove unused single line comments.
      .replace(/(\{\s*)?(\n *\/\/.*)(\s*\})/g, function(match, prelude, comment, postlude) {
        return (!prelude && postlude) ? postlude : match;
      })
      // Remove unattached multi-line and single line comments.
      .replace(/^ *(\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/|\/\/.*)\n\n/gm, function(match, comment, index) {
        var isCopyright = !index && /\bcopyright\b/i.test(comment),
            isHR = /^\/\*-+\*\/$/.test(comment);

        return (isCopyright || isHR) ? match : '\n';
      })
      // Remove unused horizontal rule comment separators.
      .replace(/(\{\s*\n) *\/\*-+\*\/\n|^ *\/\*-+\*\/\n(\s*\})/gm, '$1$2')
      // Remove trailing horizontal rule comment separators.
      .replace(/\s*\/\*-+\*\/\s*$/, '')
      // Remove incomplete variable declarations.
      .replace(/^ *var\s*;\n/gm, '')
      // Remove lines with just spaces and semicolons.
      .replace(/^ *;\n/gm, '')
      // Remove trailing spaces from lines.
      .replace(/ *$/gm, '')
      // Consolidate multiple newlines.
      .replace(/\n{3,}/g, '\n\n')
      // Remove leading empty lines.
      .replace(/^ *\n+/, '')
      // Add trailing newline.
      .trimRight() + '\n';
  });
}

/**
 * Invokes `callback` providing `source` with comments removed and returns the
 * modified source with comments restored.
 *
 * @private
 * @param {string} source The source to modify.
 * @param {Function} [callback] The function to modify the comment free source.
 * @returns {string} Returns the modified source.
 */
function commentFree(source, callback) {
  var comments = [];
  source = callback(replace(source, consts.reComment, function(match) {
    var index = comments.length;
    comments.push(match);
    return '<#com_token' + index + '#>\n';
  })) || '';

  return replace(source, consts.reCommentToken, function(match) {
    return comments[match.slice(11, -3)];
  });
}

/**
 * The default callback used for `build` invocations.
 *
 * @private
 * @param {Object} data The data for the given build.
 *  gzip - The gzipped output of the built source
 *  outputPath - The path where the built source is to be written
 *  source - The built source output
 *  sourceMap - The source map output
 */
function defaultBuildCallback(data) {
  var outputPath = data.outputPath,
      sourceMap = data.sourceMap;

  if (outputPath) {
    fs.writeFileSync(outputPath, data.source);
    if (sourceMap) {
      fs.writeFileSync(path.join(path.dirname(outputPath), path.basename(outputPath, '.js') + '.map'), sourceMap);
    }
  }
}

/**
 * Gets the aliases associated with a given identifier.
 *
 * @private
 * @param {string} identifier The identifier to get aliases for.
 * @returns {Array} Returns an array of aliases.
 */
function getAliases(identifier) {
  return _.get(mapping.realToAlias, identifier, []);
}

/**
 * Creates an array of all function, object, and variable dependencies for the
 * given identifier(s).
 *
 * @private
 * @param {string|string[]} identifier The identifier or array of identifiers to query.
 * @param {Object} funcDepMap The dependency map to look up function dependencies.
 * @param {Object} varDepMap The dependency map to look up variable dependencies.
 * @param- {Array} [stackA=[]] Internally used track queried identifiers.
 * @returns {Array} Returns an array of identifier dependencies.
 */
function getAllDependencies(identifier, funcDepMap, varDepMap, stack) {
  var isInit = !stack,
      result = _.isArray(identifier) ? (isInit ? _.clone(identifier) : identifier) : [identifier];

  stack || (stack = []);

  _.each(result, function(identifier) {
    if (!_.includes(stack, identifier)) {
      push.apply(result, getDependencies(identifier, funcDepMap));
      push.apply(result, getDependencies(identifier, varDepMap));
      stack.push(identifier);
      getAllDependencies(result, funcDepMap, varDepMap, stack);
    }
  });
  return isInit ? _.uniq(result) : result;
}

/**
 * Gets the category of the given identifier.
 *
 * @private
 * @param {string} identifier The identifier to query.
 * @returns {string|undefined} Returns the category.
 */
function getCategory(identifier) {
  identifier = getRealName(identifier);
  return _.find(listing.categories, function(category) {
    return _.includes(mapping.category[category], identifier);
  });
}

/**
 * Creates an array of depenants for the given identifier(s).
 *
 * @private
 * @param {string} identifier The identifier or array of identifiers to query.
 * @param {Object} depMap The dependency map to look up dependants.
 * @param {boolean} [isDeep=false] A flag to specify retrieving nested dependants.
 * @param- {Array} [stackA=[]] Internally used track queried identifiers.
 * @returns {Array} Returns an array of identifier dependants.
 */
function getDependants(identifier, depMap, isDeep, stack) {
  var isInit = !stack,
      identifiers = _.isArray(identifier) ? identifier : [identifier];

  stack || (stack = []);

  // Iterate over the dependency map, adding names of functions that have `identifier` as a dependency.
  var result = _.transform(depMap, function(result, depNames, otherName) {
    if (!_.includes(stack, otherName) &&
        _.some(identifiers, _.partial(_.includes, depNames, _, 0))) {
      result.push(otherName);
      if (isDeep) {
        stack.push(otherName);
        push.apply(result, getDependants(otherName, depMap, isDeep, stack));
      }
    }
  }, []);

  return isInit ? _.uniq(result) : result;
}

/**
 * Creates an array of dependencies for the given identifier(s).
 *
 * @private
 * @param {string|string[]} identifier The identifier or array of identifiers to query.
 * @param {Object} depMap The dependency map to look up dependencies.
 * @param {boolean} [isDeep=false] A flag to specify retrieving nested dependencies.
 * @param- {Array} [stackA=[]] Internally used track queried identifiers.
 * @returns {Array} Returns an array of identifier dependencies.
 */
function getDependencies(identifier, depMap, isDeep, stack) {
  var isInit = !stack,
      depNames = _.isArray(identifier) ? identifier : depMap[identifier];

  stack || (stack = []);

  if (!isDeep) {
    return depNames ? _.difference(depNames, stack) : [];
  }
  // Recursively accumulate the dependencies of the `identifier` function,
  // the dependencies of its dependencies, and so on.
  var result = _.transform(depNames, function(result, otherName) {
    if (!_.includes(stack, otherName)) {
      stack.push(otherName);
      result.push(otherName);
      push.apply(result, getDependencies(otherName, depMap, isDeep, stack));
    }
  }, []);

  return isInit ? _.uniq(result) : result;
}

/**
 * Gets the formatted source of the given function.
 *
 * @private
 * @param {Function} func The function to process.
 * @param {number|string} [indent=0] The level to indent.
 * @returns {string} Returns the formatted source.
 */
function getFunctionSource(func, indent) {
  var source = toString(func.source || func),
      srcIndent = getIndent(source),
      forceIndent = _.size(source.match(RegExp('^' + srcIndent + '}', 'gm'))) > 1;

  indent || (indent = '');
  if (typeof indent == 'number') {
    indent = _.repeat(' ', indent);
  }
  // Remove any existing indent.
  if (srcIndent) {
    source = source.replace(RegExp('^' + srcIndent, 'gm'), '');
  }
  // Set indent of source.
  return indent + source.replace(/\n(?:.*)/g, function(match, index) {
    var prelude = '\n' + indent;
    match = match.slice(1);
    if (forceIndent) {
      prelude += (match == '}' && !_.includes(source, '}', index + 2) ? '' : '  ');
    }
    return prelude + match;
  });
}

/**
 * Gets the `getTag` fork from `source`.
 *
 * @private
 * @param {string} source The source to inspect.
 * @returns {string} Returns the fork.
 */
function getGetTagFork(source) {
  return _.get(/^(?: *\/\/.*\n)*( *)if\s*\(\s*\(DataView\s*&&[\s\S]+?\n\1  getTag\s*=[\s\S]+?\n\1\}\n/m.exec(source), 0, '');
}

/**
 * Gets the copyright header of `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the copyright header.
 */
function getHeader(source) {
  source = toString(source);
  return _.get(/^\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\n|^(?:\s*\/\/.*\n)+/.exec(source), 0, '');
}

/**
 * Gets the indent string of the given function.
 *
 * @private
 * @param {Function|string} func The function or function source to process.
 * @returns {string} Returns the indent string.
 */
function getIndent(func) {
  return _.get(/^ *(?=\S)/m.exec(func.source || func), 0, '');
}

/**
 * Gets the lodash method assignments snippet from `source`.
 *
 * @private
 * @param {string} source The source to inspect.
 * @returns {string} Returns the method assignments snippet.
 */
function getMethodAssignments(source) {
  source = toString(source);
  return _.get(/\n\n(?: *\/\/.*\n)* *lodash(?:\.(?!prototype\b)[$\w]+)+\s*=[\s\S]+\n *lodash(?:\.[$\w]+)+\s=[^;]+;(?=\n)/.exec(source), 0, '');
}

/**
 * Gets the names of identifiers in `source` that belong to the given category.
 *
 * @private
 * @param {string} category The category to filter by.
 * @returns {Array} Returns a new array of names.
 */
function getNamesByCategory(category) {
  return _.get(mapping.category, category, []);
}

/**
 * Gets the value of a given name from the `options` array. If no value is
 * available the `defaultValue` is returned.
 *
 * @private
 * @param {Array} options The options array to inspect.
 * @param {string|string[]} names The name(s) of the option.
 * @param {*} defaultValue The default option value.
 * @returns {*} Returns the option value.
 */
function getOption(options, names, defaultValue) {
  var isArr = _.isArray(defaultValue);
  names = _.isArray(names) ? names : [names];

  return _.reduce(options, function(result, option) {
    _.each(names, function(name) {
      if (isArr) {
        var array = optionToArray(name, option);
        result = _.isEmpty(array) ? result : array;
      } else {
        var value = optionToValue(name, option);
        result = value == null ? result : value;
      }
    });
    return result;
  }, defaultValue);
}

/**
 * Gets the real name of `alias`.
 *
 * @private
 * @param {string} alias The alias to resolve.
 * @returns {string} Returns the real name.
 */
function getRealName(alias) {
  return _.get(mapping.aliasToReal, alias, alias);
}

/**
 * Gets the real category of `alias`.
 *
 * @private
 * @param {string} alias The alias to resolve.
 * @returns {string} Returns the real category.
 */
function getRealCategory(alias) {
  return _.get(mapping.oldCategory, alias, alias);
}

/**
 * Creates an array variables names from all variables defined outside of
 * lodash functions.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {Array} Returns a new array of variable names.
 */
function getVars(source) {
  var isDeep = consts.reHasDeepVars.test(source),
      indentA = isDeep ? ' {2,4}' : ' {2}',
      indentB = isDeep ? ' {6,8}' : ' {6}',
      result = [];

  var patterns = [
    // Match varaibles at the start of a declaration list.
    ['^(' + indentA + 'var\\s+)([$\\w]+)\\s*=.+?,\\n *', 2, 1],
    // Match variable declarations in a declaration list.
    [',\\n' + consts.rsComment + indentB + '([$\\w]+)\\s*=[\\s\\S]+?(?=[,;]\\n)', 1, -1],
    // Match variables that aren't part of a declaration list.
    ['^(' + indentA + ')var\\s+([$\\w]+)\\s*(?:|=[^;]+);\\n', 2, -1]
  ];

  source = removeStrings(removeComments(source));

  _.each(listing.complexVars, function(varName) {
    source = modifyVar(source, varName, function() {
      result.push(varName);
      return '';
    });
  });

  return _.uniq(_.transform(patterns, function(result, pattern) {
    source = source.replace(RegExp(pattern[0], 'gm'), function() {
      result.push(arguments[pattern[1]]);
      return pattern[2] > -1 ? arguments[pattern[2]] : '';
    });
  }, result));
}

/**
 * Checks if `source` is a function snippet.
 *
 * @private
 * @param {string} source The source to inspect.
 * @returns {boolean} Returns `true` for a function snippet, else `false`.
 */
function isFunctionSnippet(source) {
  var header = getHeader(source);
  return consts.reHasFuncTags.test(header) || consts.reIsFuncSnippet.test(replace(source, header, ''));
}

/**
 * Checks if `identifier` is private.
 *
 * @private
 * @param {string} identifier The identifier to query.
 * @returns {boolean} Returns `true` if the identifier is private, else `false`.
 */
function isPrivate(identifier) {
  identifier = getRealName(identifier);
  if (_.includes(listing.categories, identifier)) {
    return false;
  }
  return _.isUndefined(_.findKey(mapping.category, function(identifiers) {
    return _.includes(identifiers, identifier);
  }));
}

/**
 * Checks if the variable `varName` is used in `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {string} varName The name of the variable.
 * @returns {boolean} Returns `true` if the variable is used, else `false`.
 */
function isVarUsed(source, varName) {
  var escapedName = _.escapeRegExp(varName);

  source = removeVar(source, varName);
  return RegExp('[^.$"\'\\w]' + escapedName + '\\b(?!\\s*=)').test(source);
}

/**
 * Searches `source` for a `funcName` function declaration, expression, or
 * assignment and returns the matched snippet.
 *
 * @private
 * @param {string} source The source to inspect.
 * @param {string} funcName The name of the function to match.
 * @param {boolean} [leadingComments] A flag to specify including leading comments.
 * @returns {string} Returns the matched function snippet.
 */
var matchFunction = _.memoize(function(source, funcName, leadingComments) {
  var escapedName = _.escapeRegExp(funcName),
      otherKey = funcName + ':' + !leadingComments;

  var patterns = [
    // Match function declarations.
    ['^(' + consts.rsComment + ')(( *)function\\s+' + escapedName + '\\((?:\\)\\s*\\{\\s*|[\\s\\S]+?\\n\\3)\\}\\n)', 2, 0],
    // Match single line function expressions at the start of a declaration list.
    ['^( *var\\s+)(' + escapedName + '\\s*=\\s*\\(?function\\b.+?\\}\\)?,\\n *)', 2, 2],
    // Match single line function expressions in a declaration list.
    ['(,\\n' + consts.rsComment + ')( *' + escapedName + '\\s*=\\s*\\(?function\\b.+?\\}\\)?(?=[,;]\\n))', 2, 0],
    // Match single line function expressions that aren't in a declaration list.
    ['^(' + consts.rsComment + ')( *var\\s+' + escapedName + '\\s*=\\s*\\(?function\\b.+?\\}\\)?;\\n)', 2, 0],
    // Match variable declarations containing built-in constructors.
    ['^( *var\\s+)(' + escapedName + '\\s*=\\s*root\\.(?:[A-Z][a-z0-9]+)+,\\n *)', 2, 2],
    ['(,\\n' + consts.rsComment + ')( *' + escapedName + '\\s*=\\s*root\\.(?:[A-Z][a-z0-9]+)+(?=[,;]\\n))', 2, 0],
    ['^(' + consts.rsComment + ')( *var\\s+' + escapedName + '\\s*=\\s*root\\.(?:[A-Z][a-z0-9]+)+;\\n)', 2, 0],
    // Match variable declarations using `baseProperty` or `basePropertyOf`.
    ['(,\\n' + consts.rsComment + ')( *' + escapedName + '\\s*=\\s*baseProperty(?:Of)?\\([\\s\\S]+?\\)(?=[,;]\\n))', 2, 0],
    ['^(' + consts.rsComment + ')( *var\\s+' + escapedName + '\\s*=\\s*baseProperty(?:Of)?\\([\\s\\S]+?\\);\\n)', 2, 0],
    // Match variable declarations using creator functions.
    ['(,\\n' + consts.rsComment + ')(( *)' + escapedName + '\\s*=\\s*create(?:[A-Z][a-z]+)+\\((?:.*|[\\s\\S]+?\\n\\3(?:\\S.*?)?)\\)(?=[,;]\\n))', 2, 0],
    ['^(' + consts.rsComment + ')(( *)var\\s+' + escapedName + '\\s*=\\s*create(?:[A-Z][a-z]+)+\\((?:.*|[\\s\\S]+?\\n\\3(?:\\S.*?)?)\\);\\n)', 2, 0],
    // Match variable declarations using `getNative`.
    ['^( *var\\s+)(' + escapedName + '\\s*=\\s*getNative\\(.+?\\),\\n *)', 2, 2],
    ['(,\\n' + consts.rsComment + ')( *' + escapedName + '\\s*=\\s*getNative\\(.+?\\)(?=[,;]\\n))', 2, 0],
    ['^(' + consts.rsComment + ')( *var\\s+' + escapedName + '\\s*=\\s*getNative\\(.+?\\);\\n)', 2, 0],
    // Match variable declarations using `overArg`.
    ['(,\\n' + consts.rsComment + ')( *' + escapedName + '\\s*=\\s*overArg\\([\\s\\S]+?\\)(?=[,;]\\n))', 2, 0],
    ['^(' + consts.rsComment + ')( *var\\s+' + escapedName + '\\s*=\\s*overArg\\([\\s\\S]+?\\);\\n)', 2, 0],
    // Match variable declarations using `shortOut`.
    ['(,\\n' + consts.rsComment + ')( *' + escapedName + '\\s*=\\s*shortOut\\([\\s\\S]+?\\)(?=[,;]\\n))', 2, 0],
    ['^(' + consts.rsComment + ')( *var\\s+' + escapedName + '\\s*=\\s*shortOut\\([\\s\\S]+?\\);\\n)', 2, 0],
    // Match variable declarations using `_.memoize` or `_.rest`.
    ['(,\\n' + consts.rsComment + ')(( *)' + escapedName + '\\s*=\\s*(?:[a-z]+Rest|memoize(?:Capped)?)\\((?:.+|[\\s\\S]+?\\n\\3\\})\\)(?=[,;]\\n))', 2, 0],
    ['^(' + consts.rsComment + ')(( *)var\\s+' + escapedName + '\\s*=\\s*(?:[a-z]+Rest|memoize(?:Capped)?)\\((?:.+|[\\s\\S]+?\\n\\3\\})\\);\\n)', 2, 0],
    // Match simple variable declaration.
    ['^(' + consts.rsComment + ')( *var\\s+' + escapedName + '\\s*=.+?;\\n)', 2, 0],
    // Match multiple line function expressions.
    ['^(' + consts.rsComment + ')(( *)var\\s+' + escapedName + '\\s*=.*?function\\b[\\s\\S]+?\\{\\n[\\s\\S]+?\\n\\3\\}(?:(?:\\(\\))?\\))?;\\n)', 2, 0]
  ];

  var result = _.reduce(patterns, function(result, pattern) {
    if (!result) {
      result = RegExp(pattern[0], 'm').exec(source) || '';
      if (isFunctionSnippet(_.get(result, 0))) {
        matchFunction.cache.set(otherKey, result[pattern[leadingComments ? 1 : 2]]);
        result = result[pattern[leadingComments ? 2 : 1]];
      }
    }
    return result;
  }, '');

  if (!result) {
    matchFunction.cache.set(otherKey, result);
  }
  return result;
}, function(source, funcName, leadingComments) {
  return funcName + ':' + !!leadingComments;
});

/**
 * Searches `source` for a lodash property, of the given property name, and
 * returns the matched snippet.
 *
 * @private
 * @param {string} source The source to inspect.
 * @param {string} propName The name of the property to match.
 * @param {boolean} [leadingComments] A flag to specify including leading comments.
 * @returns {string} Returns the matched property snippet.
 */
function matchProp(source, propName, leadingComments) {
  var escapedName = _.escapeRegExp(propName);

  return _.get(RegExp(
    '^' + (leadingComments ? consts.rsComment : '') +
    '(?: {2,4}var\\s+' + escapedName + '\\b.+|(?:\\s*|.*?=\\s*)lodash\\._?' + escapedName + '\\s*)=[\\s\\S]+?' +
    '(?:\\(function\\([\\s\\S]+?\\}\\([^)]*\\)\\);\\n(?=\\n)|' +
    '[;}]\\n(?=\\n(?!\\s*\\(function\\b)))'
  , 'm').exec(source), 0, '');
}

/**
 * Searches `source` for a `varName` variable assignment and returns
 * the matched snippet.
 *
 * @private
 * @param {string} source The source to inspect.
 * @param {string} varName The name of the variable to match.
 * @param {boolean} [leadingComments] A flag to specify including leading comments.
 * @returns {string} Returns the matched variable snippet.
 */
function matchVar(source, varName, leadingComments) {
  var escapedName = _.escapeRegExp(varName);

  var patterns = [
    // Match varaibles at the start of a declaration list.
    ['^( *var\\s+)(' + escapedName + '\\s*=.+?,\\n *)', 2, 2],
    // Match variables in a declaration list.
    ['(,\\n' + consts.rsComment + ')( *' + escapedName + '\\s*=[\\s\\S]+?(?=[,;]\\n))', 2, 0],
    // Match variable declarations that aren't in a declaration list.
    ['^(' + consts.rsComment + ')( *var\\s+' + escapedName + '\\s*(?:|=[^;]+);\\n)', 2, 0]
  ];

  // Match complex variable assignments.
  if (_.includes(listing.complexVars, varName)) {
    patterns.splice(2, 0, ['^(' + consts.rsComment + ')(( *)var\\s+' + escapedName + '\\s*=[\\s\\S]+?[};]\\n(?=\\s*\\n(?:\\S|\\3(?:function\\b|if\\b|lodash\\b|var\\s|/[/*]))))', 2, 0]);
  }
  return _.reduce(patterns, function(result, pattern) {
    return result || _.get(RegExp(pattern[0], 'm').exec(source), pattern[leadingComments ? 2 : 1], '');
  }, '');
}

/**
 * Modifies the `funcName` function of `source`.
 *
 * @private
 * @param {string} source The source to modify.
 * @param {string} funcName The name of the function to match.
 * @param {Function} replacer The function to modify the matched source.
 * @returns {string} Returns the modified source.
 */
function modifyFunction(source, funcName, replacer) {
  return replace(source, matchFunction(source, funcName), function(match) {
    var result = replacer(match);
    matchFunction.cache.set(funcName + ':false', result);
    matchFunction.cache.delete(funcName + ':true');
    return result;
  });
}

/**
 * Modifies the `propName` lodash property of `source`.
 *
 * @private
 * @param {string} source The source to modify.
 * @param {string} propName The name of the property to match.
 * @param {Function} replacer The function to modify the matched source.
 * @returns {string} Returns the modified source.
 */
function modifyProp(source, propName, replacer) {
  return replace(source, matchProp(source, propName), _.unary(replacer));
}

/**
 * Modifies the `varName` variable of `source`.
 *
 * @private
 * @param {string} source The source to modify.
 * @param {string} varName The name of the variable to match.
 * @param {Function} replacer The function to modify the matched source.
 * @returns {string} Returns the modified source.
 */
function modifyVar(source, varName, replacer) {
  return replace(source, matchVar(source, varName), _.unary(replacer));
}

/**
 * Converts a comma separated option value into an array.
 *
 * @private
 * @param {string} name The name of the option to inspect.
 * @param {string} string The options string.
 * @returns {Array} Returns the new converted array.
 */
function optionToArray(name, string) {
  return _.compact(_.invokeMap((optionToValue(name, string) || '').split(/, */), 'trim'));
}

/**
 * Extracts the option value from an option string.
 *
 * @private
 * @param {string} name The name of the option to inspect.
 * @param {string} string The options string.
 * @returns {string|undefined} Returns the option value, else `undefined`.
 */
function optionToValue(name, string) {
  var result = RegExp('^' + _.escapeRegExp(name) + '(?:=([\\s\\S]+))?$').exec(string);
  if (result) {
    result = _.get(result, 1);
    result = result ? _.trim(result) : true;
  }
  return (result !== 'false') && (result || undefined);
}

/**
 * Removes all lodash method and property assignments from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function removeAssignments(source) {
  // Remove method and intermediate assignments.
  source = removeMethodAssignments(source);
  return source.replace(/(=\s*)lodash\.[$\w]+\s*=\s*/g, '$1');
}

/**
 * Removes support for lodash wrapper chaining in `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {Object} [seqDepMap] The chain dependency map to modify.
 * @param {Object} [funcDepMap] The function dependency map to modify.
 * @param {Object} [varDepMap] The variable dependency map to modify.
 * @returns {string} Returns the modified source.
 */
function removeChaining(source, seqDepMap, funcDepMap, varDepMap) {
  source = removeLazyChaining(source, seqDepMap, funcDepMap, varDepMap);
  source = removeMixinCalls(source);

  // Remove all `lodash.prototype` additions.
  return source
    .replace(/^(?: *\/\/.*\n)*( *)[$\w]+\(\['pop'[\s\S]+?\n\1\}\);\n/m, '')
    .replace(/^(?: *\/\/.*\n)*( *)if\s*\(symIterator\)[\s\S]+?\n\1\}\n/gm, '')
    .replace(/^(?: *\/\/.*\n)*( *)lodash\.prototype\.(?!constructor\b)[$\w]+\s*=[\s\S]+?;\n/gm, '');
}

/**
 * Removes all comments from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function removeComments(source) {
  return replace(source, consts.reComment, '');
}

/**
 * Removes the `getTag` fork from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function removeGetTagFork(source) {
  return replace(source, getGetTagFork(source), '');
}

/**
 * Removes support for lazy chaining in `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {Object} [seqDepMap] The chain dependency map to modify.
 * @param {Object} [funcDepMap] The function dependency map to modify.
 * @param {Object} [varDepMap] The variable dependency map to modify.
 * @returns {string} Returns the modified source.
 */
function removeLazyChaining(source, seqDepMap, funcDepMap, varDepMap) {
  if (seqDepMap) {
    _.pull(seqDepMap.varDep, 'realNames');

    _.pull(seqDepMap.funcDep,
      'baseInvoke', 'baseRest', 'createHybrid', 'getIteratee', 'identity',
      'isArray', 'last', 'lazyClone', 'lazyReverse', 'lazyValue', 'LazyWrapper',
      'toInteger', 'wrapperAt', 'wrapperReverse'
    );
  }
  if (funcDepMap) {
    funcDepMap.createFlow = ['baseFlatten', 'flatRest'];
  }
  if (varDepMap) {
    source = removeVar(source, 'realNames');
    _.forOwn(varDepMap, function(depNames, identifier) {
      _.pull(depNames, 'realNames');
    });
  }
  source = replaceFunction(source, 'createFlow', [
    'function createFlow(fromRight) {',
    '  return flatRest(function(funcs) {',
    '    funcs = baseFlatten(funcs, 1);',
    '',
    '    var length = funcs.length,',
    '        index = length;',
    '',
    '    if (fromRight) {',
    '      funcs.reverse();',
    '    }',
    '    while (index--) {',
    "      if (typeof funcs[index] != 'function') {",
    '        throw new TypeError(FUNC_ERROR_TEXT);',
    '      }',
    '    }',
    '    return function() {',
    '      var index = 0,',
    '          result = length ? funcs[index].apply(this, arguments) : arguments[0];',
    '',
    '      while (++index < length) {',
    '        result = funcs[index].call(this, result);',
    '      }',
    '      return result;',
    '    };',
    '  });',
    '}'
  ].join('\n'));

  return source
    // Remove bulk `LazyWrapper.prototype` assignments.
    .replace(/^(?: *\/\/.*\n)*( *)arrayEach\(\['(?:drop|filter|head|initial)\b[\s\S]+?\n\1\}\);\n/gm, '')
    // Remove individual `LazyWrapper` method assignments.
    .replace(/^(?: *\/\/.*\n)*( *)LazyWrapper\.prototype\.(?:compact|find|findLast|invokeMap|reject|slice|takeRightWhile|toArray)\s*=[\s\S]+?\n\1\}.*?;\n/gm, '')
    // Remove other `LazyWrapper.prototype` assignments.
    .replace(/^(?: *\/\/.*\n)* *LazyWrapper\.prototype\.(?!constructor\b)[$\w]+\s*=[^;]+;\n/gm, '')
    // Remove `LazyWrapper` additions to `LodashWrapper` and `realNames` assignments.
    .replace(/^(?: *\/\/.*\n)*( *)baseForOwn\(LazyWrapper\.prototype\b[\s\S]+?\n\1\}\);\n/gm, '')
    // Remove `realNames` assignment for `wrapper`.
    .replace(/^(?: *\/\/.*\n)* *realNames\[createHybrid\b[\s\S]+?;\n/m, '')
    // Remove lazy alias `lodash.prototype` assignments.
    .replace(/^(?: *\/\/.*\n)* *lodash\.prototype\.first\s*=[^;]+;\n/gm, '');
}

/**
 * Removes metadata optimizations from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {Object} [funcDepMap] The function dependency map to modify.
 * @returns {string} Returns the modified source.
 */
function removeMetadata(source, funcDepMap) {
  var deps = _.get(funcDepMap, 'createWrap', []);
  _.pull(deps, 'baseSetData', 'getData', 'mergeData', 'setData');

  deps = _.get(funcDepMap, 'createRecurry', []);
  _.pull(deps, 'isLaziable', 'setData');

  // Remove metadata related code.
  source = modifyFunction(source, 'createWrap', function(match) {
    match = _.reduce(['data', 'funcBitmask', 'funcIsPartialed', 'setter'], removeVar, match);
    return match
      .replace(/^(?: *\/\/.*\n)*( *)if\s*\((?:typeof\s+)?data\b[\s\S]+?\n\1\}\n/gm, '')
      .replace(/\bsetter\(([^,]+),[^)]+\)/, '$1');
  });

  source = modifyFunction(source, 'createRecurry', function(match) {
    match = removeVar(match, 'newData');
    match = replaceVar(match, 'result', 'wrapFunc(func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, newHoldersRight, argPos, ary, arity)');
    return match.replace(/^(?: *\/\/.*\n)*( *)if\s*\(isLaziable\b[\s\S]+?\n\1\}\n/m, '');
  });

  return source;
}

/**
 * Removes the `funcName` function declaration, expression, or assignment and
 * associated code from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {string} funcName The name of the function to remove.
 * @returns {string} Returns the modified source.
 */
function removeFunction(source, funcName) {
  source = toString(source);
  source = funcName == 'runInContext'
    ? removeRunInContext(source, funcName)
    : replace(source, matchFunction(source, funcName, true), '');

  matchFunction.cache.set(funcName + ':true', '');
  matchFunction.cache.set(funcName + ':false', '');
  return source;
}

/**
 * Removes all references to `getIteratee` from `source` and replaces calls
 * with `baseIteratee`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {Object} [funcDepMap] The function dependency map to modify.
 * @returns {string} Returns the modified source.
 */
function removeGetIteratee(source, funcDepMap) {
  source = removeFunction(source, 'getIteratee');

  _.forOwn(funcDepMap, function(deps, identifier) {
    if (_.includes(deps, 'getIteratee')) {
      _.pull(deps, 'getIteratee');
      if (!_.includes(deps, 'baseIteratee')) {
        deps.push('baseIteratee');
      }
      source = modifyFunction(source, identifier, function(match) {
        return match.replace(consts.reGetIteratee, 'baseIteratee');
      });
    }
  });

  return source.replace(getMethodAssignments(source), function(match) {
    var deps = _.get(funcDepMap, 'main', []);
    if (_.includes(deps, 'baseIteratee')) {
      match = match.replace(consts.reGetIteratee, 'baseIteratee');
    }
    return match;
  });
}

/**
 * Removes the copyright header from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function removeHeader(source) {
  return replace(source, getHeader(source), '');
}

/**
 * Removes the `@license` tag from the copyright header so minifiers
 * and build optimizers may strip them.
 *
 * @private
 * @param {string} source The source to inspect.
 * @returns {string} Returns the modified source.
 */
function removeLicenseTag(source) {
  return replace(source, /^ \* *@license\n/m, '');
}

/**
 * Removes a method assignment by name from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {string} [methodName] The name of the method assignment to remove.
 * @returns {string} Returns the modified source.
 */
function removeMethodAssignment(source, methodName) {
  return replace(source, getMethodAssignments(source), function(match) {
    var pattern = RegExp(
      '^( *//.*\\n)*( *)' +
      '(?:lodash(?:\\.prototype)?\\.[$\\w]+\\s*=\\s*)*' +
      'lodash(?:\\.prototype)?\\.' +
      '(?:[$\\w]+\\s*=\\s*' + methodName + '|' + methodName + '\\s*=\\s*(?:[$\\w]+|function\\b[\\s\\S]+?\\n\\2\\}));' +
      '\\n(\\n)?'
    , 'gm');

    return match.replace(pattern, function(match, comment, indent, newline) {
      return newline || comment || '';
    });
  });
}

/**
 * Removes all lodash method assignments from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function removeMethodAssignments(source) {
  return replace(source, getMethodAssignments(source), '');
}

/**
 * Removes all `_.mixin` calls from `source`.
 *
 * @private
 * @param {string} source The source to inspect.
 * @returns {string} Returns the modified source.
 */
function removeMixinCalls(source) {
  return replace(source, /^(?: *\/\/.*\n)*( *)mixin\(.+?(?:\{[\s\S]+?\n\1\}.+?)?\);\n/gm, '');
}

/**
 * Removes a lodash property, of the given property name, from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {string} propName The name of the property to remove.
 * @returns {string} Returns the modified source.
 */
function removeProp(source, propName) {
  return replace(source, matchProp(source, propName, true), '');
}

/**
 * Removes all `runInContext` references from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function removeRunInContext(source) {
  source = removeFunction(source, 'clearTimeout');
  source = removeFunction(source, 'setTimeout');
  source = removeMethodAssignment(source, 'runInContext');
  source = removeVar(source, 'contextProps');

  // Remove function scaffolding, leaving most of its content.
  source = replace(source, matchFunction(source, 'runInContext', true), function(match) {
    // Remove function frame.
    match = match.replace(/^[\s\S]+?function\s+runInContext\b[\s\S]+?context\s*=\s*context.+?\n+| *return\s+lodash;[\s\S]+$/g, '');
    match = replaceIndent(match, 1, 2);

    // Remove built-in vars and related `context` references.
    _.each(listing.builtins, function(builtin) {
      match = removeVar(match, builtin);
      match = match.replace(RegExp('\\bcontext\\.(?=' + builtin + '\\b)', 'g'), '');
    });

    // Remove `ctx` vars.
    _.each(['ctxClearTimeout', 'ctxNow', 'ctxSetTimeout'], function(varName) {
      match = removeVar(match, varName);
      match = match.replace(RegExp('\\b' + varName + '\\s*\\|\\|\\s*'), '');
    });

    // Replace remaining `context` references with `root`.
    return match.replace(/\bcontext\b/g, 'root');
  });

  return source
    // Remove `_` assignment.
    .replace(/^(?: *\/\/.*\n)* *var\s+_\s*=\s*runInContext\b.+\n+/m, '')
    // Replace `_` references with `lodash`.
    .replace(/(\breturn\s+|=\s*)_([;)])/g, '$1lodash$2');
}

/**
 * Removes all strings from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @returns {string} Returns the modified source.
 */
function removeStrings(source) {
  return replace(source, consts.reString, '');
}

/**
 * Removes a variable of the given variable name from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {string} varName The name of the variable to remove.
 * @returns {string} Returns the modified source.
 */
function removeVar(source, varName) {
  return replace(source, matchVar(source, varName, true), '');
}

/**
 * Replaces `pattern` matches in `string` with the resolved `replacement` value.
 *
 * @private
 * @param {string} string The string to modify.
 * @param {RegExp|string} pattern The pattern to match.
 * @param {Function|string} replacement The replacement value.
 * @returns {string} Returns the modified string.
 */
function replace(string, pattern, replacement) {
  string = toString(string);
  return pattern ? string.replace(pattern, replacement) : string;
}

/**
 * Replaces the `funcName` function body in `source` with `funcValue`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {string} funcName The name of the function to replace.
 * @param {string} funcValue The replacement value.
 * @returns {string} Returns the modified source.
 */
function replaceFunction(source, funcName, funcValue) {
  var leadingComments = consts.reIsVarSnippet.test(funcValue);

  return replace(source, matchFunction(source, funcName, leadingComments), function(match) {
    var header = leadingComments ? getHeader(match) : '';
    if (!isFunctionSnippet(match)) {
      header = header.replace(/^( *)\* *(?:@(?:category|param|returns)\b|\/)/m, function(match, indent) {
        return indent + '* @type +\{Function\}\n' + match;
      });
    }
    funcValue = funcValue
      .replace(RegExp('^' + getIndent(funcValue), 'gm'), getIndent(match))
      .trimRight() + '\n';

    if (leadingComments) {
      matchFunction.cache.set(funcName + ':false', funcValue);
    } else {
      matchFunction.cache.delete(funcName + ':true');
    }
    var result = header + funcValue;
    matchFunction.cache.set(funcName + ':' + leadingComments, result);
    return result;
  });
}

/**
 * Replaces the IIFE that wraps `source` with `iife`. If the `%output%` token
 * is present in `iife` it will be replaced with the unwrapped `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {string} iife The replacement IIFE.
 * @returns {string} Returns the modified source.
 */
function replaceIIFE(source, iife) {
  source = toString(source);
  iife = toString(iife);

  var token = '%output%',
      header = getHeader(source),
      index = iife.indexOf(token);

  if (index < 0) {
    return header + iife;
  }
  return header +
    iife.slice(0, index) +
    source.replace(/^[\s\S]+?\(function[^{]+\{\n+|\s*\}\.call\(this\)\)[;\s]*$/g, '\n') +
    iife.slice(index + token.length);
}

/**
 * Replaces the indent at level `from` of the given source with the level `to`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {number} [to=0] The indent level to replace with.
 * @param {number} [from=1] The indent level to be replaced.
 * @returns {string} Returns the modified source.
 */
function replaceIndent(source, to, from) {
  source = toString(source);
  if (from === undefined) {
    from = floor(getIndent(source).length / 2);
  }
  return source.replace(RegExp('^(?:  ){' + (from || 1) + '}', 'gm'), _.repeat('  ', to || 0));
}

/**
 * Replaces the `varName` variable declaration value in `source` with `varValue`.
 *
 * @private
 * @param {string} source The source to inspect.
 * @param {string} varName The name of the variable to replace.
 * @param {string} varValue The replacement value.
 * @returns {string} Returns the modified source.
 */
function replaceVar(source, varName, varValue) {
  source = toString(source);

  var escapedName = _.escapeRegExp(varName),
      modified = false;

  // Replace a variable that's not part of a declaration list.
  source = source.replace(RegExp(
    '(( *)var\\s+' + escapedName + '\\s*=)' +
    '(?:.+?;|(?:Function\\(.+?|.*?[^,])\\n[\\s\\S]+?\\n\\2.+?;)\\n'
  ), function(match, left) {
    modified = true;
    return left + ' ' + varValue + ';\n';
  });

  if (!modified) {
    // Replace a varaible at the start or middle of a declaration list.
    source = source.replace(RegExp('((?:var|\\n)\\s+' + escapedName + '\\s*=).+?(?=,\\n)'), function(match, left) {
      modified = true;
      return left + ' ' + varValue;
    });
  }
  if (!modified) {
    // Replace a variable at the end of a variable declaration list.
    source = source.replace(RegExp('(,\\s*' + escapedName + '\\s*=).+?(?=;\\n)'), function(match, left) {
      return left + ' ' + varValue;
    });
  }
  return source;
}

/**
 * Add or remove the "use strict" directive from `source`.
 *
 * @private
 * @param {string} source The source to process.
 * @param {boolean} value The value to set.
 * @returns {string} Returns the modified source.
 */
function setUseStrictOption(source, value) {
  return replace(source, /^([\s\S]*?function[^{]+\{)(?:\s*'use strict';)?/, '$1' + (value ? "\n  'use strict';" : ''));
}

/**
 * Invokes `callback` providing `source` with strings removed and returns the
 * modified source with strings restored.
 *
 * @private
 * @param {string} source The source to modify.
 * @param {Function} [callback] The function to modify the string free source.
 * @returns {string} Returns the modified source.
 */
function stringFree(source, callback) {
  var strings = [];
  source = callback(replace(source, consts.reString, function(match) {
    var index = strings.length;
    strings.push(match);
    return '<#str_token' + index + '#>';
  })) || '';

  return replace(source, consts.reStringToken, function(match) {
    return strings[match.slice(11, -2)];
  });
}

/**
 * Converts `value` to a string if it's not one.
 * An empty string is returned for `null` and `undefined` values.
 *
 * @private
 * @param {*} value The value to process.
 * @returns {string} Returns the string.
 */
function toString(value) {
  if (typeof value == 'string') {
    return value;
  }
  return value == null ? '' : (value + '');
}

/*----------------------------------------------------------------------------*/

/**
 * Creates a development and/or production build invoking `callback` for each.
 * The `callback` is invoked with one argument: (data).
 *
 * **Note:** For a list of commands see `consts.helpText` or run `lodash --help`.
 *
 * @param {Array|Object} [options=[]] An array of build commands or the state object.
 * @param {Function} [callback=defaultBuildCallback] The function called per build.
 */
function build(options, callback) {
  options || (options = []);
  callback || (callback = defaultBuildCallback);

  // Used to specify the output path for builds.
  var outputPath;

  // Used to specify the source map URL.
  var sourceMapURL;

  // Used to track the time it takes to complete a build.
  var stamp = _.now();

  // Used to pre-populate the build state.
  var state = _.isPlainObject(options) && options;

  var isExcluded = function() {
    return _.every(arguments, function(value) {
      return !_.includes(buildFuncs, value);
    });
  };

  if (state) {
    var buildFuncs = state.buildFuncs,
        filePath = state.filePath,
        funcDepMap = state.funcDepMap,
        funcTokenMap = state.funcTokenMap,
        includeFuncs = state.includeFuncs,
        includeVars = state.includeVars,
        isDevelopment = true,
        isModularize = true,
        isStdOut = state.isStdOut,
        isStrict = state.isStrict,
        minusFuncs = [],
        outputPath = state.outputPath,
        plusFuncs = [],
        source = state.source,
        varDepMap = state.varDepMap,
        varNames = state.varNames;
  }
  else {
    // Clear `matchFunction` memoize cache.
    matchFunction.cache.clear();

    // Clone dependencies to modify.
    var seqDepMap = new Hash(_.cloneDeep(mapping.seqDep)),
        funcDepMap = new Hash(_.cloneDeep(mapping.funcDep)),
        varDepMap = new Hash(_.cloneDeep(mapping.varDep));

    // The path to the source file.
    var filePath = require.resolve('lodash');

    // Used to specify a custom IIFE to wrap lodash.
    var iife = getOption(options, 'iife');

    // Used to match external template files to precompile.
    var templatePattern = getOption(options, 'template', '');

    // Used as the template settings for precompiled templates.
    var templateSettings = (function() {
      var result = getOption(options, 'settings');
      return result
        ? Function('return {' + result.replace(/^\{|\}$/g, '') + '}')()
        : _.clone(_.templateSettings);
    }());

    // A flag to specify a core build.
    var isCore = getOption(options, 'core');

    // A flag to specify only creating the development build.
    var isDevelopment = getOption(options, ['-d', '--development']);

    // A flag to indicate that a custom IIFE was specified.
    var isIIFE = typeof iife == 'string';

    // A flag to specify creating a source map for the minified source.
    var isMapped = getOption(options, ['-m', '--source-map']);

    // A flag to specify a modularize build.
    var isModularize = getOption(options, 'modularize');

    // A flag to specify only creating the minified build.
    var isProduction = getOption(options, ['-p', '--production']);

    // A flag to specify writing output to standard output.
    var isStdOut = getOption(options, ['-c', '--stdout']);

    // A flag to specify skipping status updates normally logged to the console.
    var isSilent = !isBin || isStdOut || getOption(options, ['-s', '--silent']);

    // A flag to specify `_.assign`, `_.bindAll`, and `_.defaults`
    // are constructed using the "use strict" directive.
    var isStrict = getOption(options, 'strict');

    // A flag to specify a template build.
    var isTemplate = !!templatePattern;

    // Used to specify the AMD module ID of lodash used by precompiled templates.
    var moduleId = getOption(options, 'moduleId');

    // Used as the output path for the build.
    var outputPath = _.reduce(options, function(result, value, index) {
      return /^(?:-o|--output)$/.test(value)
        ? path.normalize(options[index + 1])
        : result;
    }, isModularize ? ('.' + path.sep + 'modularize') : '');

    // Used to specify the ways to export the `lodash` function.
    var exportsOptions = (function() {
      var result = getOption(options, 'exports', buildExports.defaults[isModularize ? 'modularize' : 'monolithic']);
      if (!isModularize && _.includes(result, 'umd')) {
        result = _.union(result, buildExports.umd);
      }
      return isModularize ? _.take(result, 1) : result;
    }());

    // A flag to specify creating a custom build.
    var isCustom = !isModularize && (
      isCore || isMapped || isStrict || isTemplate ||
      /\b(?:category|exports|iife|include|minus|moduleId|plus)=/.test(options) ||
      !_.isEqual(exportsOptions, buildExports.defaults.monolithic)
    );

    // Flags to specify export options.
    var isAMD = _.includes(exportsOptions, 'amd'),
        isES = _.includes(exportsOptions, 'es'),
        isGlobal = _.includes(exportsOptions, 'global'),
        isNpm = _.includes(exportsOptions, 'npm'),
        isNode = isNpm || _.includes(exportsOptions, 'node');

    if (isTemplate) {
      isModularize = false;
    }
    // The lodash.js source.
    var source = fs.readFileSync(filePath, 'utf8');

    /*------------------------------------------------------------------------*/

    // Categories of functions to include in the build.
    var categoryOptions = _.map(getOption(options, 'category', []), function(category) {
      return getRealCategory(_.capitalize(category.toLowerCase()));
    });

    // Functions to include in the build.
    var includeFuncs = _.union(categoryOptions, _.map(getOption(options, 'include', []), getRealName));

    // Variables to include in the build.
    var includeVars = _.intersection(includeFuncs, listing.varDeps);

    // Functions to remove from the build.
    var minusFuncs = _.map(getOption(options, 'minus', []), getRealName);

    // Functions to add to the build.
    var plusFuncs = _.map(getOption(options, 'plus', []), getRealName);

    // Expand categories to function names.
    _.each([includeFuncs, minusFuncs, plusFuncs], function(funcNames) {
      var categories = _.intersection(funcNames, listing.categories);

      _.each(categories, function(category) {
        push.apply(funcNames, _.filter(getNamesByCategory(category), function(key) {
          var type = typeof _[key];
          return type == 'function' || type == 'undefined';
        }));
      });
    });

    // Remove categories from function names.
    includeFuncs = _.difference(includeFuncs, listing.categories, includeVars);
    minusFuncs = _.difference(minusFuncs, listing.categories);
    plusFuncs = _.difference(plusFuncs, listing.categories);

    /*------------------------------------------------------------------------*/

    // Used to capture warnings for invalid command-line arguments.
    var warnings = [];

    // Used to detect invalid command-line arguments.
    var invalidArgs = _.reject(options, function(value, index, options) {
      if (/^(?:-o|--output)$/.test(options[index - 1]) ||
          /^(?:category|exports|iife|include|minus|moduleId|plus|settings|template)=[\s\S]*$/.test(value)) {
        return true;
      }
      var result = _.includes(listing.buildFlags, value);
      if (!result && /^(?:-m|--source-map)$/.test(options[index - 1])) {
        sourceMapURL = value;
        return true;
      }
      return result;
    });

    // Report invalid command and option arguments.
    if (!_.isEmpty(invalidArgs)) {
      warnings.push('Invalid argument' + (_.size(invalidArgs) > 1 ? 's' : '') + ' passed: ' + invalidArgs.join(', '));
    }
    // Report invalid command entries.
    _.forOwn({
      'category': {
        'entries': categoryOptions,
        'validEntries': listing.categories
      },
      'exports': {
        'entries': exportsOptions,
        'validEntries': buildExports[isModularize ? 'modularize' : 'monolithic']
      },
      'include': {
        'entries': includeFuncs,
        'validEntries': listing.funcs
      },
      'minus': {
        'entries': minusFuncs,
        'validEntries': listing.funcs
      },
      'plus': {
        'entries': plusFuncs,
        'validEntries': listing.funcs
      }
    }, function(data, commandName) {
      invalidArgs = _.difference(data.entries, data.validEntries, ['none']);
      if (!_.isEmpty(invalidArgs)) {
        warnings.push('Invalid `' + commandName + '` entr' + (_.size(invalidArgs) > 1 ? 'ies' : 'y') + ' passed: ' + invalidArgs.join(', '));
      }
    });

    if (!_.isEmpty(warnings)) {
      var warnText = [
        '',
        warnings,
        'For more information type: lodash --help'
      ].join('\n');

      if (isBin) {
        console.warn(warnText);
        process.exit(1);
      } else {
        callback(_.create(Error.prototype, { 'message': warnText, 'source': warnText }));
      }
      return;
    }
    // Display the help message.
    if (getOption(options, ['-h', '--help'])) {
      var helpText = consts.helpText;
      if (isBin) {
        console.log(helpText);
      } else {
        callback({ 'source': helpText });
      }
      return;
    }
    // Display the `lodash.VERSION`.
    if (getOption(options, ['-V', '--version'])) {
      if (isBin) {
        console.log(_.VERSION);
      } else {
        callback({ 'source': _.VERSION });
      }
      return;
    }

    /*------------------------------------------------------------------------*/

    // The names of functions to include in the build.
    var buildFuncs = !isTemplate && (function() {
      source = setUseStrictOption(source, isStrict);

      if (isModularize) {
        // Remove `clearTimeout` and `setTimeout` deps.
        _.forOwn(funcDepMap, function(depNames) {
          _.pull(depNames, 'clearTimeout', 'setTimeout');
        });

        // Remove `lodash.placeholder` references.
        _.pull(funcDepMap.getHolder, 'lodash');

        source = modifyFunction(source, 'getHolder', function(match) {
          return replaceVar(match, 'object', 'func');
        });

        // Add deps to wrap `_.mixin` in `main`.
        funcDepMap.main.push('baseFunctions', 'isObject', 'keys', 'mixin');
      }
      else {
        // Add `arrayEach` to functions with placeholder support because it's
        // used to reduce code for placeholder assignments
        _.each(listing.placeholderFuncs, function(funcName) {
          funcDepMap[funcName].push('arrayEach');
        });
      }
      if (isModularize) {
        if (isNpm) {
          source = removeChaining(source, seqDepMap, funcDepMap, varDepMap);
          source = removeMetadata(source, funcDepMap);
        }
        // Remove `getIteratee` use from iteration methods.
        _.each(['forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'times'], function(funcName) {
          _.pull(funcDepMap[funcName], 'getIteratee').push('castFunction');
          source = modifyFunction(source, funcName, function(match) {
            return match.replace(/\bgetIteratee\(([^,\)]+)[\s\S]*?\)/, 'castFunction($1)');
          });
        });
      }
      if (isCore && _.isEmpty(plusFuncs)) {
        source = removeLazyChaining(source, seqDepMap, funcDepMap, varDepMap);
        source = removeMetadata(source, funcDepMap);

        // Add `func` check to `createPartial`.
        source = modifyFunction(source, 'createPartial', function(match) {
          return match.replace(/^( *)(?=var\b)/m, function(match, indent) {
            var prelude = '\n' + indent;
            return indent + [
              "if (typeof func != 'function') {",
              '  throw new TypeError(FUNC_ERROR_TEXT);',
              '}'
            ].join(prelude) + prelude;
          });
        });

        // Remove `apply` and `isSymbol`.
        _.forOwn(funcDepMap, function(depNames, identifier) {
          if (_.includes(depNames, 'apply')) {
            _.pull(depNames, 'apply');
            source = modifyFunction(source, identifier, function(match) {
              return match.replace(/\bapply\(([^,)]+),\s*([^,)]+),\s*([^,)]+)\)/g, '$1.apply($2, $3)');
            });
          }
          if (_.includes(depNames, 'isSymbol')) {
            _.pull(depNames, 'isSymbol');
            source = modifyFunction(source, identifier, function(match) {
              return match.replace(/\bisSymbol\([^)]+\)/g, 'false');
            });
          }
        });

        // Remove chain dependencies.
        _.pull(seqDepMap.funcDep,
          'baseLodash', 'wrapperCommit', 'wrapperNext',
          'wrapperPlant', 'wrapperToIterator'
        );

        // Remove ES5 and ES2015 built-in constructor deps.
        _.forOwn(funcDepMap, function(deps) {
          _.pull(deps, 'DataView', 'Map', 'Promise', 'Reflect', 'Set', 'Symbol', 'Uint8Array', 'WeakMap');
        });

        // Remove map, set, stack, and typed array support from `baseIsEqualDeep`.
        _.pull(funcDepMap.baseIsEqualDeep, 'getTag', 'isBuffer', 'isTypedArray', 'Stack').push('baseGetTag', 'find');

        source = modifyFunction(source, 'baseIsEqualDeep', function(match) {
          return match
            .replace(/\bgetTag\b/g, 'baseGetTag')
            .replace(/\s*\|\|\s*isTypedArray\([^)]+\)/, '')
            .replace(/^( *)if\s*\(.+?isBuffer\b[\s\S]+?\n\1\}\n/m, '')
            .replace(/^( *)stack\s*\|\|[\s\S]+?\breturn\b([^;]+)(?=;\n)/gm, function(match, indent, compared) {
              return indent + [
                'var result =' + compared + ';',
                "stack.pop();",
                'return result'
              ].join('\n' + indent);
            })
            .replace(/^ *(?=if\s*\(isSameTag\b)/m, function(indent) {
              return indent + [
                'stack || (stack = []);',
                'var objStack = find(stack, function(entry) {',
                '  return entry[0] == object;',
                '});',
                'var othStack = find(stack, function(entry) {',
                '  return entry[0] == other;',
                '});',
                'if (objStack && othStack) {',
                '  return objStack[1] == other;',
                '}',
                'stack.push([object, other]);',
                'stack.push([other, object]);',
                ''
              ].join('\n' + indent);
            });
        });

        // Remove `baseLodash` references.
        _.each(['lodash', 'LodashWrapper'], function(funcName) {
          _.pull(funcDepMap[funcName], 'baseLodash');
        });

        source = source.replace(/\bbaseLodash\.prototype\b/g, 'lodash.prototype');

        // Remove `guard` check from `createAssigner`.
        _.pull(funcDepMap.createAssigner, 'isIterateeCall');

        source = modifyFunction(source, 'createAssigner', function(match) {
          match = removeVar(match, 'guard');
          return match.replace(/^(?: *\/\/.*\n)*( *)if\s*\(guard\b[^}]+?\n\1\}\n/m, '');
        });

        // Remove set cache use from `equalArrays`.
        _.pull(funcDepMap.equalArrays, 'cacheHas', 'SetCache').push('indexOf');

        source = modifyFunction(source, 'equalArrays', function(match) {
          return match
            .replace(/\bnew SetCache\b/, '[]')
            .replace(/\bcacheHas\b/, 'indexOf')
            .replace(/\badd\b/, 'push');
        });

        // Remove array buffer, data view, map, set, and symbol support from `equalByTag`.
        _.pull(funcDepMap.equalByTag, 'mapToArray', 'setToArray');

        source = modifyFunction(source, 'equalByTag', function(match) {
          return match.replace(/^( *)  case\s*(?:arrayBuffer|dataView|map|set|symbol)Tag\b[\s\S]+?(?=\s*case\b|\n\1\})/gm, '');
        });

        // Remove stack use from `equalArrays`, `equalByTag`, and `equalObjects`.
        _.each(['equalArrays', 'equalByTag', 'equalObjects'], function(funcName) {
          source = modifyFunction(source, funcName, function(match) {
            match = removeVar(match, 'stacked');
            return match
              .replace(/^( *)if\s*\(stacked\b[^}]+?\n\1\}\n/m, '')
              .replace(/^ *stack\.set\([^)]+\);\n/gm, '')
              .replace(/^ *stack\['delete'\]\([^)]+\);\n/gm, '');
          });
        });

        // Remove `customizer` use from `equalArrays` and `equalObjects`.
        _.each(['equalArrays', 'equalObjects'], function(funcName) {
          source = modifyFunction(source, funcName, function(match) {
            return match.replace(/^( *)if\s*\(customizer\b[\s\S]+?\n\1}/m, '$1var compared;');
          });
        });

        // Remove switch statements from functions.
        _.each(['createCtor', 'negate'], function(funcName) {
          source = modifyFunction(source, funcName, function(match) {
            return match.replace(/^(?: *\/\/.*\n)*( *)switch\b[\s\S]+?\n\1\}\n/m, '');
          });
        });

        // Remove `LazyWrapper` references.
        _.pull(funcDepMap.baseWrapperValue, 'LazyWrapper');

        source = modifyFunction(source, 'baseWrapperValue', function(match) {
          return match.replace(/^( *)if\b.+?LazyWrapper\b[\s\S]+?\n\1}\n/m, '');
        });

        // Remove unneeded properties from `LodashWrapper.
        source = modifyFunction(source, 'LodashWrapper', function(match) {
          return match.replace(/^ *this\.__(?:index|values)__\s*=[^;]+;\n/gm, '');
        });

        // Replace array functions with their base counterparts.
        _.each(['arrayEach', 'arrayFilter', 'arrayMap', 'arraySome', 'arrayReduce'], function(arrayName) {
          var reArrayName = RegExp('\\b' + arrayName + '\\b', 'g');

          var baseName = arrayName == 'arrayReduce'
            ? arrayName.replace(/^array/, '').toLowerCase()
            : arrayName.replace(/^array/, 'base');

          _.forOwn(funcDepMap, function(deps, funcName) {
            if (_.includes(deps, arrayName)) {
              _.pull(deps, arrayName).push(baseName);

              source  = modifyFunction(source, funcName, function(match) {
                return match.replace(reArrayName, baseName);
              });
            }
          });
        });

        // Replace `arrayEach` with `baseEach` in the chain scaffolding.
        _.each([seqDepMap.funcDep, funcDepMap.mixin], function(depMap) {
          _.pull(depMap, 'arrayEach').push('baseEach');
        });

        source = source.replace(/^(?: *\/\/.*\n)*( *)[$\w]+\(\['pop'[\s\S]+?\n\1\}\);\n/m, function(match) {
          return match
            .replace(/\barrayEach\b/g, 'baseEach')
            .replace("'pop',", "$& 'join', 'replace', 'reverse', 'split',")
            .replace(/\bpop\|/, '$&join|replace|')
            .replace(/func\s*=[\s\S]+?(?=,\n)/, function() {
              return 'func = (/^(?:replace|split)$/.test(methodName) ? String.prototype : arrayProto)[methodName]';
            });
        });

        // Replace `getAllKeys` with `keys` in `equalObjects`.
        _.pull(funcDepMap.equalObjects, 'getAllKeys').push('keys');

        source = modifyFunction(source, 'equalObjects', function(match) {
          return match.replace(/\bgetAllKeys\b/g, 'keys');
        });

        // Replace `baseAssign` with `assign` in `_.create`.
        _.pull(funcDepMap.create, 'baseAssign').push('assign');

        source = modifyFunction(source, 'create', function(match) {
          return match.replace(/\bbaseAssign\b/g, 'assign');
        });

        // Replace `createWrap` with `_.partial` in `_.wrap`.
        _.pull(funcDepMap.wrap, 'createWrap').push('partial');

        source = modifyFunction(source, 'wrap', function(match) {
          return match.replace(/\bcreateWrap\([\s\S]+?(?=;\n)/, 'partial(wrapper, value)');
        });

        // Replace type check methods with their base counterparts.
        _.each(['isArrayBuffer', 'isDate', 'isMap', 'isRegExp', 'isSet', 'isTypedArray'], function(funcName) {
          var baseName = 'base' + _.upperFirst(funcName);
          funcDepMap[funcName] = [baseName];
          varDepMap[funcName] = [];
          source = replaceFunction(source, funcName, 'var ' + funcName + ' = ' + baseName + ';');
        });

        // Replace method implementations.
        source = replaceFunction(source, 'arrayPush', [
          'function arrayPush(array, values) {',
          '  array.push.apply(array, values);',
          '  return array;',
          '}'
        ].join('\n'));

        funcDepMap.baseAssignValue = [];

        source = replaceFunction(source, 'baseAssignValue', [
          'function baseAssignValue(object, key, value) {',
          '  object[key] = value;',
          '}'
        ].join('\n'));

        funcDepMap.baseGetTag = ['objectToString'];

        source = replaceFunction(source, 'baseGetTag', [
          'function baseGetTag(value) {',
          '  return objectToString(value);',
          '}'
        ].join('\n'));

        funcDepMap.baseIsArguments = ['noop'];
        source = replaceFunction(source, 'baseIsArguments', 'var baseIsArguments = noop;');

        funcDepMap.baseIteratee = ['baseMatches', 'baseProperty', 'identity'];

        source = replaceFunction(source, 'baseIteratee', [
          'function baseIteratee(func) {',
          "  if (typeof func == 'function') {",
          '    return func;',
          '  }',
          '  if (func == null) {',
          '    return identity;',
          '  }',
          "  return (typeof func == 'object' ? baseMatches : baseProperty)(func);",
          '}'
        ].join('\n'));

        funcDepMap.baseMatches = ['baseIsEqual', 'nativeKeys'];

        source = replaceFunction(source, 'baseMatches', [
          'function baseMatches(source) {',
          '  var props = nativeKeys(source);',
          '  return function(object) {',
          '    var length = props.length;',
          '    if (object == null) {',
          '      return !length;',
          '    }',
          '    object = Object(object);',
          '    while (length--) {',
          '      var key = props[length];',
          '      if (!(key in object &&',
          '            baseIsEqual(source[key], object[key], COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG)',
          '          )) {',
          '        return false;',
          '      }',
          '    }',
          '    return true;',
          '  };',
          '}'
        ].join('\n'));

        funcDepMap.basePick = ['reduce'];

        source = replaceFunction(source, 'basePick', [
          'function basePick(object, props) {',
          '  object = Object(object);',
          '  return reduce(props, function(result, key) {',
          '    if (key in object) {',
          '      result[key] = object[key];',
          '    }',
          '    return result;',
          '  }, {});',
          '}'
        ].join('\n'));

        funcDepMap.copyArray = ['baseSlice'];

        source = replaceFunction(source, 'copyArray', [
          'function copyArray(source) {',
          '  return baseSlice(source, 0, source.length);',
          '}'
        ].join('\n'));

        (function() {
          var copyArray = matchFunction(source, 'copyArray', true);
          source = removeFunction(source, 'copyArray');
          source = modifyFunction(source, 'baseSlice', function(match) {
            return match + '\n' + copyArray;
          });
        }());

        source = replaceFunction(source, 'isFlattenable', [
          'function isFlattenable(value) {',
          '  return isArray(value) || isArguments(value);',
          '}'
        ].join('\n'));

        funcDepMap.setToString = ['identity'];
        source = replaceFunction(source, 'setToString', 'var setToString = identity;');

        funcDepMap.wrapperClone = ['copyArray', 'LodashWrapper'];

        source = replaceFunction(source, 'wrapperClone', [
          'function wrapperClone(wrapper) {',
          '  var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);',
          '  result.__actions__ = copyArray(wrapper.__actions__);',
          '  return result;',
          '}'
        ].join('\n'));

        funcDepMap.lodash = ['LodashWrapper'];

        source = replaceFunction(source, 'lodash', [
          'function lodash(value) {',
          '  return value instanceof LodashWrapper',
          '    ? value',
          '    : new LodashWrapper(value);',
          '}'
        ].join('\n'));

        funcDepMap.assign = ['createAssigner', 'copyObject', 'nativeKeys'];

        source = replaceFunction(source, 'assign', [
          'var assign = createAssigner(function(object, source) {',
          '  copyObject(source, nativeKeys(source), object);',
          '});'
        ].join('\n'));

        funcDepMap.assignIn = ['createAssigner', 'copyObject', 'nativeKeysIn'];

        source = replaceFunction(source, 'assignIn', [
          'var assignIn = createAssigner(function(object, source) {',
          '  copyObject(source, nativeKeysIn(source), object);',
          '});'
        ].join('\n'));

        funcDepMap.bind = ['baseRest', 'createPartial'];

        source = replaceFunction(source, 'bind', [
          'var bind = baseRest(function(func, thisArg, partials) {',
          '  return createPartial(func, WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG, thisArg, partials);',
          '});'
        ].join('\n'));

        funcDepMap.clone = ['copyArray', 'copyObject', 'isArray', 'isObject', 'nativeKeys'];

        source = replaceFunction(source, 'clone', [
          'function clone(value) {',
          '  if (!isObject(value)) {',
          '    return value;',
          '  }',
          '  return isArray(value) ? copyArray(value) : copyObject(value, nativeKeys(value));',
          '}'
        ].join('\n'));

        funcDepMap.compact = ['baseFilter'];

        source = replaceFunction(source, 'compact', [
          'function compact(array) {',
          '  return baseFilter(array, Boolean);',
          '}'
        ].join('\n'));

        funcDepMap.filter = ['baseFilter', 'baseIteratee'];

        source = replaceFunction(source, 'filter', [
          'function filter(collection, predicate) {',
          '  return baseFilter(collection, baseIteratee(predicate));',
          '}'
        ].join('\n'));

        funcDepMap.forEach = ['baseIteratee', 'baseEach'];

        source = replaceFunction(source, 'forEach', [
          'function forEach(collection, iteratee) {',
          '  return baseEach(collection, baseIteratee(iteratee));',
          '}'
        ].join('\n'));

        funcDepMap.every = ['baseEvery', 'baseIteratee'];

        source = replaceFunction(source, 'every', [
          'function every(collection, predicate, guard) {',
          '  predicate = guard ? undefined : predicate;',
          '  return baseEvery(collection, baseIteratee(predicate));',
          '}'
        ].join('\n'));

        funcDepMap.has = [];

        source = replaceFunction(source, 'has', [
          'function has(object, path) {',
          '  return object != null && hasOwnProperty.call(object, path);',
          '}'
        ].join('\n'));

        funcDepMap.indexOf = [];

        source = replaceFunction(source, 'indexOf', [
          'function indexOf(array, value, fromIndex) {',
          '  var length = array == null ? 0 : array.length;',
          "  if (typeof fromIndex == 'number') {",
          '    fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;',
          '  } else {',
          '    fromIndex = 0;',
          '  }',
          '  var index = (fromIndex || 0) - 1,',
          '      isReflexive = value === value;',
          '',
          '  while (++index < length) {',
          '    var other = array[index];',
          '    if ((isReflexive ? other === value : other !== other)) {',
          '      return index;',
          '    }',
          '  }',
          '  return -1;',
          '}'
        ].join('\n'));

        funcDepMap.invokeMap = ['baseMap', 'baseRest'];

        source = replaceFunction(source, 'invokeMap', [
          'var invokeMap = baseRest(function(collection, path, args) {',
          "  var isFunc = typeof path == 'function';",
          '  return baseMap(collection, function(value) {',
          '    var func = isFunc ? path : value[path];',
          '    return func == null ? func : func.apply(value, args);',
          '  });',
          '});'
        ].join('\n'));

        funcDepMap.isEmpty = ['isArguments', 'isArray', 'isArrayLike', 'isFunction', 'isString', 'nativeKeys'];

        source = replaceFunction(source, 'isEmpty', [
          'function isEmpty(value) {',
          '  if (isArrayLike(value) &&',
          '      (isArray(value) || isString(value) ||',
          '        isFunction(value.splice) || isArguments(value))) {',
          '    return !value.length;',
          '  }',
          '  return !nativeKeys(value).length;',
          '}'
        ].join('\n'));

        funcDepMap.iteratee = ['baseIteratee'];
        source = replaceFunction(source, 'iteratee', 'var iteratee = baseIteratee;');

        funcDepMap.keys = ['nativeKeys'];
        source = replaceFunction(source, 'keys', 'var keys = nativeKeys;');

        funcDepMap.keysIn = ['nativeKeysIn'];
        source = replaceFunction(source, 'keysIn', 'var keysIn = nativeKeysIn;');

        funcDepMap.map = ['baseMap', 'baseIteratee'];

        source = replaceFunction(source, 'map', [
          'function map(collection, iteratee) {',
          '  return baseMap(collection, baseIteratee(iteratee));',
          '}'
        ].join('\n'));

        funcDepMap.matches = ['assign', 'baseMatches'];

        source = replaceFunction(source, 'matches', [
          'function matches(source) {',
          '  return baseMatches(assign({}, source));',
          '}'
        ].join('\n'));

        funcDepMap.partial = ['baseRest', 'createPartial'];

        source = replaceFunction(source, 'partial', [
          'var partial = baseRest(function(func, partials) {',
          '  return createPartial(func, PARTIAL_FLAG, undefined, partials);',
          '});'
        ].join('\n'));

        funcDepMap.property = ['baseProperty'];
        source = replaceFunction(source, 'property', 'var property = baseProperty;');

        funcDepMap.reduce = ['baseEach', 'baseIteratee', 'baseReduce'];

        source = replaceFunction(source, 'reduce', [
          'function reduce(collection, iteratee, accumulator) {',
          '  return baseReduce(collection, baseIteratee(iteratee), accumulator, arguments.length < 3, baseEach);',
          '}'
        ].join('\n'));

        funcDepMap.result = ['isFunction'];

        source = replaceFunction(source, 'result', [
          'function result(object, path, defaultValue) {',
          '  var value = object == null ? undefined : object[path];',
          '  if (value === undefined) {',
          '    value = defaultValue;',
          '  }',
          '  return isFunction(value) ? value.call(object) : value;',
          '}'
        ].join('\n'));

        funcDepMap.size = ['isArrayLike', 'nativeKeys'];

        source = replaceFunction(source, 'size', [
          'function size(collection) {',
          '  if (collection == null) {',
          '    return 0;',
          '  }',
          '  collection = isArrayLike(collection) ? collection : nativeKeys(collection);',
          '  return collection.length;',
          '}'
        ].join('\n'));

        funcDepMap.slice = ['baseSlice'];

        source = replaceFunction(source, 'slice', [
          'function slice(array, start, end) {',
          '  var length = array == null ? 0 : array.length;',
          '  start = start == null ? 0 : +start;',
          '  end = end === undefined ? length : +end;',
          '  return length ? baseSlice(array, start, end) : [];',
          '}'
        ].join('\n'));

        funcDepMap.some = ['baseSome', 'baseIteratee'];

        source = replaceFunction(source, 'some', [
          'function some(collection, predicate, guard) {',
          '  predicate = guard ? undefined : predicate;',
          '  return baseSome(collection, baseIteratee(predicate));',
          '}'
        ].join('\n'));

        funcDepMap.sortBy = ['baseIteratee', 'baseMap', 'baseProperty', 'compareAscending'];

        source = replaceFunction(source, 'sortBy', [
          'function sortBy(collection, iteratee) {',
          '  var index = 0;',
          '  iteratee = baseIteratee(iteratee);',
          '',
          '  return baseMap(baseMap(collection, function(value, key, collection) {',
          "    return { 'value': value, 'index': index++, 'criteria': iteratee(value, key, collection) };",
          '  }).sort(function(object, other) {',
          '    return compareAscending(object.criteria, other.criteria) || (object.index - other.index);',
          "  }), baseProperty('value'));",
          '}'
        ].join('\n'));

        funcDepMap.toArray = ['copyArray', 'isArrayLike', 'values'];
        varDepMap.toArray = [];

        source = replaceFunction(source, 'toArray', [
          'function toArray(value) {',
          '  if (!isArrayLike(value)) {',
          '    return values(value);',
          '  }',
          '  return value.length ? copyArray(value) : [];',
          '}'
        ].join('\n'));

        funcDepMap.toInteger = [];
        source = replaceFunction(source, 'toInteger', 'var toInteger = Number;');

        funcDepMap.toNumber = [];
        source = replaceFunction(source, 'toNumber', 'var toNumber = Number;');

        funcDepMap.toString = [];
        varDepMap.toString = [];

        source = replaceFunction(source, 'toString', [
          'function toString(value) {',
          "  if (typeof value == 'string') {",
          '    return value;',
          '  }',
          "  return value == null ? '' : (value + '');",
          '}'
        ].join('\n'));
      }
      // Redistribute `seqDepMap` deps.
      if (isModularize) {
        funcDepMap.main = _.union(funcDepMap.main, _.difference(seqDepMap.funcDep, _.without(mapping.category.Seq, 'thru')));
        varDepMap.main = _.union(varDepMap.main, seqDepMap.varDep);
      }
      else {
        funcDepMap.wrapperValue = _.union(funcDepMap.wrapperValue, _.without(seqDepMap.funcDep, 'lodash', 'LodashWrapper'));
        varDepMap.wrapperValue = _.union(varDepMap.wrapperValue, seqDepMap.varDep);

        _.each(_.without(mapping.category.Seq, 'lodash', 'wrapperValue'), function(funcName) {
          funcDepMap[funcName].push('wrapperValue');
        });
      }
      if (isModularize ||
          (isCore && _.isEmpty(plusFuncs))) {
        source = removeGetIteratee(source, funcDepMap);
      }
      // Remove iteratee shorthand support from `iteratee`.
      if (_.isEmpty(_.difference(['matches', 'matchesProperty', 'property'], minusFuncs))) {
        _.pull(funcDepMap.iteratee, 'baseClone');
        source = modifyFunction(source, 'iteratee', function(match) {
          return match.replace(/^( *return\s+)[\s\S]+?(?=;\n)/m, '$1baseIteratee(func)');
        });
      }
      // Remove individual iteratee shorthands from `baseIteratee`.
      _.each(['baseMatches', 'baseMatchesProperty', 'property'], function(funcName) {
        var otherName = _.camelCase(_.trimStart(funcName, 'base'));
        if (_.includes(minusFuncs, otherName)) {
          _.pull(funcDepMap.baseIteratee, funcName);
          source = modifyFunction(source, 'baseIteratee', function(match) {
            return match.replace(RegExp('\\b' + funcName + '\\([\\s\\S]+?\\)(?=[;\\n])', 'm'), 'identity');
          });
        }
      });

      // Add core function names.
      if (isCore) {
        var result = _.clone(listing.coreFuncs);
      }
      // Add function names explicitly.
      else if (!_.isEmpty(includeFuncs)) {
        result = includeFuncs;
      }
      // Add default function names.
      else if (_.isEmpty(includeVars)) {
        result = _.clone(listing.includes);
      }
      // Remove special "none" entry.
      _.pull(result, 'none');

      // Force removing or adding deps.
      if (isModularize) {
        minusFuncs.push('noConflict', 'runInContext');
      } else {
        plusFuncs.push('lodash');
      }
      // Add extra function names.
      if (!_.isEmpty(plusFuncs)) {
        result = _.union(result, plusFuncs);
      }
      // Subtract function names.
      if (!_.isEmpty(minusFuncs)) {
        result = _.difference(result, minusFuncs.concat(getDependants(minusFuncs, funcDepMap, true)));
      }
      if (!isModularize) {
        result.push('main');
      }
      result = _.uniq(result);

      var hasLodash = _.includes(result, 'lodash');
      result = getDependencies(result, funcDepMap, true, ['lodash']);

      // Simplify `lodash` when not capable of chaining.
      if (!_.includes(result, 'mixin') && !_.includes(result, 'wrapperValue')) {
        funcDepMap.lodash.length = 0;

        source = replaceFunction(source, 'lodash', [
          'function lodash() {',
          '  // No operation performed.',
          '}'
        ].join('\n'));
      }
      if (hasLodash) {
        result = _.union(result, ['lodash'], getDependencies('lodash', funcDepMap, true));
      }
      return result;
    }());

    // Expand properties, variables, and their function dependencies to include in the build.
    var allDeps = getAllDependencies(buildFuncs, funcDepMap, varDepMap).sort();

    buildFuncs = _.intersection(listing.funcs, allDeps);
    includeVars = _.intersection(listing.varDeps, allDeps);

    /*------------------------------------------------------------------------*/

    // Load customized lodash module.
    var lodash = !isTemplate && (function() {
      var context = vm.createContext({
        'console': console
      });

      vm.runInContext(source, context);
      return context._;
    }());

    /*------------------------------------------------------------------------*/

    if (isTemplate) {
      source = buildTemplate({
        'moduleId': moduleId,
        'source': source,
        'templatePattern': templatePattern,
        'templateSettings': templateSettings
      });
    }
    else if (isModularize) {
      // Replace the `lodash.templateSettings` property assignment with a variable assignment.
      source = source.replace(/\b(lodash\.)(?=templateSettings\s*=)/, 'var ');

      // Remove the `lodash` namespace from properties.
      source = source.replace(/( *)lodash\.([$\w]+\.)?([$\w]+)(\s*=\s*(?:function\([\s\S]+?\n\1\}|.+?);\n)?/g, function(match, indent, property, identifier, right) {
        return (property || right || identifier == 'com' || identifier == 'prototype')
          ? match
          : (indent + identifier);
      });

      // Remove all horizontal rule comment separators.
      source = source.replace(/^ *\/\*-+\*\/\n/gm, '');

      // Remove `lodash` branch in `_.mixin`.
      source = modifyFunction(source, 'mixin', function(match) {
        return match
          .replace(/^(?: *\/\/.*\n)*( *)if\s*\(options\s*==\s*null\b[\s\S]+?\n\1\}\n/m, '')
          .replace(/^(?: *\/\/.*\n)*( *)if\s*\(!methodNames\b[\s\S]+?\n\1\}/m, function(match, indent) {
            return indent + 'var methodNames = baseFunctions(source, keys(source));\n';
          });
      });

      // Replace `lodash` use in `_.templateSettings.imports`.
      source = modifyProp(source, 'templateSettings', function(match) {
        return match.replace(/(:\s*)lodash\b/, "$1{ 'escape': escape }");
      });

      source = modifyFunction(source, 'template', function(match) {
        // Assign `settings` using `template.imports`.
        match = match.replace(/=\s*templateSettings(?=[,;])/, '$&.imports._.templateSettings || templateSettings');

        // Remove default `sourceURL` value.
        return modifyVar(match, 'sourceURL', function(match) {
          return match.replace(/^( *)(var\s+sourceURL\s*=\s*)[\s\S]+?(?=;\n$)/m, function(submatch, indent, left) {
            return indent + left + [
              "hasOwnProperty.call(options, 'sourceURL')",
              indent + "  ? ('//# sourceURL=' +",
              indent + "     (options.sourceURL + '').replace(/\\s/g, ' ') +",
              indent + "     '\\n')",
              indent + "  : ''"
            ].join('\n');
          });
        });
      });

      if (!isAMD) {
        source = removeVar(source, 'undefined');
      }
    }
    if (!isTemplate) {
      // Remove functions and method assignments from the build.
      _.each(_.difference(listing.funcs, buildFuncs), function(funcName) {
        source = removeFunction(source, funcName);
        if (!isModularize) {
          source = removeMethodAssignment(source, funcName);
        }
      });
      // Remove method assignments for non-core methods.
      if (isCore) {
        _.each(_.difference(buildFuncs, listing.coreFuncs, plusFuncs), function(funcName) {
          source = removeMethodAssignment(source, funcName);
        });
      }
      // Tokenize functions to reduce modularized build times.
      if (isModularize) {
        funcTokenMap = _.transform(buildFuncs, function(result, funcName) {
          var match = matchFunction(source, funcName, true);
          source = replace(source, match,
            _.get(/^,\s+/.exec(match), 0, '') +
            '<<' + funcName + '>>' +
            _.get(/(?:,?\s+|\n)$/.exec(match), 0, '')
          );
          result[funcName] = match;
        }, new Hash);
      }
      // Detect variables after tokenizing functions.
      varNames = _.difference(getVars(source), buildFuncs.concat(includeVars, 'freeGlobal'));
    }

    /*------------------------------------------------------------------------*/

    (function() {
      var snippet = isTemplate ? source : source.slice(-(getMethodAssignments(source), RegExp.rightContext.length)),
          modified = snippet;

      // Set the AMD module ID.
      if (isAMD && !isModularize && !isTemplate && moduleId != null && moduleId != 'none') {
        modified = modified.replace(/^ *define\((?=function)/m, "$&'" + moduleId + "', ");
      }
      // Customize lodash's exports.
      if (!isAMD || isModularize) {
        modified = modified.replace(/^(?: *\/\/.*\n)*( *)if\s*\(typeof\s+define\b[\s\S]+?else\s+/m, '$1');
      }
      if (!isNode || isModularize) {
        modified = modified.replace(/^(?: *\/\/.*\n)*( *)(?:else\s+)?if\s*\(freeModule\b[\s\S]+?\n\1\}\n+/m, '');
      }
      if (!isGlobal || isModularize) {
        if (isAMD && !isModularize && !isTemplate) {
          modified = modified.replace(/^(?: *\/\/.*\n)* *root\._\s*=[\s\S]+?\n+/m, '');
        }
        modified = modified.replace(/^(?: *\/\/.*\n)*( *)else\b[^}]+?(?:\._|_\.templates)\s*=[\s\S]+?\n\1\}\n+/m, '');
      }
      else if (!isAMD && !isNode) {
        modified = modified
          .replace(/^( *)else\s+(?=if\s*\(_\))/m, '$1')
          .replace(/^( *)else\s\{\s*([^}]+?\._\s*=[\s\S]+?)\n\1\}/m, function(match, indent, block) {
            return indent + block.replace(/\n\s*/g, '\n' + indent);
          });
      }
      source = isTemplate ? modified : source.replace(snippet, modified);
    }());

    /*------------------------------------------------------------------------*/

    source = cleanupSource(source);

    // Exit early to create modules.
    if (isModularize) {
      if (callback == defaultBuildCallback) {
        callback = null;
      }
      buildModule({
        'buildFuncs': buildFuncs,
        'filePath': filePath,
        'funcDepMap': funcDepMap,
        'funcTokenMap': funcTokenMap,
        'includeFuncs': includeFuncs,
        'includeVars': includeVars,
        'isAMD': isAMD,
        'isES': isES,
        'isNode': isNode,
        'isNpm': isNpm,
        'isSilent': isSilent,
        'isStdOut': isStdOut,
        'isStrict': isStrict,
        'lodash': lodash,
        'minusFuncs': minusFuncs,
        'options': options,
        'outputPath': outputPath,
        'plusFuncs': plusFuncs,
        'source': source,
        'stamp': stamp,
        'varDepMap': varDepMap,
        'varNames': varNames
      }, callback);
      return;
    }
  }

  /*--------------------------------------------------------------------------*/

  // Modify/remove references to removed functions/variables.
  if (!isTemplate) {
    // Remove prototype assignments.
    _.each(['Hash', 'ListCache', 'MapCache', 'SetCache', 'Stack'], function(funcName) {
      if (isExcluded(funcName)) {
        source = source.replace(RegExp('^(?: *\\/\\/.*\\n)* *' + funcName + '\\.prototype(?:\\.[$\\w]+|\\[\'[^\']+\'\\])\\s*=[^;]+;\\n', 'gm'), '');
      }
    });

    if (isExcluded('getTag')) {
      source = removeGetTagFork(source);
    }
    if (isExcluded('LazyWrapper')) {
      // Remove `LazyWrapper.prototype` assignment.
      source = source.replace(/^(?: *\/\/.*\n)* *LazyWrapper\.prototype(\.constructor)?\s*=[^;]+;\n/gm, '');
    }
    if (isExcluded('lodash') || !_.includes(funcDepMap.lodash, 'baseLodash')) {
      // Remove `lodash.prototype` assignment.
      source = source.replace(/^(?: *\/\/.*\n)* *lodash\.prototype(\.constructor)?\s*=[^;]+;\n/gm, '');
    }
    if (isExcluded('LodashWrapper')) {
      // Remove `LodashWrapper.prototype` assignment.
      source = source.replace(/^(?: *\/\/.*\n)* *LodashWrapper\.prototype(\.constructor)?\s*=[^;]+;\n/gm, '');
    }
    if (isExcluded('memoize')) {
      // Remove `memoize.Cache` assignment.
      source = source.replace(/^(?: *\/\/.*\n)* *memoize\.Cache\s*=[^;]+;\n/m, '');
    }
    if (isExcluded(isModularize ? 'main' : 'wrapperToIterator')) {
      // Remove conditional `wrapperToIterator` assignment.
      source = source.replace(/^(?: *\/\/.*\n)*( *)if\s*\(symIterator\)[\s\S]+?\n\1\}\n/gm, '');
    }
    if (isExcluded(isModularize ? 'main' : 'mixin')) {
      source = removeMixinCalls(source);
    }
    if (isExcluded(isModularize ? 'main' : 'wrapperValue')) {
      source = removeChaining(source);
    }
    if (isModularize && isExcluded('main')) {
      source = removeAssignments(source);
    }
    // Remove placeholder assignments of removed functions.
    source = source.replace(/^((?: *\/\/.*\n)*)( *)(arrayEach\(\[')bind\b[\s\S]+?('\][\s\S]+?\n\2\}\))/m, function(match, comment, indent, prelude, postlude) {
      var funcNames = _.reject(listing.placeholderFuncs, isExcluded),
          length = isCore ? 0 : funcNames.length;

      if (length) {
        return length > 1
          ? (comment + indent + prelude + funcNames.join("', '") + postlude)
          : (comment + indent + funcNames[0] + '.placeholder = ') + (isModularize ? '{}' : 'lodash');
      }
      return '';
    });

    // Remove unused variable dependencies.
    _.each(_.difference(listing.varDeps, includeVars.concat('root')), function(varName) {
      source = removeVar(source, varName);
    });

    if (!_.includes(includeVars, 'root')) {
      varNames = _.without(varNames, 'root');
      source = removeVar(source, 'root');
    }
    if (!_.includes(includeVars, 'templateSettings')) {
      varNames = _.without(varNames, 'templateSettings');
      source = removeProp(source, 'templateSettings');
    }
    if (isModularize) {
      // Untokenize functions to include in the build.
      _.each(buildFuncs, function(funcName) {
        source = source.replace(RegExp(',\\s+<<' + funcName + '>>|<<' + funcName + '>>(,\\s+|\\n)?'), function() {
          return funcTokenMap[funcName];
        });
      });
      source = source.replace(consts.reNamedToken, '');
    }
    // Remove unused variables.
    source = stringFree(source, function(source) {
      return commentFree(source, function(source) {
        var useMap = new Hash;
        while (varNames.length) {
          varNames = _.sortBy(varNames, function(varName) {
            var result = isVarUsed(source, varName);
            useMap[varName] = result;
            return result;
          });

         if (useMap[varNames[0]]) {
            break;
          }
          while (varNames.length && !useMap[varNames[0]]) {
            source = removeVar(source, varNames.shift());
          }
        }
        return source;
      });
    });
  }
  // Customize lodash's IIFE.
  if (isIIFE) {
    source = replaceIIFE(source, iife);
  }

  /*--------------------------------------------------------------------------*/

  source = cleanupSource(source);

  // A flag to track if `outputPath` has been used by `callback`.
  var outputUsed = false;

  // Expand `outputPath` and create directories if needed.
  if (outputPath) {
    outputPath = (function() {
      var dirname = path.dirname(outputPath);
      fs.mkdirpSync(dirname);
      return path.join(fs.realpathSync(dirname), path.basename(outputPath));
    }());
  }
  // Resolve the basename of the output path.
  var basename = filePath = outputPath;
  if (!basename) {
    basename = 'lodash';
    if (isTemplate) {
      basename += '.templates';
    } else if (isCustom) {
      basename += '.custom';
    }
    filePath =  path.join(cwd, basename + '.js');
  }
  // Output development build.
  if (!isProduction) {
    var devSource = source;
    if (isCustom) {
      devSource = addCommandsToHeader(devSource, options);
    }
    if (isDevelopment && isStdOut) {
      stdout.write(devSource);
      callback({
        'source': devSource
      });
    }
    else if (!isStdOut) {
      outputUsed = true;
      callback({
        'source': devSource,
        'outputPath': filePath
      });
    }
  }
  // Begin the minification process.
  if (!isDevelopment) {
    if (outputPath && outputUsed) {
      outputPath = path.join(path.dirname(outputPath), path.basename(outputPath, '.js') + '.min.js');
    } else if (!outputPath) {
      outputPath = path.join(cwd, basename + '.min.js');
    }
    minify(source, {
      'filePath': filePath,
      'isMapped': isMapped,
      'isSilent': isSilent,
      'isTemplate': isTemplate,
      'modes': isIIFE ? ['simple', 'hybrid'] : ['simple', 'advanced', 'hybrid'],
      'outputPath': outputPath,
      'sourceMapURL': sourceMapURL,
      'onComplete': function(data) {
        if (isCustom) {
          data.source = addCommandsToHeader(data.source, options);
        }
        if (isStdOut) {
          delete data.outputPath;
          stdout.write(data.source);
        }
        callback(data);
      }
    });
  }
}

/*----------------------------------------------------------------------------*/

// Export `build`.
if (!isBin) {
  module.exports = build;
}
// Handle invoking `build` by the command-line.
else if (_.size(process.argv) > 2) {
  build(process.argv.slice(2));
}