text: 'use strict';
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
  
  var assert = require('assert'),
      path = require('path'),
      Completion = require('./lib/completion'),
      Parser = require('./lib/parser'),
      Usage = require('./lib/usage'),
      Validation = require('./lib/validation');
  
  Argv(process.argv.slice(2));
  
  var _exports = module.exports = Argv;
  function Argv(processArgs, cwd) {
    processArgs = processArgs || []; // handle calling yargs().
  
    var self = {};
    var completion = null;
    var usage = null;
    var validation = null;
  
    if (!cwd) cwd = process.cwd();
  
    self.$0 = process.argv.slice(0, 2).map(function (x, i) {
      // ignore the node bin, specify this in your
      // bin file with #!/usr/bin/env node
      if (i === 0 && /\b(node|iojs)$/.test(x)) return;
      var b = rebase(cwd, x);
      return x.match(/^\//) && b.length < x.length ? b : x;
    }).join(' ').trim();
  
    if (process.env._ !== undefined && process.argv[1] === process.env._) {
      self.$0 = process.env._.replace(path.dirname(process.execPath) + '/', '');
    }
  
    var options;
    self.resetOptions = self.reset = function () {
      // put yargs back into its initial
      // state, this is useful for creating a
      // nested CLI.
      options = {
        array: [],
        boolean: [],
        string: [],
        narg: {},
        key: {},
        alias: {},
        default: {},
        defaultDescription: {},
        requiresArg: [],
        count: [],
        normalize: [],
        config: []
      };
  
      usage = Usage(self); // handle usage output.
      validation = Validation(self, usage); // handle arg validation.
      completion = Completion(self, usage);
  
      demanded = {};
  
      exitProcess = true;
      strict = false;
      helpOpt = null;
      versionOpt = null;
      completionOpt = null;
      commandHandlers = {};
      self.parsed = false;
  
      return self;
    };
    self.resetOptions();
  
    self.boolean = function (bools) {
      options.boolean.push.apply(options.boolean, [].concat(bools));
      return self;
    };
  
    self.array = function (arrays) {
      options.array.push.apply(options.array, [].concat(arrays));
      return self;
    };
  
    self.nargs = function (key, n) {
      if ((typeof key === 'undefined' ? 'undefined' : _typeof(key)) === 'object') {
        Object.keys(key).forEach(function (k) {
          self.nargs(k, key[k]);
        });
      } else {
        options.narg[key] = n;
      }
      return self;
    };
  
    self.normalize = function (strings) {
      options.normalize.push.apply(options.normalize, [].concat(strings));
      return self;
    };
  
    self.config = function (configs) {
      options.config.push.apply(options.config, [].concat(configs));
      return self;
    };
  
    self.example = function (cmd, description) {
      usage.example(cmd, description);
      return self;
    };
  
    self.command = function (cmd, description, fn) {
      usage.command(cmd, description);
      if (fn) commandHandlers[cmd] = fn;
      return self;
    };
  
    var commandHandlers = {};
    self.getCommandHandlers = function () {
      return commandHandlers;
    };
  
    self.string = function (strings) {
      options.string.push.apply(options.string, [].concat(strings));
      return self;
    };
  
    self.default = function (key, value, defaultDescription) {
      if ((typeof key === 'undefined' ? 'undefined' : _typeof(key)) === 'object') {
        Object.keys(key).forEach(function (k) {
          self.default(k, key[k]);
        });
      } else {
        if (typeof value === 'function') {
          defaultDescription = usage.functionDescription(value, defaultDescription);
          value = value.call();
        }
        options.defaultDescription[key] = defaultDescription;
        options.default[key] = value;
      }
      return self;
    };
  
    self.alias = function (x, y) {
      if ((typeof x === 'undefined' ? 'undefined' : _typeof(x)) === 'object') {
        Object.keys(x).forEach(function (key) {
          self.alias(key, x[key]);
        });
      } else {
        options.alias[x] = (options.alias[x] || []).concat(y);
      }
      return self;
    };
  
    self.count = function (counts) {
      options.count.push.apply(options.count, [].concat(counts));
      return self;
    };
  
    var demanded = {};
    self.demand = self.required = self.require = function (keys, msg) {
      if (typeof keys === 'number') {
        if (!demanded._) demanded._ = { count: 0, msg: null };
        demanded._.count += keys;
        demanded._.msg = msg;
      } else if (Array.isArray(keys)) {
        keys.forEach(function (key) {
          self.demand(key, msg);
        });
      } else {
        if (typeof msg === 'string') {
          demanded[keys] = { msg: msg };
        } else if (msg === true || typeof msg === 'undefined') {
          demanded[keys] = { msg: undefined };
        }
      }
  
      return self;
    };
    self.getDemanded = function () {
      return demanded;
    };
  
    self.requiresArg = function (requiresArgs) {
      options.requiresArg.push.apply(options.requiresArg, [].concat(requiresArgs));
      return self;
    };
  
    self.implies = function (key, value) {
      validation.implies(key, value);
      return self;
    };
  
    self.usage = function (msg, opts) {
      if (!opts && (typeof msg === 'undefined' ? 'undefined' : _typeof(msg)) === 'object') {
        opts = msg;
        msg = null;
      }
  
      usage.usage(msg);
  
      if (opts) self.options(opts);
  
      return self;
    };
  
    self.epilogue = self.epilog = function (msg) {
      usage.epilog(msg);
      return self;
    };
  
    self.fail = function (f) {
      usage.failFn(f);
      return self;
    };
  
    self.check = function (f) {
      validation.check(f);
      return self;
    };
  
    self.defaults = self.default;
  
    self.describe = function (key, desc) {
      options.key[key] = true;
      usage.describe(key, desc);
      return self;
    };
  
    self.parse = function (args) {
      return parseArgs(args);
    };
  
    self.option = self.options = function (key, opt) {
      if ((typeof key === 'undefined' ? 'undefined' : _typeof(key)) === 'object') {
        Object.keys(key).forEach(function (k) {
          self.options(k, key[k]);
        });
      } else {
        assert((typeof opt === 'undefined' ? 'undefined' : _typeof(opt)) === 'object', 'second argument to option must be an object');
  
        options.key[key] = true; // track manually set keys.
  
        if (opt.alias) self.alias(key, opt.alias);
  
        var demand = opt.demand || opt.required || opt.require;
  
        if (demand) {
          self.demand(key, demand);
        }if ('default' in opt) {
          self.default(key, opt.default);
        }if ('nargs' in opt) {
          self.nargs(key, opt.nargs);
        }if (opt.boolean || opt.type === 'boolean') {
          self.boolean(key);
          if (opt.alias) self.boolean(opt.alias);
        }if (opt.array || opt.type === 'array') {
          self.array(key);
          if (opt.alias) self.array(opt.alias);
        }if (opt.string || opt.type === 'string') {
          self.string(key);
          if (opt.alias) self.string(opt.alias);
        }if (opt.count || opt.type === 'count') {
          self.count(key);
        }
  
        var desc = opt.describe || opt.description || opt.desc;
        if (desc) {
          self.describe(key, desc);
        }
  
        if (opt.requiresArg) {
          self.requiresArg(key);
        }
      }
  
      return self;
    };
    self.getOptions = function () {
      return options;
    };
  
    self.wrap = function (cols) {
      usage.wrap(cols);
      return self;
    };
  
    var strict = false;
    self.strict = function () {
      strict = true;
      return self;
    };
    self.getStrict = function () {
      return strict;
    };
  
    self.showHelp = function (level) {
      if (!self.parsed) parseArgs(processArgs); // run parser, if it has not already been executed.
      usage.showHelp(level);
      return self;
    };
  
    var versionOpt = null;
    self.version = function (ver, opt, msg) {
      versionOpt = opt || 'version';
      usage.version(ver);
      self.boolean(versionOpt);
      self.describe(versionOpt, msg || 'Show version number');
      return self;
    };
  
    var helpOpt = null;
    self.addHelpOpt = function (opt, msg) {
      helpOpt = opt;
      self.boolean(opt);
      self.describe(opt, msg || 'Show help');
      return self;
    };
  
    self.showHelpOnFail = function (enabled, message) {
      usage.showHelpOnFail(enabled, message);
      return self;
    };
  
    var exitProcess = true;
    self.exitProcess = function (enabled) {
      if (typeof enabled !== 'boolean') {
        enabled = true;
      }
      exitProcess = enabled;
      return self;
    };
    self.getExitProcess = function () {
      return exitProcess;
    };
  
    self.help = function () {
      if (arguments.length > 0) return self.addHelpOpt.apply(self, arguments);
  
      if (!self.parsed) parseArgs(processArgs); // run parser, if it has not already been executed.
  
      return usage.help();
    };
  
    var completionOpt = null,
        completionCommand = null;
    self.completion = function (cmd, desc, fn) {
      // a function to execute when generating
      // completions can be provided as the second
      // or third argument to completion.
      if (typeof desc === 'function') {
        fn = desc;
        desc = null;
      }
  
      // register the completion command.
      completionCommand = cmd;
      completionOpt = completion.completionKey;
      self.command(completionCommand, desc || 'generate bash completion script');
  
      // a function can be provided
      if (fn) completion.registerFunction(fn);
  
      return self;
    };
  
    self.showCompletionScript = function ($0) {
      $0 = $0 || self.$0;
      console.log(completion.generateCompletionScript($0));
      return self;
    };
  
    self.getUsageInstance = function () {
      return usage;
    };
  
    self.getValidationInstance = function () {
      return validation;
    };
  
    self.terminalWidth = function () {
      return require('window-size').width;
    };
  
    Object.defineProperty(self, 'argv', {
      get: function get() {
        var args = null;
  
        try {
          args = parseArgs(processArgs);
        } catch (err) {
          usage.fail(err.message);
        }
  
        return args;
      },
      enumerable: true
    });
  
    function parseArgs(args) {
      var parsed = Parser(args, options),
          argv = parsed.argv,
          aliases = parsed.aliases;
  
      argv.$0 = self.$0;
  
      self.parsed = parsed;
  
      // generate a completion script for adding to ~/.bashrc.
      if (completionCommand && ~argv._.indexOf(completionCommand)) {
        self.showCompletionScript();
        if (exitProcess) {
          process.exit(0);
        }
      }
  
      // if there's a handler associated with a
      // command defer processing to it.
      var handlerKeys = Object.keys(self.getCommandHandlers());
      for (var i = 0, command; (command = handlerKeys[i]) !== undefined; i++) {
        if (~argv._.indexOf(command)) {
          self.getCommandHandlers()[command](self.reset());
          return self.argv;
        }
      }
  
      Object.keys(argv).forEach(function (key) {
        if (key === helpOpt && argv[key]) {
          self.showHelp('log');
          if (exitProcess) {
            process.exit(0);
          }
        } else if (key === versionOpt && argv[key]) {
          usage.showVersion();
          if (exitProcess) {
            process.exit(0);
          }
        } else if (key === completionOpt) {
          // we allow for asynchronous completions,
          // e.g., loading in a list of commands from an API.
          completion.getCompletion(function (completions) {
            ;(completions || []).forEach(function (completion) {
              console.log(completion);
            });
  
            if (exitProcess) {
              process.exit(0);
            }
          });
          return;
        }
      });
  
      validation.nonOptionCount(argv);
      validation.missingArgumentValue(argv);
      validation.requiredArguments(argv);
  
      if (strict) {
        validation.unknownArguments(argv, aliases);
      }
  
      validation.customChecks(argv, aliases);
      validation.implications(argv);
      setPlaceholderKeys(argv);
  
      return argv;
    }
  
    function setPlaceholderKeys(argv) {
      Object.keys(options.key).forEach(function (key) {
        if (typeof argv[key] === 'undefined') argv[key] = undefined;
      });
    }
  
    sigletonify(self);
    return self;
  }
  
  // rebase an absolute path to a relative one with respect to a base directory
  // exported for tests
  _exports.rebase = rebase;
  function rebase(base, dir) {
    return path.relative(base, dir);
  }
  
  /*  Hack an instance of Argv with process.argv into Argv
      so people can do
      require('yargs')(['--beeble=1','-z','zizzle']).argv
      to parse a list of args and
      require('yargs').argv
      to get a parsed version of process.argv.
  */
  function sigletonify(inst) {
    Object.keys(inst).forEach(function (key) {
      if (key === 'argv') {
        Argv.__defineGetter__(key, inst.__lookupGetter__(key));
      } else {
        Argv[key] = typeof inst[key] === 'function' ? inst[key].bind(inst) : inst[key];
      }
    });
  }
  
  //# sourceMappingURL=index-compiled.js.map