Commits

kai zhu committed 07c14c7

merge cli.js, libStable.js2, libUnstable.js into moduleMain.js. migrate from nopt to commander.

Comments (0)

Files changed (7)

cli.js

-#!/usr/bin/env node
-/**
- * @class EXPORTS
- * @module cli.js
- */
-
-
-
-/*FILE_BEG {"actions": ["jslint", "eval", "watch"], "name": "cli.js"}*/
-/*jslint indent: 2, nomen: true, regexp: true, stupid: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      //// EXPORTS
-      EXPORTS.exportLocal = local.exportLocal;
-      EXPORTS.exportLocal(local);
-      EXPORTS.require = EXPORTS.require || require;
-      EXPORTS.requireChildProcess = EXPORTS.requireChildProcess || require('child_process');
-      EXPORTS.requireExpress = EXPORTS.requireExpress || require('express');
-      EXPORTS.requireCrypto = EXPORTS.requireCrypto || require('crypto');
-      EXPORTS.requireFs = EXPORTS.requireFs || require('fs');
-      EXPORTS.requireFsExtra = EXPORTS.requireFsExtra || require('fs-extra');
-      EXPORTS.requireHttp = EXPORTS.requireHttp || require('http');
-      EXPORTS.requireIstanbul = EXPORTS.requireIstanbul || require('istanbul');
-      EXPORTS.requireJslintLinter = EXPORTS.requireJslintLinter || require('./node_modules/jslint/lib/linter');
-      EXPORTS.requireJslintReporter = EXPORTS.requireJslintReporter || require('./node_modules/jslint/lib/reporter');
-      EXPORTS.requireMime = EXPORTS.requireMime || require('mime');
-      EXPORTS.requireModule = EXPORTS.requireModule || require('module');
-      EXPORTS.requireNopt = EXPORTS.requireNopt || require('nopt');
-      EXPORTS.requirePath = EXPORTS.requirePath || require('path');
-      EXPORTS.requireRepl = EXPORTS.requireRepl || require('repl');
-      EXPORTS.requireUrl = EXPORTS.requireUrl || require('url');
-      EXPORTS.requireUtil = EXPORTS.requireUtil || require('util');
-      EXPORTS.requireVm = EXPORTS.requireVm || require('vm');
-      EXPORTS.ARGV = EXPORTS.ARGV || EXPORTS.requireNopt();
-      EXPORTS.COVER = EXPORTS.COVER || new EXPORTS.requireIstanbul.Instrumenter();
-      EXPORTS.COVER_FILE = EXPORTS.COVER_FILE || {};
-      EXPORTS.FS_CWD = EXPORTS.FS_CWD || process.cwd();
-      EXPORTS.FS_MODULE = EXPORTS.FS_MODULE || EXPORTS.requirePath.dirname(module.filename);
-      EXPORTS.JSLINT_WATCH = EXPORTS.JSLINT_WATCH || {};
-      EXPORTS.MODULE = EXPORTS.MODULE || module;
-      EXPORTS.MODULES = EXPORTS.MODULES || {};
-      EXPORTS.MODULE_ACTION = {
-        base64Decode: EXPORTS.moduleBase64Decode,
-        cover: EXPORTS.moduleCover,
-        coverSelf: EXPORTS.moduleCoverSelf,
-        eval: EXPORTS.moduleEval,
-        jslint: EXPORTS.moduleJslint,
-        watch: EXPORTS.moduleWatch,
-        write: EXPORTS.moduleWrite
-      };
-      /**
-       * @attribute MODULE_FILE
-       */
-      EXPORTS.MODULE_FILE = EXPORTS.MODULE_FILE || {};
-      EXPORTS.MODULE_WATCH = EXPORTS.MODULE_WATCH || {};
-      EXPORTS.requireIstanbul.Store.mix(EXPORTS.requireIstanbul.Report.create('html').opts.sourceStore.constructor, {
-        get: function (key) {
-          return EXPORTS.COVER_FILE[key];
-        }
-      });
-      EXPORTS.STR_ASCII = EXPORTS.STR_ASCII || '\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
-      EXPORTS.TEST = EXPORTS.TEST || {};
-      EXPORTS.TEST_HTTP = EXPORTS.TEST_HTTP || {};
-      //// initialize command-line code
-      if (module === require.main) { local._cliInit(); }
-      //// initialize tinyjs libraries
-      require.extensions['.js2'] = EXPORTS.moduleLoad;
-      require('tinyjs-external');
-      require('./libStable.js2');
-      require('./libUnstable.js2');
-      //// debug
-      global[String('p' + 'rintd')] = console.log;
-      EXPORTS.moduleWatch(module);
-      EXPORTS.jslintWatch('./libUnused.js2');
-      //// start application
-      if (EXPORTS.startApp) { EXPORTS.startApp(); }
-      //// main command-line code
-      if (module === require.main) { local._cliMain(); }
-    },
-
-    _cliInit: function () {
-      //// initialize command-line code
-      Object.keys(EXPORTS.ARGV).forEach(function (key) {
-        var val = EXPORTS.ARGV[key];
-        if (!val) { return; }
-        //// auto-set environment variables
-        try { val = JSON.parse(val); } catch (errParse) {}
-        EXPORTS['IS_' + key.replace((/\W/g), '_').toUpperCase()] = val;
-        switch (key) {
-        case 'debug':
-          //// display environment
-          console.log(['process.argv', process.EXPORTS.ARGV]);
-          console.log(['cwd', EXPORTS.FS_CWD]);
-          console.log(['nodejs', process.version]);
-          console.log(['module', module.filename, module.id]);
-          break;
-        case 'port':
-          EXPORTS.HTTP_PORT = val;
-          break;
-        }
-      });
-      if (EXPORTS.EXIT) { process.exit(); }
-      //// initialize command-line modules
-      EXPORTS.ARGV.argv.remain.forEach(function (filename) {
-        require(EXPORTS.requirePath.resolve(EXPORTS.FS_CWD, filename));
-      });
-    },
-
-    _cliMain: function () {
-      //// main command-line code
-      Object.keys(EXPORTS.ARGV).forEach(function (key) {
-        var val = EXPORTS.ARGV[key];
-        if (!val) { return; }
-        switch (key) {
-        case 'rollup':
-          EXPORTS.externalRollup();
-          EXPORTS.EXIT = true;
-          break;
-        }
-      });
-      if (EXPORTS.EXIT) { process.exit(); }
-      //// start interactive debugger
-      EXPORTS.startRepl();
-      //// start http server if port exists
-      EXPORTS.startServer();
-      //// debug
-      EXPORTS.moduleWatch(module);
-      EXPORTS.jslintWatch(require.resolve('./package.json'));
-    },
-
-    coverInstrument: function (code, filename) {
-      var ii = 0;
-      EXPORTS.COVER_FILE[filename] = code;
-      switch ((/\w*$/).exec(filename)[0]) {
-      //// instrument js embedded in html
-      case 'html':
-        return code.replace((/<script>([\S\s]+)<\/script>/g), function (_, code) {
-          return '<script>' + EXPORTS.COVER.instrumentSync(code, filename + '.script.' + (ii += 1)) + '</script>';
-        });
-      //// instrument js
-      default:
-        return EXPORTS.COVER.instrumentSync(code, filename);
-      }
-    },
-
-    exportLocal: function (local) {
-      //// export local methods to EXPORTS
-      var arr, ii, key;
-      for (key in local) {
-        if (local.hasOwnProperty(key) && !(/^_|^init$/).test(key) && typeof local[key] === 'function') {
-          EXPORTS[key] = local[key];
-        }
-      }
-    },
-
-    _jslintIgnore: function (code) {
-      //// OPTIMIZATION - cached callback
-      return code.match('\n').join('');
-    },
-
-    jslintReport: function (filename, code) {
-      code = code || EXPORTS.requireFs.readFileSync(filename, 'utf8');
-      //// jslint ignore
-      code = code.replace(
-        (/^\/\*JSLINT_IGNORE_BEG\*\/$[\S\s]*?^\/\*JSLINT_IGNORE_END\*\/$/gm),
-        local._jslintIgnore
-      );
-      switch (EXPORTS.requirePath.extname(filename)) {
-      case '.css':
-        code = code.replace((/^(\n+)@charset "UTF-8";/), '@charset "UTF-8";$1');
-        break;
-      }
-      //// jslint file and report to stdout
-      EXPORTS.requireJslintReporter.report(
-        filename,
-        EXPORTS.requireJslintLinter.lint(code),
-        true
-      );
-    },
-
-    /**
-    watch file and auto-jslint if modified
-    @method jslintWatch
-    @param {String} filename
-    @static
-    **/
-    jslintWatch: function (filename) {
-      EXPORTS.JSLINT_WATCH[filename] = EXPORTS.JSLINT_WATCH[filename] || EXPORTS.requireFs.watchFile(
-        filename,
-        {interval: 1000, persistent: false},
-        function (curr, prev) {
-          if (curr.mtime > prev.mtime) { EXPORTS.jslintReport(filename); }
-        }
-      );
-    },
-
-    moduleBase64Decode: function (module, file, code) {
-      EXPORTS.MODULE_FILE[file.name] = new Buffer(code, 'base64');
-    },
-
-    moduleCover: function (module, file, code) {
-      if (EXPORTS.IS_COVER) {
-        EXPORTS.MODULE_FILE[file.name] = EXPORTS.coverInstrument(code, module.id + '.' + file.name);
-      }
-    },
-
-    moduleCoverSelf: function (module, file, code) {
-      if (EXPORTS.IS_COVER === 'self') {
-        EXPORTS.MODULE_FILE[file.name] = EXPORTS.coverInstrument(code, module.id + '.' + file.name);
-      }
-    },
-
-    moduleEval: function (module, file, code) {
-      code = code.replace((/^#!/m), '// #!');
-      module._compile(code, module.filename);
-    },
-
-    moduleJslint: function (module, file, code) {
-      code = code.replace((/^#!/m), '// #!');
-      EXPORTS.jslintReport(file.name, code);
-    },
-
-    moduleLoad: function (module) {
-      //// custom module loader
-      var content = EXPORTS.requireFs.readFileSync(module.filename, 'utf8');
-      //// if module is a filename, create a new module with filename as module id
-      if (typeof module === 'string') {
-        module = EXPORTS.requirePath.resolve(EXPORTS.FS_CWD, module);
-        module = EXPORTS.MODULES[module] || new EXPORTS.requireModule.Module(module);
-      }
-      EXPORTS.MODULES[module.id] = module;
-      //// bump up version
-      EXPORTS.VERSION = new Date().toISOString().replace((/(....)-(..)-(..)T(..):(..):(..).*/), '$1.$2.$3-$4.$5.$6');
-      return content.replace((/^\/\*FILE_BEG (.*?)\*\/$([\S\s]*?)^\/\*FILE_END\*\/$/gm), function (_, file, code, start) {
-        file = JSON.parse(file);
-        //// filename
-        file.name = file.name.replace((/\/FS_MODULE\b/), EXPORTS.FS_MODULE);
-        //// preserve line number position
-        code = (content.slice(0, start).match('\n') || []).join('') + code;
-        //// save source code
-        EXPORTS.MODULE_FILE[file.name] = EXPORTS.stringFormat ? EXPORTS.stringFormat(code, { EXPORTS: EXPORTS }) : code;
-        file.actions.forEach(function (action) {
-          EXPORTS.MODULE_ACTION[action](module, file, EXPORTS.MODULE_FILE[file.name]);
-        });
-      });
-    },
-
-    moduleWatch: function (module) {
-      //// auto-reload module if modified
-      EXPORTS.MODULE_WATCH[module.filename] = EXPORTS.MODULE_WATCH[module.filename] || EXPORTS.requireFs.watchFile(module.filename, {interval: 1000, persistent: false}, function (curr, prev) {
-        //// reload module if modified
-        if (curr.mtime > prev.mtime) { EXPORTS.moduleLoad(module, null, 'reload'); }
-      });
-    },
-
-    moduleWrite: function (module, file, code) {
-      //// write code to file
-      if (EXPORTS.IS_BUILD) {
-        EXPORTS.requireFs.writeFileSync(
-          EXPORTS.requirePath.resolve(EXPORTS.FS_CWD, file.name),
-          //// trim text
-          typeof code === 'string' ? code.trim() : code
-        );
-      }
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/

libStable.js2

-/**
- * @class EXPORTS
- * @module libStable.js2
- */
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf", "eval", "watch"], "name": "libGist.js"}*/
-/*jslint bitwise: true, indent: 2, nomen: true, regexp: true, stupid: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      //// EXPORTS
-      EXPORTS.exportLocal(local);
-    },
-
-    arrayZeros: function (length) {
-      var arr = [], ii = length;
-      while (ii > 0) {
-        arr.push(0);
-        ii -= 1;
-      }
-      return arr;
-    },
-
-    hashSha256: function (str) {
-      var hash = require('crypto').createHash('sha256');
-      hash.update(typeof str === 'string' || Buffer.isBuffer(str) ? str : String(str));
-      return hash.digest('hex');
-    },
-
-    /**
-     * JSON.stringify circular object
-     * @method jsonStringifyCircular
-     * @param {Object} obj
-     * @return {String}
-     * @static
-     */
-    jsonStringifyCircular: function (obj) {
-      return local._jsonStringifyCircularRecurse(obj, []);
-    },
-
-    _jsonStringifyCircularRecurse: function (obj, arr) {
-      var ii, keys, result, val;
-      if (obj) {
-        for (ii = 0; ii < arr.length; ii += 1) {
-          if (obj === arr[ii]) {
-            obj = '[Circular]';
-            break;
-          }
-        }
-      }
-      try {
-        return JSON.stringify(obj);
-      } catch (err) {
-      }
-      //// fallback
-      arr.push(obj);
-      result = '';
-      //// array
-      if (Array.isArray(obj)) {
-        for (ii = 0; ii < obj.length; ii += 1) {
-          val = local._jsonStringifyCircularRecurse(obj[ii], arr);
-          if (val !== undefined) {
-            result += val + ',';
-          }
-        }
-        return '[' + result.slice(0, -1) + ']';
-      }
-      //// object
-      keys = Object.keys(obj).sort();
-      for (ii = 0; ii < keys.length; ii += 1) {
-        val = local._jsonStringifyCircularRecurse(obj[keys[ii]], arr);
-        if (val !== undefined) {
-          result += JSON.stringify(keys[ii]) + ':' + val + ',';
-        }
-      }
-      return '{' + result.slice(0, -1) + '}';
-    },
-
-    jsonStringifySorted: function (obj) {
-      //// recursively JSON.stringify dictionaries in sorted-key order
-      var ii, keys, result, val;
-      result = '';
-      //// array
-      if (Array.isArray(obj)) {
-        for (ii = 0; ii < obj.length; ii += 1) {
-          val = local.jsonStringifySorted(obj[ii]);
-          if (val !== undefined) {
-            result += val + ',';
-          }
-        }
-        return '[' + result.slice(0, -1) + ']';
-      }
-      //// object
-      if (typeof obj === 'object' && obj !== null) {
-        keys = Object.keys(obj).sort();
-        for (ii = 0; ii < keys.length; ii += 1) {
-          val = local.jsonStringifySorted(obj[keys[ii]]);
-          if (val !== undefined) {
-            result += JSON.stringify(keys[ii]) + ':' + val + ',';
-          }
-        }
-        return '{' + result.slice(0, -1) + '}';
-      }
-      return JSON.stringify(obj);
-    },
-
-    objectFirstKey: function (obj) {
-      //// get first iterated key in object
-      var key;
-      for (key in obj) { if (obj.hasOwnProperty(key)) { return key; } }
-    },
-
-    shell: function (command) {
-      //// quick and dirty convenience function for running shell commands
-      require('child_process').spawn('/bin/sh', ['-c', command], {stdio: [0, 1, 2]});
-    },
-
-    streamReadBuffer: function (reader, callback) {
-      //// efficiently pipe readable stream to buffer
-      //// and run callback(error, buffer) on end
-      //// example usage:
-      //// function (request, response) {
-      ////   streadReadBuffer(request, function (error, buffer) {
-      ////     response.write(JSON.parse(buffer).interestingStuff);
-      ////     response.end();
-      ////   }));
-      //// }
-      var chunks = [], ended = false;
-      function onData(chunk) {
-        console.assert(Buffer.isBuffer(chunk));
-        chunks.push(chunk);
-      }
-      function onEnd(err) {
-        if (ended) { return; }
-        ended = true;
-        callback(err, !err && Buffer.concat(chunks));
-        reader.removeListener('close', onEnd);
-        reader.removeListener('data', onData);
-        reader.removeListener('end', onEnd);
-        reader.removeListener('error', onEnd);
-      }
-      reader.on('close', onEnd);
-      reader.on('data', onData);
-      reader.on('end', onEnd);
-      reader.on('error', onEnd);
-    },
-
-    stringFormat: function (template, options) {
-      function getValue(keys) {
-        //// get value from options using keys
-        var fndKey, rgxKey = (/["']([^"'])+|(\w+)/g), val = options;
-        while (true) {
-          fndKey = rgxKey.exec(keys);
-          if (!(fndKey && val)) { break; }
-          val = val[fndKey[0] || fndKey[1]];
-        }
-        return val;
-      }
-      return template.replace((/\{\{.+?\}\}/g), function (code) {
-        //// format {{...}}
-        var args, result;
-        args = code.split('(');
-        result = getValue(args.pop());
-        try {
-          return result === undefined ? code : args.length ? getValue(args.pop())(result) : result;
-        } catch (err) {
-          return code;
-        }
-      });
-    },
-
-    uuid4: function () {
-      //// return uuid4 string of form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
-      var uuid = '', ii;
-      for (ii = 0; ii < 32; ii += 1) {
-        switch (ii) {
-        case 8:
-        case 20:
-          uuid += '-';
-          uuid += (Math.random() * 16 | 0).toString(16);
-          break;
-        case 12:
-          uuid += '-';
-          uuid += '4';
-          break;
-        case 16:
-          uuid += '-';
-          uuid += (Math.random() * 4 | 8).toString(16);
-          break;
-        default:
-          uuid += (Math.random() * 16 | 0).toString(16);
-        }
-      }
-      return uuid;
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf", "eval"], "name": "libRepl.js"}*/
-/*jslint evil: true, indent: 2, nomen: true, regexp: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      //// EXPORTS
-      EXPORTS.exportLocal(local);
-      if (EXPORTS.REPL && EXPORTS.REPL.context) {
-        EXPORTS.REPL.context.EXPORTS = EXPORTS;
-        EXPORTS.REPL.eval = local._replEval;
-      }
-    },
-
-    _replEval: function (code, context, file, callback) {
-      try {
-        callback(null, EXPORTS.requireVm.runInThisContext(local._replParse(code), file));
-      } catch (err) {
-        callback(err);
-      }
-    },
-
-    _replParse: function (code) {
-      var aa, bb;
-      //// null -> "(null\n)"
-      if (!/^\(.*\n\)$/.test(code)) {
-        return code;
-      }
-      code = code.slice(1, -2);
-      while (/\w@@ /.test(code)) {
-        code = code.replace(/(\w)@@ ([\S\s]*)/, '$1($2)');
-      }
-      aa = code.split(' ');
-      bb = aa.slice(1).join(' ');
-      aa = aa[0];
-      switch (aa) {
-      //// execute /bin/sh commands in console
-      case '$':
-        EXPORTS.shell(bb);
-        return;
-      case 'error':
-        try {
-          EXPORTS.requireVm.runInThisContext(bb);
-        } catch (errEval) {
-          console.error(errEval.stack);
-        }
-        return;
-      case 'git':
-        EXPORTS.shell('git ' + (bb === 'log' ? 'log | head -n 18' : bb));
-        return;
-      case 'grep':
-        EXPORTS.shell(
-          'grep -in ' + JSON.stringify(bb) + ' $(find . -type f | grep -v "/\\.\\|\\b\\(\\.\\d\\|build\\|min\\|node_modules\\|rollup\\|swp\\|test\\|tmp\\)\\b")'
-        );
-        return;
-      //// print function
-      case 'print':
-        code = 'console.log(String(' + bb + '))';
-        break;
-      }
-      return '(' + code + '\n)';
-    },
-
-    startRepl: function () {
-      //// start interactive interpreter / debugger
-      EXPORTS.REPL = EXPORTS.REPL || EXPORTS.requireRepl.start({
-        eval: local._replEval,
-        useGlobal: true
-      });
-      local.init();
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf", "eval", "watch"], "name": "libHttp.js"}*/
-/*jslint indent: 2, nomen: true, regexp: true, stupid: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      //// EXPORTS
-      EXPORTS.exportLocal(local);
-      EXPORTS.HTTP_HANDLER = EXPORTS.HTTP_HANDLER || {};
-      EXPORTS.HTTP_HANDLER['/echo'] = EXPORTS.handlerEcho;
-      EXPORTS.HTTP_HANDLER['/http:'] = EXPORTS.handlerHttpProxy;
-      EXPORTS.HTTP_HANDLER['/https:'] = EXPORTS.handlerHttpProxy;
-      EXPORTS.HTTP_HANDLER['/public'] = EXPORTS.handlerStatic;
-      EXPORTS.HTTP_HISTORY = EXPORTS.HTTP_HISTORY || EXPORTS.arrayZeros(8);
-      EXPORTS.HTTP_SECURITY = EXPORTS.HTTP_SECURITY || {};
-      EXPORTS.HTTP_SECURITY['/echo'] = EXPORTS.HTTP_SECURITY['/echo'] || true;
-      EXPORTS.HTTP_SECURITY['/http:'] = EXPORTS.HTTP_SECURITY['/http:'] || true;
-      EXPORTS.HTTP_SECURITY['/https:'] = EXPORTS.HTTP_SECURITY['/https:'] || true;
-      EXPORTS.HTTP_SECURITY['/public'] = EXPORTS.HTTP_SECURITY['/public'] || true;
-      //// create http  server app
-      if (!EXPORTS.HTTP_APP) {
-        EXPORTS.HTTP_APP = EXPORTS.HTTP_APP || EXPORTS.requireExpress();
-        //// middleware - logging
-        EXPORTS.HTTP_APP.use(EXPORTS.requireExpress.logger('dev'));
-        //// middleware - security
-        EXPORTS.HTTP_APP.use(EXPORTS.middlewareSecurity);
-        //// middleware - dynamic path handler
-        EXPORTS.HTTP_APP.use(EXPORTS.middlewarePath);
-      }
-    },
-
-    handlerEcho: function (request, response) {
-      //// echo's back request along with post data if any
-      var headers, name;
-      response.writeHead(200, {'content-type': 'text/plain'});
-      response.write(request.method + ' ' + request.url + ' http/' + request.httpVersion + '\n');
-      headers = request.headers;
-      for (name in headers) {
-        if (headers.hasOwnProperty(name)) {
-          response.write(name + ': ' + JSON.stringify(headers[name]) + '\n');
-        }
-      }
-      response.write('\n');
-      //// OPTIMIZATION - stream data
-      request.pipe(response);
-    },
-
-    handlerHttpProxy: function (request, response, next) {
-      var key, options = {
-        url: /http.*/.exec(request.url)[0],
-        headers: {},
-        method: request.method,
-      };
-      //// modify proxy request headers
-      for (key in request.headers) {
-        if (request.headers.hasOwnProperty(key) && key !== 'host') {
-          options.headers[key] = request.headers[key];
-        }
-      }
-      //// error callback
-      options.callbackError = function (err) { next(err); };
-      //// response callback
-      options.callbackResponse = function (proxyResponse) {
-        response.writeHead(proxyResponse.statusCode, proxyResponse.headers);
-        //// OPTIMIZATION - stream data
-        proxyResponse.pipe(response);
-      };
-      //// OPTIMIZATION - stream data
-      request.pipe(EXPORTS.httpRequest(options));
-    },
-
-    handlerStatic: function (request, response, next) {
-      var readStream, path;
-      path = request.absolutePath;
-      //// OPTIMIZATION - client-side cache versioning
-      path = path.replace((/\/cacheVersion\/[^\/]+\//), '/cacheVersion/');
-      if (path !== request.absolutePath) {
-        response.setHeader('cache-control', 'public, max-age=2592000');
-      }
-      //// OPTIMIZATION - serve cached file from memory
-      if (EXPORTS.MODULE_FILE.hasOwnProperty(path)) {
-        response.setHeader('content-type', EXPORTS.requireMime.lookup(path));
-        response.end(EXPORTS.MODULE_FILE[path]);
-        return;
-      }
-      //// serve physical file
-      try {
-        readStream = EXPORTS.requireFs.createReadStream(EXPORTS.FS_CWD + path);
-        readStream.once('error', function (err) { next(err); });
-      } catch (errExists) {
-        next();
-        return;
-      }
-      readStream.once('open', function () {
-        response.setHeader('content-type', EXPORTS.requireMime.lookup(path));
-        //// OPTIMIZATION - stream file to response
-        readStream.pipe(response);
-      });
-    },
-
-    httpGet: function (options) {
-      //// quick and dirty http GET / POST client
-      //// example usage:
-      //// httpGet({data: require('fs').readFileSync('foo.png'), url: 'http://www.upload.com'});
-      var request;
-      if (options.data) {
-        options.method = options.method || 'POST';
-      }
-      request = EXPORTS.httpRequest(options);
-      request.end(options.data);
-    },
-
-    httpGetLocal: function (options) {
-      options.url = 'http://localhost:' + EXPORTS.HTTP_PORT + options.url;
-      options.headers = options.headers || {};
-      options.headers.authorization = options.headers.authorization || 'Basic ' + EXPORTS.ADMIN_BASIC_AUTH;
-      EXPORTS.httpGet(options);
-    },
-
-    httpGetTest: function (options) {
-      var callback = options.callback;
-      options.callback = function (err, data, response) {
-        if (err) {
-          throw err;
-        }
-        console.assert(response.statusCode < 500, response.statusCode);
-        (callback || EXPORTS.httpRequestCallback)(err, data, response);
-      };
-      EXPORTS.httpGetLocal(options);
-    },
-
-    httpRequest: function (options) {
-      var url = EXPORTS.requireUrl.parse(options.url), request;
-      //// OPTIMIZATION - disable socket pooling
-      options.agent = false;
-      options.callback = options.callback || EXPORTS.httpRequestCallback;
-      options.callbackResponse = options.callbackResponse || function (response) {
-        EXPORTS.streamReadBuffer(response, function (err, data) {
-          options.callback(err, data, response);
-        });
-      };
-      options.hostname = url.hostname;
-      options.path = url.path;
-      options.port = url.port;
-      //// DEBUG
-      if (EXPORTS.IS_DEBUG) { console.log(['httpRequest', options]); }
-      request = (options.protocol === 'https:' ? EXPORTS.requireHttps : EXPORTS.requireHttp).request(options, options.callbackResponse);
-      request.once('error', options.callback);
-      return request;
-    },
-
-    httpRequestCallback: function (err, data, response) {
-      //// default http client request callback - prints received data
-      if (err) {
-        console.error(err.stack);
-      } else {
-        console.log(response.statusCode);
-        console.log(data.toString());
-      }
-    },
-
-    middlewarePath: function (request, response, next) {
-      var path;
-      //// debug history of requests / responses
-      EXPORTS.request = request;
-      EXPORTS.response = response;
-      EXPORTS.HTTP_HISTORY.unshift({request: request, response: response, url: request.url});
-      EXPORTS.HTTP_HISTORY.pop();
-      //// dyanamic path handler
-      for (path = request.absolutePath; path.length > 1; path = path.replace(/\/+[^\/]*$/, '')) {
-        if (EXPORTS.HTTP_HANDLER.hasOwnProperty(path)) {
-          EXPORTS.HTTP_HANDLER[path](request, response, next);
-          return;
-        }
-      }
-      //// fallback to next middleware
-      next();
-    },
-
-    middlewareSecurity: function (request, response, next) {
-      var check, path;
-      //// SECURITY - resolve absolute url path
-      request.absolutePath = EXPORTS.requirePath.resolve(
-        '/' +
-          //// filter out query parameters
-          (/[^?&#]*/).exec(
-            //// SECURITY - limit path to 256 characters
-            request.url.slice(0, 256)
-          )[0]
-      ).replace(/\/+$/, '');
-      //// dyanamic path handler
-      for (path = request.absolutePath; path.length > 1; path = path.replace(/\/+[^\/]*$/, '')) {
-        if (EXPORTS.HTTP_SECURITY.hasOwnProperty(path)) {
-          check = EXPORTS.HTTP_SECURITY[path];
-          if (typeof check === 'function') {
-            check(request, response, next);
-            return;
-          }
-          if (check) {
-            next();
-            return;
-          }
-          break;
-        }
-      }
-      response.writeHead(404, {'content-type': 'text/plain'});
-      response.end('404 Not Found');
-    },
-
-    startServer: function (port) {
-      //// start http server on specified port
-      EXPORTS.HTTP_SERVER = EXPORTS.HTTP_SERVER || EXPORTS.requireHttp.createServer(EXPORTS.HTTP_APP).listen(EXPORTS.HTTP_PORT = EXPORTS.HTTP_PORT || 1337, function () {
-        console.log('express server listening on port ' + EXPORTS.HTTP_PORT);
-      });
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf", "eval", "watch"], "name": "libExternal.js"}*/
-/*jslint indent: 2, nomen: true, regexp: true, stupid: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      //// EXPORTS
-      EXPORTS.exportLocal(local);
-      EXPORTS.EXTERNAL_URL = {
-        //// jquery
-        'aa.jquery.js': 'http://code.jquery.com/jquery-1.9.1.js',
-        //// bootstrap
-        'bootstrap.glyphicons-halflings-white.png': 'http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/img/glyphicons-halflings-white.png',
-        'bootstrap.glyphicons-halflings.png': 'http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/img/glyphicons-halflings.png',
-        'bootstrap.css': 'http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.css',
-        'bootstrap.js': 'http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.js',
-        'bootstrap.responsive.css': 'http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap-responsive.css',
-        //// datatables
-        'datatables.back_disabled.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/back_disabled.png',
-        'datatables.back_enabled.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/back_enabled.png',
-        'datatables.back_enabled_hover.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/back_enabled_hover.png',
-        'datatables.css': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css',
-        'datatables.forward_disabled.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/forward_disabled.png',
-        'datatables.forward_enabled.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/forward_enabled.png',
-        'datatables.forward_enabled_hover.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/forward_enabled_hover.png',
-        'datatables.js': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.js',
-        'datatables.sort_asc.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_asc.png',
-        'datatables.sort_asc_disabled.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_asc_disabled.png',
-        'datatables.sort_both.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_both.png',
-        'datatables.sort_desc.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_desc.png',
-        'datatables.sort_desc_disabled.png': 'http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_desc_disabled.png',
-        //// datatables extra
-        'datatables.copy_csv_xls.swf': 'http://datatables.net/release-datatables/extras/TableTools/media/swf/copy_csv_xls.swf',
-        'datatables.copy_csv_xls_pdf.swf': 'http://datatables.net/release-datatables/extras/TableTools/media/swf/copy_csv_xls_pdf.swf',
-        'datatables.tabletools.js': 'http://datatables.net/release-datatables/extras/TableTools/media/js/TableTools.js',
-        //// select
-        'select2.css': 'https://raw.github.com/ivaynberg/select2/3.3.1/select2.css',
-        'select2.js': 'https://raw.github.com/ivaynberg/select2/3.3.1/select2.js',
-        'select2.png': 'https://raw.github.com/ivaynberg/select2/3.3.1/select2.png',
-        'select2x2.png': 'https://raw.github.com/ivaynberg/select2/3.3.1/select2x2.png',
-        //// image ajax loader
-        //// 'ajaxLoader.gif': 'http://www.ajaxload.info/download.php?img=cache/FF/FF/FF/00/00/00/26-1.gif',
-      };
-      EXPORTS.FS_EXTERNAL = EXPORTS.FS_EXTERNAL || EXPORTS.FS_MODULE + '/node_modules/tinyjs-external';
-      //// load public external assets
-      [
-        'externalRollup.css',
-        'externalRollup.js',
-      ].forEach(function (filename) {
-        if (EXPORTS.requireFs.existsSync(EXPORTS.FS_EXTERNAL + '/' + filename)) {
-          EXPORTS.MODULE_FILE['/public/cacheVersion/' + filename] = EXPORTS.requireFs.readFileSync(EXPORTS.FS_EXTERNAL + '/' + filename);
-        }
-      });
-      //// auto rollup
-      if (EXPORTS.EXTERNAL_ROLLUP) {
-        EXPORTS.externalRollup();
-      }
-    },
-
-    externalDataUri: function (filename) {
-      return '\n"data:' + EXPORTS.requireMime.lookup(filename) + ';base64,' + EXPORTS.requireFs.readFileSync(filename, 'base64') + '"\n';
-    },
-
-    externalGet: function (arr) {
-      var filename, ii = 0, obj = {};
-      function closure(filename) {
-        ii += 1;
-        EXPORTS.httpGet({
-          callback: function (err, data, response) {
-            var arr;
-            ii -= 1;
-            try {
-              if (err) { throw err; }
-              console.assert(response.statusCode === 200, response.statusCode);
-              EXPORTS.requireFs.writeFileSync(EXPORTS.FS_EXTERNAL + '/' + filename, data);
-              delete obj[filename];
-            } catch (errCallback) {
-              console.log(errCallback.stack);
-              console.log(response.headers);
-            }
-            console.log(filename, 'EXPORTS.externalGet(' + JSON.stringify(Object.keys(obj).sort()) + ')\n');
-            //// finished attempting to download all files
-            if (ii === 0) { console.log(obj); }
-          },
-          url: obj[filename]
-        });
-      }
-      //// debug - test culled EXPORTS.EXTERNAL_URL
-      (arr || Object.keys(EXPORTS.EXTERNAL_URL)).forEach(function (filename) {
-        obj[filename] = EXPORTS.EXTERNAL_URL[filename];
-      });
-      for (filename in obj) {
-        if (obj.hasOwnProperty(filename)) { closure(filename); }
-      }
-    },
-
-    externalRollup: function () {
-      var css = '', js = '';
-      Object.keys(EXPORTS.EXTERNAL_URL).sort().forEach(function (filename) {
-        switch (EXPORTS.requirePath.extname(filename)) {
-        case '.css':
-          css += EXPORTS._externalRollupFile(filename);
-          break;
-        case '.js':
-          js += EXPORTS._externalRollupFile(filename);
-          break;
-        }
-      });
-      [
-        'imgAjaxLoader.gif'
-      ].forEach(function (filename) {
-        css += '.' + (/\w+/).exec(filename) + ' { background: url(' + EXPORTS.externalDataUri(EXPORTS.FS_EXTERNAL + '/' + filename) + ') no-repeat center center;';
-      });
-      EXPORTS.requireFs.writeFileSync(EXPORTS.FS_EXTERNAL + '/externalRollup.css', css);
-      EXPORTS.requireFs.writeFileSync(EXPORTS.FS_EXTERNAL + '/externalRollup.js', js);
-    },
-
-    _externalRollupFile: function (filename) {
-      var data = EXPORTS.requireFs.readFileSync(EXPORTS.FS_EXTERNAL + '/' + filename, 'utf8') + '\n';
-      switch (filename) {
-      case 'bootstrap.css':
-        data = data.replace(/"\.\.\/img\/(.+)"/g, function (_, filename) {
-          return EXPORTS.externalDataUri(EXPORTS.FS_EXTERNAL + '/bootstrap.' + filename);
-        });
-        break;
-      case 'datatables.css':
-        data = data.replace(/'\.\.\/images\/(.+)'/g, function (_, filename) {
-          return EXPORTS.externalDataUri(EXPORTS.FS_EXTERNAL + '/datatables.' + filename);
-        });
-        break;
-      case 'select2.css':
-        data = data.replace(/'(\w+\.png)'/g, function (_, filename) {
-          return EXPORTS.externalDataUri(EXPORTS.FS_EXTERNAL + '/' + filename);
-        });
-        break;
-      }
-      return (data += '\n');
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf", "eval", "watch"], "name": "libAdmin.js"}*/
-/*jslint indent: 2, nomen: true, regexp: true, stupid: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      //// EXPORTS
-      EXPORTS.exportLocal(local);
-      EXPORTS.ADMIN_BASIC_AUTH = EXPORTS.ADMIN_BASIC_AUTH || new Buffer(Math.random().toString(16).slice(2) + ':' + Math.random().toString(16).slice(2)).toString('base64');
-      EXPORTS.HTTP_HANDLER['/admin'] = EXPORTS.handlerStatic;
-      EXPORTS.HTTP_SECURITY['/admin'] = EXPORTS.handlerAdminBasicAuth;
-    },
-
-    handlerAdminEval: function (request, response, next) {
-      EXPORTS.streamReadBuffer(request, function (err, data) {
-        if (err) {
-          next(err);
-          return;
-        }
-        try {
-          console.log(JSON.stringify(data.toString()));
-          data = EXPORTS.requireVm.runInThisContext(data);
-        } catch (errEval) {
-          next(errEval);
-        }
-        response.end(EXPORTS.jsonStringifyCircular(data));
-      });
-    },
-
-    adminBasicAuthGet: function () {
-      return new Buffer(EXPORTS.ADMIN_BASIC_AUTH, 'base64').toString();
-    },
-
-    adminBasicAuthSet: function (userPass) {
-      EXPORTS.ADMIN_BASIC_AUTH = new Buffer(userPass).toString('base64');
-    },
-
-    handlerAdminBasicAuth: function (request, response, next) {
-      if (/\S*$/.exec(request.headers.authorization || '')[0] === EXPORTS.ADMIN_BASIC_AUTH) {
-        next();
-        return;
-      }
-      response.writeHead(401, {'www-authenticate': 'basic realm="Authorization Required"'});
-      response.end('401 Unauthorized');
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf", "eval", "watch"], "name": "libDb.js"}*/
-/*jslint bitwise: true, indent: 2, nomen: true, regexp: true, stupid: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      if (!EXPORTS.HTTP_PORT) { return; }
-      //// EXPORTS
-      EXPORTS.exportLocal(local);
-      EXPORTS.FS_CWD = EXPORTS.FS_CWD || process.cwd();
-      EXPORTS.FS_TMP = EXPORTS.FS_TMP || '/tmp/' + EXPORTS.FS_CWD.replace(/\W/g, '_') + '_' + EXPORTS.HTTP_PORT;
-      EXPORTS.FS_CACHE = EXPORTS.FS_CACHE || EXPORTS.FS_TMP + '/cache';
-      EXPORTS.FS_DB = EXPORTS.FS_DB || EXPORTS.FS_TMP + '/db';
-      EXPORTS.HTTP_HANDLER['/admin/db'] = EXPORTS.handlerDb;
-      //// create directories
-      EXPORTS.requireFsExtra.mkdirpSync(EXPORTS.FS_CACHE);
-      EXPORTS.requireFsExtra.mkdirpSync(EXPORTS.FS_DB);
-      //// remove stale tmp files
-      EXPORTS.requireFs.readdir(EXPORTS.FS_CACHE, function (err, data) {
-        (data || []).forEach(function (key) {
-          //// physically remove files after 60000 ms
-          setTimeout(function () {
-            EXPORTS.requireFsExtra.remove(EXPORTS.FS_CACHE + '/' + key);
-          }, 60000);
-        });
-      });
-    },
-
-    dbAssertKey: function (key) {
-      console.assert(/^\w[\w\-\.]*$/.test(key), [key]);
-      return key;
-    },
-
-    dbAssertPath: function (path) {
-      console.assert(/^(?:\/\w[\w\-\.]*)+$/.test(path), [path]);
-      return path;
-    },
-
-    fsTempFilename: function (filename) {
-      return EXPORTS.FS_CACHE + '/' + (filename || '').replace(/\W/g, '_') + '.' + new Date().getTime().toString(16) + Math.random().toString(16).slice(1);
-    },
-
-    fsWriteFileAtomic: function (filename, data, callback) {
-      //// atomicly write file by first writing to temporary file, and then renaming to filename
-      var tmp = EXPORTS.fsTempFilename(filename);
-      EXPORTS.requireFs.writeFile(tmp, data, function (err) {
-        if (err) {
-          callback(err);
-          return;
-        }
-        EXPORTS.requireFs.rename(tmp, filename, callback);
-      });
-    },
-
-    handlerDb: function (request, response, next) {
-      EXPORTS.streamReadBuffer(request, function (err, data) {
-        var action, fnd, path;
-        function callback(err, data) {
-          if (err) {
-            next(err);
-            return;
-          }
-          response.end(Array.isArray(data) ? JSON.stringify(data) : data);
-        }
-        try {
-          fnd = /\/db\/([\w]+)(.*)/.exec(EXPORTS.dbAssertPath(request.absolutePath));
-          //// SECURITY - fs
-          if (!fnd || fnd[2].length >= 256) {
-            next();
-            return;
-          }
-          action = fnd[1] + fnd[2].split('/').length + ((data.length && 'Data') || '');
-          path = EXPORTS.FS_DB + fnd[2];
-          switch (action) {
-          //// get record
-          case 'get3':
-            EXPORTS.requireFs.readFile(path, callback);
-            return;
-          //// list tables
-          case 'list1':
-          //// list table
-          case 'list2':
-            EXPORTS.requireFs.readdir(path, callback);
-            return;
-          //// remove table
-          case 'remove2':
-            EXPORTS.requireFs.rmdir(path, callback);
-            return;
-          //// remove record
-          case 'remove3':
-            EXPORTS.requireFs.unlink(path, callback);
-            return;
-          //// rename table
-          case 'rename2Data':
-          //// rename record
-          case 'rename3Data':
-            EXPORTS.requireFs.rename(path, path.replace(/[^\/]+$/, '') + EXPORTS.dbAssertKey(data.toString()), callback);
-            return;
-          //// create table
-          case 'set2':
-            EXPORTS.requireFs.mkdir(path, callback);
-            return;
-          //// set record
-          case 'set3Data':
-            EXPORTS.fsWriteFileAtomic(path, data, callback);
-            return;
-          }
-          next();
-        } catch (errHandler) {
-          next(errHandler);
-        }
-      });
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf", "eval"], "name": "libTest.js"}*/
-/*jslint bitwise: true, indent: 2, nomen: true, regexp: true, stupid: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      //// EXPORTS
-      EXPORTS.exportLocal(local);
-      //// http tests
-      if (!EXPORTS.HTTP_SERVER) { return; }
-      EXPORTS.TEST_HTTP.proxy = function () {
-        EXPORTS.httpGetTest({
-          callback: function (err, data) {
-            data = data && data.toString();
-            console.assert(/^POST \/echo\/foo http\/1\.1\n[\S\s]+\nbar\n$/.test(data), [data]);
-          },
-          data: 'bar\n',
-          url: '/http://localhost:' + EXPORTS.HTTP_PORT + '/echo/foo',
-        });
-      };
-      EXPORTS.startTest();
-    },
-
-    coverClear: function () {
-      //// clear __coverage__
-      var arr, cov = global.__coverage__, key, obj;
-      for (key in cov) {
-        if (cov.hasOwnProperty(key)) {
-          obj = cov[key];
-          arr = obj.b;
-          for (key in arr) { if (arr.hasOwnProperty(key)) { arr[key] = [0, 0]; } }
-          arr = obj.f;
-          for (key in arr) { if (arr.hasOwnProperty(key)) { arr[key] = 0; } }
-          arr = obj.s;
-          for (key in arr) { if (arr.hasOwnProperty(key)) { arr[key] = 0; } }
-        }
-      }
-    },
-
-    startTest: function () {
-      EXPORTS.coverClear();
-      //// run tests
-      Object.keys(EXPORTS.TEST).sort().forEach(function (key) { EXPORTS.TEST[key](); });
-      if (EXPORTS.HTTP_SERVER) {
-        Object.keys(EXPORTS.TEST_HTTP).sort().forEach(function (key) {
-          EXPORTS.TEST_HTTP[key]();
-        });
-      }
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "write"], "name": "/FS_MODULE/package.json"}*/
-{
-  "author": "kai zhu <kaizhu256@gmail.com>",
-  "bin": { "tinyjs": "cli.js" },
-  "dependencies": {
-    "express": "*",
-    "fs-extra": "*",
-    "istanbul": "*",
-    "jslint": "*",
-    "mime": "*",
-    "nopt": "*",
-    "tinyjs-external": "*",
-    "uglify-js": "*",
-    "uglifycss": "*"
-  },
-  "description": "tinyjs is another nodejs micro-framework",
-  "engines": {
-    "node": ">=0.8.0"
-  },
-  "files": [
-    "cli.js",
-    "libStable.js2",
-    "libUnstable.js2",
-    "README.md"
-  ],
-  "homepage": "https://bitbucket.org/kaizhu/tinyjs",
-  "keywords": [
-    "micro framework", "tinyjs", "template", "zero config"
-  ],
-  "license": "BSD",
-  "main": "cli.js",
-  "name": "tinyjs",
-  "os" : [
-    "!win32"
-  ],
-  "repository": {
-    "type": "git",
-    "url": "https://bitbucket.org/kaizhu/tinyjs.git"
-  },
-  "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "version": "{{EXPORTS.VERSION}}"
-}
-/*FILE_END*/

libUnstable.js2

-/**
- * @class EXPORTS
- * @module libUnStable.js2
- */
-
-
-
-/*
-CHANGELOG
-auto-generate online documentation via yuidoc.
-
-TODO
-add optional istanbul coverage in require.
-add client-side interactive tests.
-rewrite db.
-*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf", "eval", "watch"], "name": "libUnstable.js"}*/
-/*jslint bitwise: true, continue: true, indent: 2, nomen: true, regexp: true, stupid: true*/
-(function () {
-
-  'use strict';
-
-  var EXPORTS = process.EXPORTS || {}, local = {
-
-    init: function () {
-      //// EXPORTS
-      EXPORTS.exportLocal(local);
-    },
-
-    coverReport: function () {
-      var collector = new EXPORTS.requireIstanbul.Collector();
-      collector.add(global.__coverage__);
-      EXPORTS.requireIstanbul.Report.create('lcov', { dir: EXPORTS.FS_CWD + '/coverage' }).writeReport(collector);
-    }
-
-  };
-
-  local.init();
-
-}());
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "coverSelf"], "name": "/admin/admin.html"}*/
-<html>
-<head>
-<link rel="stylesheet" href="/public/cacheVersion/{{EXPORTS.VERSION}}/externalRollup.css">
-<style>
-#formDbTableEdit .row-fluid {
-  display: none;
-}
-#formDbTableEdit[data-action="aDbRecordCopy"] .aDbRecordCopy {
-  display: block;
-}
-#formDbTableEdit[data-action="aDbRecordEdit"] .aDbRecordEdit {
-  display: block;
-}
-#formDbTableEdit[data-action="aDbRecordRename"] .aDbRecordRename {
-  display: block;
-}
-#formDbTableEdit[data-action="aDbTableCreate"] .aDbTableCreate {
-  display: block;
-}
-#formDbTableEdit[data-action="aDbTableRename"] .aDbTableRename {
-  display: block;
-}
-.imgAjaxLoader {
-  background-color: white;
-  border: 2px solid;
-  border-radius: 1em;
-  display: none;
-  height: 64px;
-  left: 49%;
-  position: absolute;
-  top: 49%;
-  width: 64px;
-  z-index: 99;
-}
-.marginBottom {
-  margin-bottom: 20px;
-}
-.marginLeft {
-  margin-left: 2em;
-}
-.marginTop {
-  margin-top: 20px;
-}
-</style>
-</head>
-<body>
-
-<span class="imgAjaxLoader" id="imgAjaxLoader"></span>
-
-<form class="fade form hide modal" id="formDbTableEdit"><div class="container-fluid">
-  <div class="marginBottom"></div>
-  <div class="aDbTableRename row-fluid">
-    <label>current table name</label>
-    <input class="span12" id="formDbTableEditNameOld" readonly type="text"/>
-  </div>
-  <div class="aDbTableCreate aDbTableRename row-fluid">
-    <label>new table name</label>
-    <input class="span12" id="formDbTableEditNameNew" placeholder="newTable" type="text"/>
-  </div>
-  <div class="aDbRecordCopy aDbRecordEdit aDbRecordRename row-fluid">
-    <label>current record key</label>
-    <input class="span12" id="formDbRecordEditKeyOld" readonly type="text"/>
-  </div>
-  <div class="aDbRecordCopy aDbRecordRename row-fluid">
-    <label>new record key</label>
-    <input class="span12" id="formDbRecordEditKeyNew" type="text"/>
-  </div>
-  <div class="aDbRecordCopy aDbRecordEdit row-fluid">
-    <label>record value</label>
-    <textarea class="span12" id="formDbRecordEditValue" rows="8"></textarea>
-  </div>
-  <div class="aDbRecordCopy aDbRecordEdit aDbRecordRename aDbTableCreate aDbTableRename controls row-fluid">
-    <button class="btn btn-success" data-dismiss="modal" id="formDbTableEditSubmit">submit</button>
-    <button class="btn btn-danger marginLeft" data-dismiss="modal">cancel</button>
-  </div>
-  <div class="marginBottom"></div>
-</div></form>
-
-<div class="hide" id="fragmentDbRecordEdit">
-  <div class="btn-group">
-    <button class="btn btn-mini inputDbRecordSelect" data-toggle="button">select</button>
-    <button class="btn btn-mini dropdown-toggle" data-toggle="dropdown">edit <span class="caret"></span></button>
-    <ul class="dropdown-menu" data-key="{{key}}">
-      <li><a class="aDbRecordCopy" href="#">copy</a></li>
-      <li><a class="aDbRecordEdit" href="#">edit</a></li>
-      <li><a class="aDbRecordRename" href="#">rename</a></li>
-    </ul>
-  </div>
-</div>
-
-<div class="container-fluid marginTop">
-  <label class="control-label">table</label>
-  <div class="btn-group">
-    <button class="btn dropdown-toggle" data-toggle="dropdown" id="btnDbTableSelect">select table <span class="caret"></span></button>
-    <ul class="dropdown-menu" id="ulDbTables">
-    </ul>
-  </div>
-<div class="control-group row-fluid">
-  <div class="btn-group form-inline span12">
-    <button class="btn dropdown-toggle span2" data-toggle="dropdown" id="btnDbTableAction">table action <span class="caret"></span></button>
-    <ul class="dropdown-menu">
-      <li><a href="#" id="aDbTableCreate">create table</a></li>
-      <li><a id="aDbTableRemove" href="#">remove table</a></li>
-      <li><a href="#" id="aDbTableRename">rename table</a></li>
-      <li><a href="#" id="aDbTableSelect">select table</a></li>
-    </ul>
-    <input class="span10" id="inputDbTableId" readonly type="text"/>
-  </div>
-</div>
-
-<div class="marginTop"></div>
-<table class="dataTable" id="tableDbTable"></table>
-</div>
-
-<script src="/public/cacheVersion/{{EXPORTS.VERSION}}/externalRollup.js"></script>
-<script>
-/*global jQuery: false*/
-/*jslint bitwise: true, browser: true, indent: 2, nomen: true, regexp: true*/
-jQuery(document).ready(function () {
-  'use strict';
-
-  var dom = {}, local;
-
-  //// debug
-  window[String('p' + 'rintd')] = console.log;
-
-  local = {
-
-    adminEval: function (code, callback) {
-      local.ajax({
-        callback: callback,
-        contentType: 'application/octet-stream',
-        data: code,
-        method: 'POST',
-        url: '/admin/eval'
-      });
-    },
-
-    ajax: function (options) {
-      options.datatype = options.datatype || 'text';
-      dom.imgAjaxLoader.style.display = 'inline';
-      jQuery.ajax(options).done(function (data, statusCode, xhr) {
-        dom.imgAjaxLoader.style.display = 'none';
-        if (options.callback) {
-          options.callback(data, statusCode, xhr);
-          return;
-        }
-        window.AJAX_DATA = data;
-        try {
-          window.AJAX_DATA_JSON = JSON.parse(data);
-        } catch (errParse) {
-        }
-        console.log(data);
-      });
-    },
-
-    //// example usage - local.dbAction('/get/namespace1/table1')
-    dbAction: function (url, data, callback) {
-      if (!callback && typeof data === 'function') {
-        callback = data;
-        data = null;
-      }
-      local.ajax({
-        callback: callback,
-        data: data,
-        type: 'POST',
-        url: '/admin/db/' + url
-      });
-    },
-
-    _dbGetRecord: function (data) {
-      dom.formDbRecordEditValue.innerHTML = data;
-      jQuery(dom.formDbTableEdit).modal('show');
-    },
-
-    dbGetRecord: function (target, action) {
-      var id = target.parentElement.parentElement.getAttribute('data-key');
-      dom.formDbRecordEditKeyOld.value = id;
-      dom.formDbRecordEditKeyNew.value = local.uuid4();
-      dom.formDbTableEdit.setAttribute('data-action', action);
-      local.dbAction('/get/' + local.DB_TABLE_ID + '/' + id, null, local._dbGetRecord);
-    },
-
-    _dbListTable: function (arr) {
-      var ii;
-      arr = JSON.parse(arr);
-      for (ii = 0; ii < arr.length; ii += 1) {
-        arr[ii] = [
-          dom.fragmentDbRecordEdit.innerHTML.replace('{{key}}',  arr[ii]),
-          arr[ii]
-        ];
-      }
-      jQuery(dom.tableDbTable).dataTable({
-        aaData: arr,
-        aaSorting: [[1, 'asc']],
-        aoColumns: [
-          {bSortable: false, sTitle: 'select / edit', sWidth: '6em'},
-          {sTitle: 'id'}
-        ],
-        bDeferRender: true,
-        bDestroy: true,
-        bProcessing: true,
-        iDisplayLength: 100
-      });
-    },
-
-    dbListTable: function (id) {
-      local.DB_TABLE_ID = local.localStorageSetItemOrClear('DB_TABLE_ID', id);
-      dom.btnDbTableSelect.innerHTML = id + ' <span class="caret"><\/span>';
-      local.dbAction('/list/' + id, null, local._dbListTable);
-    },
-
-    _dbListTables: function (arr) {
-      var ii, html = '';
-      arr = JSON.parse(arr);
-      for (ii = 0; ii < arr.length; ii += 1) {
-        html += '<li><a class="aDbTableSelect" href="#">' + arr[ii] + '<\/a><\/li>';
-      }
-      dom.ulDbTables.innerHTML = html;
-    },
-
-    dbListTables: function () {
-      local.dbAction('/list', null, local._dbListTables);
-    },
-
-    eventHandler: function (evt) {
-      var ii, target = evt.target;
-      //// debug
-      window.evt = evt;
-      console.log([evt, evt.target]);
-      switch (evt.type) {
-      case 'click':
-        switch (target.id) {
-        case 'aDbTableCreate':
-          dom.formDbTableEdit.setAttribute('data-action', target.id);
-          jQuery(dom.formDbTableEdit).modal('show');
-          return;
-        case 'aDbTableRemove':
-          if (!window.confirm('remove table "' + local.DB_TABLE_ID + '"?')) {
-            return;
-          }
-          local.dbAction('/remove/' + local.DB_TABLE_ID, null, local.dbListTables);
-          return;
-        case 'aDbTableRename':
-          dom.formDbTableEditNameOld.value = local.DB_TABLE_ID;
-          dom.formDbTableEdit.setAttribute('data-action', target.id);
-          jQuery(dom.formDbTableEdit).modal('show');
-          return;
-        case 'aDbTableSelect':
-          dom.formDbTableEdit.setAttribute('data-action', target.id);
-          jQuery(dom.formDbTableEdit).modal('show');
-          return;
-        }
-        for (ii = 0; ii < target.classList.length; ii += 1) {
-          switch (target.classList[ii]) {
-          case 'aDbRecordCopy':
-          case 'aDbRecordEdit':
-            local.dbGetRecord(target, target.classList[ii]);
-            return;
-          case 'aDbRecordRename':
-            dom.formDbRecordEditKeyOld.value = target.parentElement.parentElement.getAttribute('data-key');
-            dom.formDbRecordEditKeyNew.value = local.uuid4();
-            dom.formDbTableEdit.setAttribute('data-action', target.classList[ii]);
-            jQuery(dom.formDbTableEdit).modal('show');
-            return;
-          //// select table
-          case 'aDbTableSelect':
-            evt.preventDefault();
-            local.dbListTable(target.innerHTML);
-            return;
-          }
-        }
-        return;
-      }
-    },
-
-    localStorageSetItemOrClear: function (key, val) {
-      //// auto-clear local storage if maximum space exceeded
-      try {
-        localStorage.setItem(key, val);
-      } catch (err) {
-        localStorage.clear();
-        localStorage.setItem(key, val);
-      }
-      return val;
-    },
-
-    uuid4: function () {
-      //// return uuid4 string of form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
-      var uuid = '', ii;
-      for (ii = 0; ii < 32; ii += 1) {
-        switch (ii) {
-        case 8:
-        case 20:
-          uuid += '-';
-          uuid += (Math.random() * 16 | 0).toString(16);
-          break;
-        case 12:
-          uuid += '-';
-          uuid += '4';
-          break;
-        case 16:
-          uuid += '-';
-          uuid += (Math.random() * 4 | 8).toString(16);
-          break;
-        default:
-          uuid += (Math.random() * 16 | 0).toString(16);
-        }
-      }
-      return uuid;
-    },
-
-    init: function () {
-      var arr, ii;
-      //// event handlers
-      document.onclick = local.eventHandler;
-      //// auto index elements by id
-      arr = document.querySelectorAll('[id]');
-      for (ii = 0; ii < arr.length; ii += 1) { dom[arr[ii].id] = arr[ii]; }
-      //// restore state
-      local.DB_TABLE_ID = localStorage.getItem('DB_TABLE_ID');
-      //// refresh
-      local.dbListTables();
-      if (local.DB_TABLE_ID) {
-        local.dbListTable(local.DB_TABLE_ID);
-      }
-      //// EXPORTS
-      window.dom = dom;
-      window.local = local;
-      Object.keys(local).forEach(function (key) {
-        if (!window.hasOwnProperty(key)) { window[key] = local[key]; }
-      });
-    }
-
-  };
-
-  local.init();
-
-});
-</script>
-</body>
-</html>
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "write"], "name": "/FS_MODULE/.gitignore"}*/
-.DS_Store
-.gitignore
-node_modules
-yuidoc.json
-/*FILE_END*/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "write"], "name": "/FS_MODULE/yuidoc.json"}*/
-{
-  "options": {
-    "port": "4060",
-    "extension": ".js,.js2",
-    "outdir": "./docs"
-  }
-}
-/*FILE_END*/

