/*
builds the run template

@param {obj} object of options
@callback {err} err
322416
function buildMasterTemplate(opts, callback) {
  var viewOpt = {
    user: opts.user,
    logRoot: opts.logRoot
  };

  renderTemplate(templateFilePath('master.conf', opts.templateOpt), viewOpt, function(err, renderedOutput) {
    if (err) {
      return callback(err.message);
    } else {
      return fs.writeFile(opts.writePath, renderedOutput, function(err) {
	if (err) {
	  return callback(err.message);
	} else {
	  return callback(null);
	}
      });
    }
  });
}
335480
function runCommand(command, options) {
    let cmd = getCommand(command);
    if (!cmd || command === 'help') {
      cmd = getCommand('help');
    } else {
      try {
        validateConfig(options);
      } catch (error) {
        console.log(error.message);
        process.exit(1);
      }
    }
    let fn = cmd.callback;
    let opts = mapParams(cmd, options);
    fn(opts).then(function (result) {
      if (cmd.formatter) {
        cmd.formatter.format(result.messages, options);
      } else {
        console.log(result);
      }
    }).catch(function (error) {
      let formatter = new formatters.MessageFormatter();
      if (error.response) {
        console.log(error);
        formatter.format(['Error response received: ' + error.response.data.errors[0].message]);
      } else {

        formatter.format([error.message]);
      }
      process.exit(1);
    });
  }
143219
function runNew(){
  if (args[1] && args[2]) {
    var targetPath = args[2];
    if(targetPath == '.') {
      console.error('Invalid app name, you may not specify \'.\' as an app name'.error);
      process.exit(0);
    }
    if (fs.existsSync(targetPath)) {
      console.error(('Invalid app name "' + targetPath + '", directory already exists').error);
      process.exit(0);
    }
    getTemplatesList().then(function(knownTemplates){
      var template = _.find(knownTemplates, function(el){return el.id == args[1];})
      if (!template) {
        if (validURL(args[1])) {
          template = {repo: args[1], name : "dummy"};
        }
      }
      if (template) {
        console.log('Cloning MobileCaddy template "' + args[1] + '" from ' + template.repo);
        fetchArchive(targetPath, template).then(function(){
          console.log('Clone complete'.info);
          return installNpmDeps(targetPath);
        }).then(function(){
          console.log('NPM dependancies installed'.info);
          cd(targetPath);
          return installBowerDeps(targetPath);
        }).then(function(res){
          if (res != "no-bower.json") console.log('Bower dependancies installed'.info);
          return runInitGruntTask(targetPath)
        }).then(function(){
          console.log('Grunt tasks completed'.info);
          process.exit(0);
        }).catch(function(err){
          console.error(err.error);
          process.exit(0);
        });
      } else if (validURL(args[1])) {
        console.log("That looks like a URL, nice");
        process.exit(0)
      } else {
        console.error('Unknown template ' + args[1].error);
        process.exit(0);
      }
    });
  } else {
    console.error('You need more arguments, man!'.error);
    //optimist.showHelp();
    process.exit(0);
  }
}
1290235
function render_template(type, object) {
  try {
    return new EJS({text: __templates[type]}).render(object);
  } catch (e) {
    //console.error(e);
    return "";
  }
}
898049
function _print (template, values, options) {
  return template.replace(/\$([\w.]+)/g, function (original, key) {
    const keys = key.split('.')
    let value = values[keys.shift()]
    while (keys.length && value !== undefined) {
      const k = keys.shift()
      value = k ? value[k] : value + '.'
    }

    if (value !== undefined) {
      if (!isString(value)) {
        return format(value, options)
      } else {
        return value
      }
    }

    return original
  }
  )
}
694350
function buildEnvTemplates(opts, callback) {
  var envOptsObj = envOpts(opts);
  var envOptsKeys = _.keys(envOptsObj);
  var writeEnvFiles = function(envKey, writeCallback) {
    fs.writeFile(opts.processEnvDir + '/' + envKey, envOptsObj[envKey], function(err) {
      if (err) {
	return callback(err.message);
      } else {
	return writeCallback(null);
      }
    });
  };

  async.forEach(envOptsKeys, writeEnvFiles, callback);
}
912908
function WError(options)
{
	Error.call(this);

	var args, cause, ctor;
	if (typeof (options) === 'object') {
		args = Array.prototype.slice.call(arguments, 1);
	} else {
		args = Array.prototype.slice.call(arguments, 0);
		options = undefined;
	}

	if (args.length > 0) {
		this.message = mod_extsprintf.sprintf.apply(null, args);
	} else {
		this.message = '';
	}

	if (options) {
		if (options instanceof Error) {
			cause = options;
		} else {
			cause = options.cause;
			ctor = options.constructorOpt;
		}
	}

	Error.captureStackTrace(this, ctor || this.constructor);
	if (cause)
		this.cause(cause);

}
109288
function run(exec, args, shell, callback) {
    var env = extend({}, this.env)
    env.TERM = 'dumb'
    const opts = { env: env, shell: shell }

    this.log.silly('execFile: exec = %j', exec)
    this.log.silly('execFile: args = %j', args)
    this.log.silly('execFile: opts = %j', opts)
    try {
      this.execFile(exec, args, opts, execFileCallback.bind(this))
    } catch (err) {
      this.log.silly('execFile: threw:\n%s', err.stack)
      return callback(err)
    }

    function execFileCallback(err, stdout, stderr) {
      this.log.silly('execFile result: err = %j', err && err.stack || err)
      this.log.silly('execFile result: stdout = %j', stdout)
      this.log.silly('execFile result: stderr = %j', stderr)
      if (err) {
        return callback(err)
      }
      const execPath = stdout.trim()
      callback(null, execPath)
    }
  }
232575
function VError(options)
{
	var args, causedBy, ctor, tailmsg;

	if (options instanceof Error || typeof (options) === 'object') {
		args = Array.prototype.slice.call(arguments, 1);
	} else {
		args = Array.prototype.slice.call(arguments, 0);
		options = undefined;
	}

	tailmsg = args.length > 0 ?
	    mod_extsprintf.sprintf.apply(null, args) : '';
	this.jse_shortmsg = tailmsg;
	this.jse_summary = tailmsg;

	if (options) {
		causedBy = options.cause;

		if (!causedBy || !(options.cause instanceof Error))
			causedBy = options;

		if (causedBy && (causedBy instanceof Error)) {
			this.jse_cause = causedBy;
			this.jse_summary += ': ' + causedBy.message;
		}
	}

	this.message = this.jse_summary;
	Error.call(this, this.jse_summary);

	if (Error.captureStackTrace) {
		ctor = options ? options.constructorOpt : undefined;
		ctor = ctor || arguments.callee;
		Error.captureStackTrace(this, ctor);
	}
}
1329228
function tasks(options) {
  options = options || {};
  var fp = path.resolve(options.template);
  var tmpl = new utils.File({path: fp, contents: fs.readFileSync(fp)});
  var data = {tasks: []};

  return utils.through.obj(function(file, enc, next) {
    var description = options.description || file.stem;

    if (typeof description === 'function') {
      description = options.description(file);
    }

    data.tasks.push({
      alias: 'gitignore',
      path: path.relative(path.resolve('generators'), file.path),
      name: file.stem.toLowerCase(),
      description: description,
      relative: file.relative,
      basename: '.gitignore'
    });

    next();
  }, function(next) {
    tmpl.data = data;
    this.push(tmpl);
    next();
  });
}
1240562
function Templater(options) {
  if (options == null) {
    options = { allowEval: true };
  }
  this.options = options;
  if (options.stack && Array.isArray(options.stack)) {
    this.stack = options.stack;
  }
  else if (typeof options.stack === 'string') {
    this.stack = [ options.stack ];
  }
  else {
    this.stack = [];
  }
  this.nodes = [];
}
888159
function Compiler(node, options) {
  this.options = options = options || {};
  this.node = node;
  this.hasCompiledDoctype = false;
  this.hasCompiledTag = false;
  this.pp = options.pretty || false;
  if (this.pp && typeof this.pp !== 'string') {
    this.pp = '  ';
  }
  this.debug = false !== options.compileDebug;
  this.indents = 0;
  this.parentIndents = 0;
  this.terse = false;
  this.mixins = {};
  this.dynamicMixins = false;
  this.eachCount = 0;
  if (options.doctype) this.setDoctype(options.doctype);
  this.runtimeFunctionsUsed = [];
  this.inlineRuntimeFunctions = options.inlineRuntimeFunctions || false;
  if (this.debug && this.inlineRuntimeFunctions) {
    this.runtimeFunctionsUsed.push('rethrow');
  }
  this.codeBuffer = '_=function*(){';
  this.codeMarker = {};
  this.codeIndex = -1;

  this.useGenerators = false;
  this.templateVars = ['locals']

}
873226
function Markdown(runner, options) {
  Base.call(this, runner, options);

  var level = 0;
  var buf = '';

  function title(str) {
    return Array(level).join('#') + ' ' + str;
  }

  function mapTOC(suite, obj) {
    var ret = obj;
    var key = SUITE_PREFIX + suite.title;

    obj = obj[key] = obj[key] || {suite: suite};
    suite.suites.forEach(function(suite) {
      mapTOC(suite, obj);
    });

    return ret;
  }

  function stringifyTOC(obj, level) {
    ++level;
    var buf = '';
    var link;
    for (var key in obj) {
      if (key === 'suite') {
        continue;
      }
      if (key !== SUITE_PREFIX) {
        link = ' - [' + key.substring(1) + ']';
        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
        buf += Array(level).join('  ') + link;
      }
      buf += stringifyTOC(obj[key], level);
    }
    return buf;
  }

  function generateTOC(suite) {
    var obj = mapTOC(suite, {});
    return stringifyTOC(obj, 0);
  }

  generateTOC(runner.suite);

  runner.on(EVENT_SUITE_BEGIN, function(suite) {
    ++level;
    var slug = utils.slug(suite.fullTitle());
    buf += '<a name="' + slug + '"></a>' + '\n';
    buf += title(suite.title) + '\n';
  });

  runner.on(EVENT_SUITE_END, function() {
    --level;
  });

  runner.on(EVENT_TEST_PASS, function(test) {
    var code = utils.clean(test.body);
    buf += test.title + '.\n';
    buf += '\n```js\n';
    buf += code + '\n';
    buf += '```\n\n';
  });

  runner.once(EVENT_RUN_END, function() {
    process.stdout.write('# TOC\n');
    process.stdout.write(generateTOC(runner.suite));
    process.stdout.write(buf);
  });
}
194921
function renderTemplate(template, locals, cb) {
    var res;

    try {
      var localTemplateOptions = self.getLocalTemplateOptions(locals);
      var localsClone = _.extend({}, locals);
      self.updateLocalTemplateOptions(localsClone, undefined);
      res = template(localsClone, _.merge({}, self._options.templateOptions, localTemplateOptions));
    } catch (err) {
      if (err.message) {
        err.message = '[' + template.__filename + '] ' + err.message;
      } else if (typeof err === 'string') {
        return cb('[' + template.__filename + '] ' + err, null);
      }
      return cb(err, null);
    }
    cb(null, res);
  }
853879
function Bobsled(opts)
{
  require('http').Server.call(this);

  if (typeof(opts) == "undefined") opts = {};

  this.port = ("port" in opts) ? opts.port : 8085; // reads like BOBS on an old calculator

  if ("env" in opts) this.env = opts.env;
  if ("uid" in opts) this.uid = opts.uid;
  if ("gid" in opts) this.gid = opts.gid;

  this.template_compiler = ("template_compiler" in opts) ? opts.template_compiler : function () { throw new Error("no template compiler configured"); };

  // TODO: support other template engines besides doT?
  //
  this.template_config = {
    evaluate:    /<%([\s\S]+?)%>/g, // some erb like delimiters
    interpolate: /<%=([\s\S]+?)%>/g,
    varname: ["Page", "Server"],
    strip: false,
    append: true
  };

  this.templates = {};

  // compile all templates, useful for checking correctness on startup
  this.compileTemplates = function() {
    for (var template_name in this.templates) this.templates[template_name].compile();
  };

  this.controllers = {
    template: function(pathinfo, request, response) {
      var template_name = pathinfo.basename || "index"
      if (template_name in this.templates) {
        this.templateResponder(template_name, pathinfo, response);
      } else {
        this.emit("notFound", pathinfo, request, response);
      }
    }.bind(this),
    "static": function(pathinfo, request, response) {
      var filename = "." + pathinfo.dirname + "/" + pathinfo.basename + pathinfo.extname;
      if (!fs.statSync(filename).isFile()) {
        this.emit("notFound", pathinfo, request, response);
      } else {
        response.writeHead(200, {"content-type": "text/css"}); // HACK TODO mimetype
        fs.readFile(filename, function (err, data) { response.end(data); });
      }
    }.bind(this),
    favicon: function(pathinfo, request, response) {
      response.writeHead(200, {"content-type": "image/x-icon"}); // TODO: set expires
      fs.readFile("favicon.ico", function (err, data) { response.end(data); });
    },
    notFound: function (pathinfo, request, response) {
      if ("404" in this.templates) {
        this.templateResponder("404", { statusCode: 404, pathinfo: pathinfo, request: request }, response);
      } else {
        response.writeHead(404, {"content-type": "text/plain"});
        response.end(request.url + " not found");
      }
    }.bind(this)
  };

  // TODO: config/recipe for default routes
  this.routes = {
    GET: {
      "/": {
        "favicon.ico": this.controllers.favicon,
        "*.html": this.controllers.template
      },
    },
    POST: { }
  };

  // setup static routes
  if (true) { // TODO: opts.static? (could pass in path?)
    var static_folders = {"css": "/css", "img": "/img", "js": "/js"}; // TODO: pass in opts?
    for (folder in static_folders) {
      if (fs.existsSync(folder) && fs.statSync(folder).isDirectory()) {
        this.routes.GET[static_folders[folder]] = { "*": this.controllers.static };
      }
    }
  }

  if (opts.env) {
    // TODO: make path part of config?
    this.routes.GET["/"]["env"] = function(pathinfo, request, response) {
      response.writeHead(200, {"content-type": "application/json"}); // TODO switch to HTML on extname
      var data = { env: process.env, uid: process.getuid(), os: {} };
      var os = require("os");
      ["hostname", "type", "platform", "arch", "release", "networkInterfaces", "cpus"].forEach(function (a) {
        data.os[a] = os[a]();
      });
      if (process.env.HOME) data.home = fs.readdirSync(process.env.HOME);
      // data.passwd = require("getpw").getpwuid(data.uid); (TODO: pass to constructor to eliminate hard dep)
      response.end(JSON.stringify(data, null, "  "));
    }
  }

  this.redirect = function(new_url, response) {
      response.writeHead(302, { 'Location': new_url });
      response.end();
  };

  this.on("notFound", this.controllers.notFound);

  this.route = function(request, response, body) {
    var parsed_url = url.parse(request.url, true);
    var method = request.method,
        dirname = path.dirname(parsed_url.pathname).replace(/\/*$/, ''), // strip any trailing slash
        extname = path.extname(parsed_url.pathname), // TODO: should have a default for extname?
        basename = path.basename(parsed_url.pathname, extname) || "index"; // TODO: configurable default basename?

    console.log("%s %s/%s%s", method, dirname, basename, extname); // TODO: add an on/off switch for this logging

    if (dirname == "") dirname = "/"; // special case root routes, where the leading and trailing slash are the same

    // TODO: add a switch for case (in)sensitivity
    // dirname = dirname.toLowerCase();
    // basename = basename.toLowerCase();

    var controller = this.controllers.notFound;
    if (this.routes[method] && this.routes[method][dirname]) {
       // find the most specific match possible
       var candidate, candidates = [basename + extname, basename, "*" + extname, "*"];
       while (candidate = candidates.shift()) {
         if (candidate in this.routes[method][dirname]) {
             controller = this.routes[method][dirname][candidate];
             break; // while
         }
       }
    }
    return controller({ dirname: dirname, basename: basename, extname: extname, query: parsed_url.query }, request, response, body);
  };
}
655644
function format(err, options) {
    const error = { message: 'Internal Server Error' };

    options = options || {};

    if (options.exposeErrors || (err.httpStatusCode && err.httpStatusCode < 500)) {
        error.message = err.message;
        if (err.code) error.code = err.code;
        if (err.validation) error.validation = err.validation;
    }

    if (options.exposeErrors) {
        if (err.stack) error.stack = err.stack.split(/\r?\n/);

        if (err.info) {
            Object.keys(err.info).forEach(key => {
                if (!has(error, key) && has(err.info, key)) error[key] = err.info[key];
            });
        }
    }

    return error;
}
293575
function TpBuilderProcess(str, options){
    let init = str;
    if (typeof str === 'object') {
        init = init.map((item) => '{{@ ' + item + ' }}').join('\n');
    }
    return new TpBuilder(init, options).parse();
}