libUnused.js2

-/**
-@class libUnused
-@module libUnused.js2
-**/
-
-
-
-/*FILE_BEG {"actions": ["jslint", "watch"], "name": "libUnused.js"}*/
-/*jslint bitwise: true, indent: 2, nomen: true*/
-(function () {
-  'use strict';
-
-  var EXPORTS = process.EXPORTS, local = {
-
-    arrayRandom: function (length) {
-      //// create an array with random numbers
-      var arr = [], ii = length;
-      while (ii > 0) {
-        arr.push(Math.random());
-        ii -= 1;
-      }
-      return arr;
-    },
-
-    arrayRange: function (length) {
-      var arr = [], ii;
-      for (ii = 0; ii < length; ii += 1) {
-        arr.push(ii);
-      }
-      return arr;
-    },
-
-    arrayShuffle: function (arr) {
-      //// randomly shuffle elements in array
-      var ii, rnd, swap;
-      for (ii = 1; ii <= arr.length; ii += 1) {
-        //// OPTIMIZATION - Fisher-Yates algorithm
-        rnd = Math.floor(Math.random() * ii);
-        swap = arr[ii];
-        arr[ii] = arr[rnd];
-        arr[rnd] = swap;
-      }
-    },
-
-    echo: function (obj) {
-      return obj;
-    },
-
-    echoArguments: function () {
-      return arguments;
-    },
-
-    _jsStringifyCircular: function (obj, arr) {
-      var ii, keys, result, val;
-      if (obj) {
-        for (ii = 0; ii < arr.length; ii += 1) {
-          if (obj === arr[ii]) {
-            obj = '[Circular]';
-            break;
-          }
-        }
-      }
-      try {
-        return JSON.stringify(obj);
-      } catch (err) {
-      }
-      //// fallback
-      arr.push(obj);
-      result = '';
-      //// array
-      if (Array.isArray(obj)) {
-        for (ii = 0; ii < obj.length; ii += 1) {
-          val = local._jsStringifyCircular(obj[ii], arr);
-          if (val !== undefined) {
-            result += val + ',';
-          }
-        }
-        return '[' + result.slice(0, -1) + ']';
-      }
-      //// object
-      keys = Object.keys(obj).sort();
-      for (ii = 0; ii < keys.length; ii += 1) {
-        val = local._jsStringifyCircular(obj[keys[ii]], arr);
-        if (val !== undefined) {
-          result += JSON.stringify(keys[ii]) + ':' + val + ',';
-        }
-      }
-      return '{' + result.slice(0, -1) + '}';
-    },
-
-    jsStringifyCircular: function (obj) {
-      //// stringify circular objects
-      return local._jsStringifyCircular(obj, []);
-    },
-
-    _jsStringifySorted: function (obj) {
-      //// stringify with object keys sorted
-      var ii, keys, result, val;
-      result = '';
-      //// array
-      if (Array.isArray(obj)) {
-        for (ii = 0; ii < obj.length; ii += 1) {
-          val = local._jsStringifySorted(obj[ii]);
-          if (val !== undefined) {
-            result += val + ',';
-          }
-        }
-        return '[' + result.slice(0, -1) + ']';
-      }
-      //// object
-      if (typeof obj === 'object' && obj !== null) {
-        keys = Object.keys(obj).sort();
-        for (ii = 0; ii < keys.length; ii += 1) {
-          val = local._jsStringifySorted(obj[keys[ii]]);
-          if (val !== undefined) {
-            result += JSON.stringify(keys[ii]) + ':' + val + ',';
-          }
-        }
-        return '{' + result.slice(0, -1) + '}';
-      }
-      return JSON.stringify(obj);
-    },
-
-    nop: function () {},
-
-  };
-
-  function Cache(size) {
-    this.size = size;
-    this.clear();
-  }
-
-  Cache.prototype = {
-
-    clear: function () {
-      //// clear cache
-      this.arr1 = {};
-      this.arr2 = {};
-      this.ii = this.size;
-    },
-
-    gc: function (force) {
-      //// garbage collect arbitray number of lru items
-      this.ii -= 1;
-      if (force || this.ii <= 0) {
-        this.arr1 = this.arr2;
-        this.arr2 = {};
-        this.ii = this.size;
-      }
-    },
-
-    getItem: function (key) {
-      this.gc();
-      return (this.arr2[key] = this.arr1[key]);
-    },
-
-    setItem: function (key, val) {
-      this.gc();
-      this.arr2[key] = this.arr1[key] = val;
-    },
-
-    _objectCullEmpty: function (obj, key) {
-      var empty, key2, val = obj[key];
-      if (typeof val !== 'object') {
-        return val === undefined;
-      }
-      empty = true;
-      for (key2 in val) {
-        if (val.hasOwnProperty(key2)) {
-          empty &= local._objectCullEmpty(val, key2);
-        }
-      }
-      if (empty) {
-        obj[key] = undefined;
-        return true;
-      }
-    },
-
-    objectCullEmpty: function (obj) {
-      //// recursively set empty objects and nulls to undefined
-      local._objectCullEmpty(obj = [obj], 0);
-      return obj[0];
-    },
-
-    objectUpdateIfUndefined: function (aa, bb) {
-      var key, val;
-      for (key in bb) { if (bb.hasOwnProperty(key) && !aa.hasOwnProperty(key)) { aa[key] = bb[key]; } }
-    },
-
-    printe: function (err) {
-      if (err) {
-        console.error(err.stack);
-      }
-    },
-
-  };
-
-}());
-/*FILE_END*/
+#!/usr/bin/env node
+
+
+
+/*
+CHANGELOG
+merge cli.js, libStable.js2, libUnstable.js into moduleMain.js. migrate from nopt to commander.
+
+TODO
+add client-side interactive tests.
+rewrite db.
+*/
+
+
+
+/**
+ * @class EXPORTS
+ */
+
+
+
+/*FILE_BEG {"actions": ["jslint", "cover", "eval", "watch"], "name": "/FS_MODULE/moduleMain.js"}*/
+/*jslint bitwise: true, evil: true, indent: 2, nomen: true, regexp: true, stupid: true*/
+
+
+
+/**
+ * initialization code
+ * @module moduleInit
+ */
+
+(function () {
+
+  'use strict';
+
+  var EXPORTS = process.EXPORTS = process.EXPORTS || {}, local = {
+
+    _init: function () {
+      //// EXPORTS
+      EXPORTS.exportLocal = local.exportLocal;
+      EXPORTS.exportLocal(local);
+      EXPORTS.require = EXPORTS.require || require;
+      EXPORTS.requireChildProcess = EXPORTS.requireChildProcess || require('child_process');
+      EXPORTS.requireCommander = EXPORTS.requireCommander || require('commander');
+      EXPORTS.requireCrypto = EXPORTS.requireCrypto || require('crypto');
+      EXPORTS.requireExpress = EXPORTS.requireExpress || require('express');
+      EXPORTS.requireFs = EXPORTS.requireFs || require('fs');
+      EXPORTS.requireFsExtra = EXPORTS.requireFsExtra || require('fs-extra');
+      EXPORTS.requireHttp = EXPORTS.requireHttp || require('http');
+      EXPORTS.requireIstanbul = EXPORTS.requireIstanbul || require('istanbul');
+      EXPORTS.requireJslintLinter = EXPORTS.requireJslintLinter || require('./node_modules/jslint/lib/linter');
+      EXPORTS.requireJslintReporter = EXPORTS.requireJslintReporter || require('./node_modules/jslint/lib/reporter');
+      EXPORTS.requireMime = EXPORTS.requireMime || require('mime');
+      EXPORTS.requireModule = EXPORTS.requireModule || require('module');
+      EXPORTS.requirePath = EXPORTS.requirePath || require('path');
+      EXPORTS.requireRepl = EXPORTS.requireRepl || require('repl');
+      EXPORTS.requireUrl = EXPORTS.requireUrl || require('url');
+      EXPORTS.requireUtil = EXPORTS.requireUtil || require('util');
+      EXPORTS.requireVm = EXPORTS.requireVm || require('vm');
+      EXPORTS.ARGV = EXPORTS.ARGV || EXPORTS.requireCommander
+        .option('--build', 'build mode')
+        .option('--cover', 'enable code coverage')
+        .option('--debug', 'debug mode')
+        .option('--port []', 'http port', parseInt)
+        .parse(process.argv);
+      console.log(EXPORTS.requireCommander);
+      EXPORTS.COVER = EXPORTS.COVER || new EXPORTS.requireIstanbul.Instrumenter();
+      EXPORTS.COVER_FILE = EXPORTS.COVER_FILE || {};
+      EXPORTS.FS_CWD = EXPORTS.FS_CWD || process.cwd();
+      EXPORTS.FS_MODULE = EXPORTS.FS_MODULE || EXPORTS.requirePath.dirname(module.filename);
+      EXPORTS.JSLINT_WATCH = EXPORTS.JSLINT_WATCH || {};
+      EXPORTS.MODULE = EXPORTS.MODULE || module;
+      EXPORTS.MODULES = EXPORTS.MODULES || {};
+      EXPORTS.MODULE_ACTION = {
+        base64Decode: EXPORTS.moduleBase64Decode,
+        cover: EXPORTS.moduleCover,
+        eval: EXPORTS.moduleEval,
+        jslint: EXPORTS.moduleJslint,
+        watch: EXPORTS.moduleWatch,
+        write: EXPORTS.moduleWrite
+      };
+      /**
+       * @attribute MODULE_FILE
+       */
+      EXPORTS.MODULE_FILE = EXPORTS.MODULE_FILE || {};
+      EXPORTS.MODULE_WATCH = EXPORTS.MODULE_WATCH || {};
+      EXPORTS.requireIstanbul.Store.mix(EXPORTS.requireIstanbul.Report.create('html').opts.sourceStore.constructor, {
+        get: function (key) {
+          return EXPORTS.COVER_FILE[key];
+        }
+      });
+      EXPORTS.STR_ASCII = EXPORTS.STR_ASCII || '\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+      EXPORTS.TEST = EXPORTS.TEST || {};
+      EXPORTS.TEST_HTTP = EXPORTS.TEST_HTTP || {};
+      //// initialize command-line code
+      if (module !== require.main) { return; }
+      Object.keys(EXPORTS.ARGV).forEach(function (key) {
+        var val = EXPORTS.ARGV[key];
+        if (!val) { return; }
+        //// auto-set environment variables
+        try { val = JSON.parse(val); } catch (errParse) {}
+        EXPORTS['IS_' + key.replace((/\W/g), '_').toUpperCase()] = val;
+        switch (key) {
+        case 'debug':
+          //// display environment
+          console.log(['process.argv', process.EXPORTS.ARGV]);
+          console.log(['cwd', EXPORTS.FS_CWD]);
+          console.log(['nodejs', process.version]);
+          console.log(['module', module.filename, module.id]);
+          break;
+        case 'port':
+          EXPORTS.HTTP_PORT = val;
+          break;
+        }
+      });
+      //// initialize command-line modules
+      EXPORTS.ARGV.args.forEach(function (filename) {
+        require(EXPORTS.requirePath.resolve(EXPORTS.FS_CWD, filename));
+      });
+    },
+
+    coverClear: function () {
+      //// clear __coverage__
+      var arr, cov = global.__coverage__, key, obj;
+      for (key in cov) {
+        if (cov.hasOwnProperty(key)) {
+          obj = cov[key];
+          arr = obj.b;
+          for (key in arr) { if (arr.hasOwnProperty(key)) { arr[key] = [0, 0]; } }
+          arr = obj.f;
+          for (key in arr) { if (arr.hasOwnProperty(key)) { arr[key] = 0; } }
+          arr = obj.s;
+          for (key in arr) { if (arr.hasOwnProperty(key)) { arr[key] = 0; } }
+        }
+      }
+    },
+
+    coverInstrument: function (code, filename) {
+      var ii = 0;
+      switch ((/\w*$/).exec(filename)[0]) {
+      //// instrument javascript embedded in .html file
+      case 'html':
+        EXPORTS.COVER_FILE[filename] = code;
+        return code.replace((/<script>([\S\s]+)<\/script>/g), function (_, code) {
+          return '<script>' + EXPORTS.COVER.instrumentSync(code, filename + '.script.' + (ii += 1)) + '</script>';
+        });
+      //// instrument .js file
+      case 'js':
+        EXPORTS.COVER_FILE[filename] = code;
+        return EXPORTS.COVER.instrumentSync(code, filename);
+      default:
+        return code;
+      }
+    },
+
+    coverReport: function () {
+      var collector = new EXPORTS.requireIstanbul.Collector();
+      collector.add(global.__coverage__);
+      EXPORTS.requireIstanbul.Report.create('lcov', { dir: EXPORTS.FS_CWD + '/coverage' }).writeReport(collector);
+    },
+
+    exportLocal: function (local) {
+      //// export local methods to EXPORTS
+      var arr, ii, key;
+      for (key in local) {
+        if (local.hasOwnProperty(key) && key[0] !== '_') {
+          EXPORTS[key] = local[key];
+        }
+      }
+    },
+
+    jslintReport: function (filename, code) {
+      code = code || EXPORTS.requireFs.readFileSync(filename, 'utf8');
+      //// jslint ignore
+      code = code.replace(
+        (/^\/\*JSLINT_IGNORE_BEG\*\/$[\S\s]*?^\/\*JSLINT_IGNORE_END\*\/$/gm),
+        local._jslintReportIgnore
+      );
+      switch (EXPORTS.requirePath.extname(filename)) {
+      case '.css':
+        code = code.replace((/^(\n+)@charset "UTF-8";/), '@charset "UTF-8";$1');
+        break;
+      }
+      //// jslint file and report to stdout
+      EXPORTS.requireJslintReporter.report(
+        filename,
+        EXPORTS.requireJslintLinter.lint(code),
+        true
+      );
+    },
+
+    _jslintReportIgnore: function (code) {
+      //// OPTIMIZATION - cached callback
+      return code.match('\n').join('');
+    },
+
+    /**
+     * watch file and auto-jslint if modified
+     * @method jslintWatch
+     * @param {String} filename
+     * @static
+     */
+    jslintWatch: function (filename) {
+      EXPORTS.JSLINT_WATCH[filename] = EXPORTS.JSLINT_WATCH[filename] || EXPORTS.requireFs.watchFile(
+        filename,
+        {interval: 1000, persistent: false},
+        function (curr, prev) {
+          if (curr.mtime > prev.mtime) { EXPORTS.jslintReport(filename); }
+        }
+      );
+    },
+
+    moduleBase64Decode: function (module, file, code) {
+      EXPORTS.MODULE_FILE[file.name] = new Buffer(code, 'base64');
+    },
+
+    moduleCover: function (module, file, code) {
+      if (EXPORTS.IS_COVER) {
+        EXPORTS.MODULE_FILE[file.name] = EXPORTS.coverInstrument(code, module.id + '.' + file.name);
+      }
+    },
+
+    moduleEval: function (module, file, code) {
+      code = code.replace((/^#!/m), '// #!');
+      module._compile(code, module.filename);
+    },
+
+    moduleJslint: function (module, file, code) {
+      code = code.replace((/^#!/m), '// #!');
+      EXPORTS.jslintReport(file.name, code);
+    },
+
+    moduleLoad: function (module) {
+      //// custom module loader
+      var content = EXPORTS.requireFs.readFileSync(module.filename, 'utf8');
+      //// if module is a filename, create a new module with filename as module id
+      if (typeof module === 'string') {
+        module = EXPORTS.requirePath.resolve(EXPORTS.FS_CWD, module);
+        module = EXPORTS.MODULES[module] || new EXPORTS.requireModule.Module(module);
+      }
+      EXPORTS.MODULES[module.id] = module;
+      //// bump up version
+      EXPORTS.VERSION = new Date().toISOString().replace((/(....)-(..)-(..)T(..):(..):(..).*/), '$1.$2.$3-$4.$5.$6');
+      return content.replace((/^\/\*FILE_BEG (.*?)\*\/$([\S\s]*?)^\/\*FILE_END\*\/$/gm), function (_, file, code, start) {
+        file = JSON.parse(file);
+        //// filename
+        file.name = file.name.replace((/\/FS_MODULE\b/), EXPORTS.FS_MODULE);
+        //// preserve line number position
+        code = (content.slice(0, start).match('\n') || []).join('') + code;
+        //// save source code
+        EXPORTS.MODULE_FILE[file.name] = EXPORTS.stringFormat ? EXPORTS.stringFormat(code, { EXPORTS: EXPORTS }) : code;
+        file.actions.forEach(function (action) {
+          EXPORTS.MODULE_ACTION[action](module, file, EXPORTS.MODULE_FILE[file.name]);
+        });
+      });
+    },
+
+    moduleWatch: function (module) {
+      //// auto-reload module if modified
+      EXPORTS.MODULE_WATCH[module.filename] = EXPORTS.MODULE_WATCH[module.filename] || EXPORTS.requireFs.watchFile(module.filename, {interval: 1000, persistent: false}, function (curr, prev) {
+        //// reload module if modified
+        if (curr.mtime > prev.mtime) { EXPORTS.moduleLoad(module, null, 'reload'); }
+      });
+    },
+
+    moduleWrite: function (module, file, code) {
+      //// write code to file
+      if (EXPORTS.IS_BUILD) {
+        EXPORTS.requireFs.writeFileSync(
+          EXPORTS.requirePath.resolve(EXPORTS.FS_CWD, file.name),
+          //// trim text
+          typeof code === 'string' ? code.trim() : code
+        );
+      }
+    }
+
+  };
+
+  local._init();
+
+}());
+
+
+
+/**
+ * @module moduleGist
+ */
+
+(function () {
+
+  'use strict';
+
+  var EXPORTS = process.EXPORTS || {}, local = {
+
+    _init: function () {
+      //// EXPORTS
+      EXPORTS.exportLocal(local);
+    },
+
+    arrayZeros: function (length) {
+      var arr = [], ii = length;
+      while (ii > 0) {
+        arr.push(0);
+        ii -= 1;
+      }
+      return arr;
+    },
+
+    hashSha256: function (str) {
+      var hash = require('crypto').createHash('sha256');
+      hash.update(typeof str === 'string' || Buffer.isBuffer(str) ? str : String(str));
+      return hash.digest('hex');
+    },
+
+    /**
+     * JSON.stringify circular object
+     * @method jsonStringifyCircular
+     * @param {Object} obj
+     * @return {String}
+     * @static
+     */
+    jsonStringifyCircular: function (obj) {
+      return local._jsonStringifyCircularRecurse(obj, []);
+    },
+
+    _jsonStringifyCircularRecurse: function (obj, arr) {
+      var ii, keys, result, val;
+      if (obj) {
+        for (ii = 0; ii < arr.length; ii += 1) {
+          if (obj === arr[ii]) {
+            obj = '[Circular]';
+            break;
+          }
+        }
+      }
+      try {
+        return JSON.stringify(obj);
+      } catch (err) {
+      }
+      //// fallback
+      arr.push(obj);
+      result = '';
+      //// array
+      if (Array.isArray(obj)) {
+        for (ii = 0; ii < obj.length; ii += 1) {
+          val = local._jsonStringifyCircularRecurse(obj[ii], arr);
+          if (val !== undefined) {
+            result += val + ',';
+          }
+        }
+        return '[' + result.slice(0, -1) + ']';
+      }
+      //// object
+      keys = Object.keys(obj).sort();
+      for (ii = 0; ii < keys.length; ii += 1) {
+        val = local._jsonStringifyCircularRecurse(obj[keys[ii]], arr);
+        if (val !== undefined) {
+          result += JSON.stringify(keys[ii]) + ':' + val + ',';
+        }
+      }
+      return '{' + result.slice(0, -1) + '}';
+    },
+
+    jsonStringifySorted: function (obj) {
+      //// recursively JSON.stringify dictionaries in sorted-key order
+      var ii, keys, result, val;
+      result = '';
+      //// array
+      if (Array.isArray(obj)) {
+        for (ii = 0; ii < obj.length; ii += 1) {
+          val = local.jsonStringifySorted(obj[ii]);
+          if (val !== undefined) {
+            result += val + ',';
+          }
+        }
+        return '[' + result.slice(0, -1) + ']';
+      }
+      //// object
+      if (typeof obj === 'object' && obj !== null) {
+        keys = Object.keys(obj).sort();
+        for (ii = 0; ii < keys.length; ii += 1) {
+          val = local.jsonStringifySorted(obj[keys[ii]]);
+          if (val !== undefined) {
+            result += JSON.stringify(keys[ii]) + ':' + val + ',';
+          }
+        }
+        return '{' + result.slice(0, -1) + '}';
+      }
+      return JSON.stringify(obj);
+    },
+
+    objectFirstKey: function (obj) {
+      //// get first iterated key in object
+      var key;
+      for (key in obj) { if (obj.hasOwnProperty(key)) { return key; } }
+    },
+
+    shell: function (command) {
+      //// quick and dirty convenience function for running shell commands
+      require('child_process').spawn('/bin/sh', ['-c', command], {stdio: [0, 1, 2]});
+    },
+
+    streamReadBuffer: function (reader, callback) {
+      //// efficiently pipe readable stream to buffer
+      //// and run callback(error, buffer) on end
+      //// example usage:
+      //// function (request, response) {
+      ////   streadReadBuffer(request, function (error, buffer) {
+      ////     response.write(JSON.parse(buffer).interestingStuff);
+      ////     response.end();
+      ////   }));
+      //// }
+      var chunks = [], ended = false;
+      function onData(chunk) {
+        console.assert(Buffer.isBuffer(chunk));
+        chunks.push(chunk);
+      }
+      function onEnd(err) {
+        if (ended) { return; }
+        ended = true;
+        callback(err, !err && Buffer.concat(chunks));
+        reader.removeListener('close', onEnd);
+        reader.removeListener('data', onData);
+        reader.removeListener('end', onEnd);
+        reader.removeListener('error', onEnd);
+      }
+      reader.on('close', onEnd);
+      reader.on('data', onData);
+      reader.on('end', onEnd);
+      reader.on('error', onEnd);
+    },
+
+    stringFormat: function (template, options) {
+      function getValue(keys) {
+        //// get value from options using keys
+        var fndKey, rgxKey = (/["']([^"'])+|(\w+)/g), val = options;
+        while (true) {
+          fndKey = rgxKey.exec(keys);
+          if (!(fndKey && val)) { break; }
+          val = val[fndKey[0] || fndKey[1]];
+        }
+        return val;
+      }
+      return template.replace((/\{\{.+?\}\}/g), function (code) {
+        //// format {{...}}
+        var args, result;
+        args = code.split('(');
+        result = getValue(args.pop());
+        try {
+          return result === undefined ? code : args.length ? getValue(args.pop())(result) : result;
+        } catch (err) {
+          return code;
+        }
+      });
+    },
+
+    uuid4: function () {
+      //// return uuid4 string of form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
+      var uuid = '', ii;
+      for (ii = 0; ii < 32; ii += 1) {
+        switch (ii) {
+        case 8:
+        case 20:
+          uuid += '-';
+          uuid += (Math.random() * 16 | 0).toString(16);
+          break;
+        case 12:
+          uuid += '-';
+          uuid += '4';
+          break;
+        case 16:
+          uuid += '-';
+          uuid += (Math.random() * 4 | 8).toString(16);
+          break;
+        default:
+          uuid += (Math.random() * 16 | 0).toString(16);
+        }
+      }
+      return uuid;
+    }
+
+  };
+
+  local._init();
+