Пример #1
0
var JokeCLI = module.exports = function (options) {
  if (!(this instanceof JokeCLI))
    return new JokeCLI(options);

  options = options || {};

  this.err = ansi(options.err || process.stderr);
  this.out = ansi(options.out || process.stdout);

  this.levels = {
    fatal: {
      stream: this.err,
      fg: '#ff0000'
    },
    error: {
      stream: this.err,
      fg: '#ff0000'
    },
    warn: {
      stream: this.err,
      fg: '#ffa500'
    },
    info: {
      stream: this.out
    },
    debug: {
      stream: this.out,
      fg: '#0070BB'
    }
  };

  Writable.call(this, { objectMode: true });
}
Пример #2
0
var Wolverine = function Wolverine(level, options) {
  if((typeof level === 'undefined' && typeof options === 'undefined') || typeof level === 'object') {
    this.level = Wolverine.ALL;
    this.options = level || {};
  }
  else {
    this.level = level;
    this.options = options || {};
  }

  if(typeof this.options.output !== 'undefined') {
    var outputStream = this.options.output;
    
    if(typeof outputStream === 'string') {
      outputStream = fs.createWriteStream(this.options.output);
    }

    //If the output must be saved to a file
    this.cursor = ansi(outputStream);
  }
  else {
    //If should print it on the terminal
    this.cursor = ansi(process.stderr);
  }
};
Пример #3
0
var ProgressBar = module.exports = function (options, cursor) {
  if (! options) options = {}
  if (! cursor && options.write) {
    cursor = options
    options = {}
  }
  if (! cursor) {
    cursor = ansi(defaultStream)
  }
  this.cursor = cursor
  this.showing = false
  this.theme = options.theme || (hasUnicode() ? ProgressBar.unicode : ProgressBar.ascii)
  this.template = options.template || [
    {type: "name", separated: true, length: 25},
    {type: "spinner", separated: true},
    {type: "startgroup"},
    {type: "completionbar"},
    {type: "endgroup"}
  ]
  this.updatefreq = options.maxUpdateFrequency == null ? 50 : options.maxUpdateFrequency
  this.lastName = ""
  this.lastCompleted = 0
  this.spun = 0
  this.last = new Date(0)

  var self = this
  this._handleSizeChange = function () {
    if (!self.showing) return
    self.hide()
    self.show()
  }
}
Пример #4
0
  constructor(output = stdout, input = stdin) {
    this.output = output;
    this.input = input;

    this.input.setRawMode(true);
    this.input.setEncoding('utf8');

    this.cursor = ansi(this.output).hide();

    this.input.addListener('data', data => {
      let always = listeners.filter(listener => {
        return listener.key === '';
      });

      always.forEach(listener => listener.fn());

      let key = Object.keys(keys).find((value, i) => {
        return keys[value] === data;
      });

      if ( key === 'exit' ) {
				this.output.write('\u001b[2J\u001b[0;0H');
				process.exit();
			}

      let match = listeners.filter(listener => {
        return listener.key === key || listener.key === data;
      });

      match.forEach(listener => listener.fn());
    })
  }
  Jimp.read(photoPath, (error, image) => {
    if (error) {
      return callback(error)
    }

    const cursor = ansi(process.stdout)
    const resizedImage = image.resize(cols, Jimp.AUTO)
    const height = resizedImage.bitmap.height
    const width = resizedImage.bitmap.width

    for (let y = 0; y < height; y++) {
      for (let x = 0; x < width; x++) {
        let hexColor = `${resizedImage.getPixelColor(x, y).toString(16).substr(0, 6)}`

        if (hexColor.length !== 6) {
          hexColor = '000000'
        }

        cursor
          .hex(`#${hexColor}`)
          .write('██')
          .reset()
      }

      cursor.write('\n')
    }

    callback(null, true)
  })
Пример #6
0
 log.write = function(msg, style) {
   if (!this.cursor)
     return;
   if (this.stream !== this.cursor.stream) {
     this.cursor = ansi(this.stream, {enabled: colorEnabled});
     var options = {};
     if (gaugeTheme != null)
       options.theme = gaugeTheme;
     if (gaugeTemplate != null)
       options.template = gaugeTemplate;
     this.gauge = new Gauge(options, this.cursor);
   }
   style = style || {};
   if (style.fg)
     this.cursor.fg[style.fg]();
   if (style.bg)
     this.cursor.bg[style.bg]();
   if (style.bold)
     this.cursor.bold();
   if (style.underline)
     this.cursor.underline();
   if (style.inverse)
     this.cursor.inverse();
   if (style.beep)
     this.cursor.beep();
   this.cursor.write(msg).reset();
 };
Пример #7
0
/**
 * @class CordovaLogger
 *
 * Implements logging facility that anybody could use. Should not be
 *   instantiated directly, `CordovaLogger.get()` method should be used instead
 *   to acquire logger instance
 */
function CordovaLogger () {
    this.levels = {};
    this.colors = {};
    this.stdout = process.stdout;
    this.stderr = process.stderr;

    this.stdoutCursor = ansi(this.stdout);
    this.stderrCursor = ansi(this.stderr);

    this.addLevel('verbose', 1000, 'grey');
    this.addLevel('normal' , 2000);
    this.addLevel('warn'   , 2000, 'yellow');
    this.addLevel('info'   , 3000, 'blue');
    this.addLevel('error'  , 5000, 'red');
    this.addLevel('results' , 10000);

    this.setLevel('normal');
}
Пример #8
0
/**
 * Explicit Throttling Stream
 * By default, pipe to stderr stream.
 * Keep buffing unless `flush` or it's alias `out`
 */
function Weir(options) {
  Stream.call(this);
  this._buf = [];
  this.writable = true;
  this.readable = true;

  // keep connect with stderr
  this._paused = true;
  this.cursor = ansi(this, { enabled: true });
  this._options = _.extend({}, defaults, options);
  this.invalidate();
  this.pipe(this._options.stream, { end: false });
}
Пример #9
0
export function printLogo() {
  let cursor = ansi(process.stdout);

  cursor
    .bold()
    .bg.black()
    .green().write('>')
    .white().write('boot')
    .resetBold()
    .bg.green()
    .black().write('env')
    .reset().write('\n');
}
Пример #10
0
// COLORFUL PRINTING IS FNU
function printInfo(s, color, prefix) {
  var ansi = require('ansi')
  var cursor = ansi(process.stdout);
  
  if(!color)
    color = "#00FF66";
  
  if(!prefix)
    prefix = "TAFL";
  
  cursor.hex(color)
  console.log("-- "+prefix+" -- "+s)
  cursor.reset()
}
Пример #11
0
log.write = function (msg, style) {
    if (!this.cursor) return
    if (this.stream !== this.cursor.stream) {
        this.cursor = ansi(this.stream, { enabled:colorEnabled })
    }

    style = style || {}
    if (style.fg) this.cursor.fg[style.fg]()
    if (style.bg) this.cursor.bg[style.bg]()
    if (style.bold) this.cursor.bold()
    if (style.underline) this.cursor.underline()
    if (style.inverse) this.cursor.inverse()
    if (style.beep) this.cursor.beep()
    this.cursor.write(msg).reset()
}
Пример #12
0
 write: function (str) {
     var e = document.createElement("div");
     e.innerHTML = ansi(str.replace(/</g, "&lt;").replace(/>/g, "&gt;"));
     
     var scroll = false;
     if (this.pre.parentNode.scrollTop === 0 || this.pre.parentNode.scrollTop === this.pre.parentNode.scrollHeight || this.pre.parentNode.scrollHeight - this.pre.parentNode.scrollTop === this.pre.parentNode.clientHeight) {
         scroll = true;   
     }
     
     this.pre.appendChild(e);
     
     if (scroll) {
         this.pre.parentNode.scrollTop = this.pre.parentNode.scrollHeight;
     }
 },
Пример #13
0
	function NetmonUiApp() {
		this.ui = 'tty';
		this.port = 8080;
		this.host = 'localhost';
		this.cursor = ansi(process.stdout);
		this.program = require('commander');
		this.recoMsgInterval = -1;

		this._sigintCount = 0;

		this.getProcessArgs();

		this.initProcessSignals();

		this.initSocketIoClient();
	}
Пример #14
0
export function printBanner() {
  console.log('');

  let bootenv = ' '.repeat(80) + '\n' +
    figlet.textSync('>bootenv', { font: 'DOS Rebel' }).replace(/\n *$/, '');
  let cursor = ansi(process.stdout);
  let regExp = /(.{10})(.*)(.{32})\n/g;

  let match;
  while (match = regExp.exec(bootenv)) { // jshint ignore:line
    cursor
      .bg.black()
      .green().write(' ' + match[1])
      .white().write(match[2] + ' ')
      .bg.green()
      .black().write(match[3] + ' ')
      .reset().write('\n');
  }

  console.log(figlet.textSync(' '.repeat(8) + 'Rest API', { font: 'JS Stick Letters' }));

  console.log('');
}
Пример #15
0
var server = telnet.createServer(function (client) {
    var prompt = ansi(client, {enabled: true});

    Engine.addClient(client);

  client.on('window size', function (e) {
    if (e.command === 'sb') {
      // a real "resize" event; 'readline' listens for this
      client.columns = e.columns;
      client.rows = e.rows;
      client.emit('resize');
    }
  });

  client.on('suppress go ahead',  console.log);
  client.on('echo', console.log);
  client.on('window size', console.log);
  client.on('x display location', console.log);
  client.on('terminal speed', console.log);
  client.on('environment variables', console.log);
  client.on('transmit binary', console.log);
  client.on('status', console.log);
  client.on('linemode', console.log);
  client.on('authentication', console.log);

  // 'readline' will call `setRawMode` when it is a function
  client.setRawMode = setRawMode;

  // make unicode characters work properly
  client['do'].transmit_binary();

  // emit 'window size' events
  client['do'].window_size();

  client.on('data', function(data) {
    var input = data.toString().trim();
    var args = input.split(' ');
    if(input !== '') {
        Engine.emit(args.shift(), args, prompt);
    }
  });

  client.on('foo', function() { client.write('socket bar!\r\n'); });

  /*

  // create the REPL
    var r = repl.start({
        input: client,
        output: client,
        prompt: 'telnet repl> ',
        terminal: true,
        useGlobal: false
    }).on('exit', function () {
        client.end();
    });

  r.context.r = r;
  r.context.client = client;
  r.context.socket = client;*/

});
Пример #16
0
 return function(stdin, stdout) {
   if(stdin == null) stdin = process.stdin;
   if(stdout == null) stdout = process.stdout;
   
   var cursor,
       em = new EventEmitter(),
       nl = '\n',
       cr = '\r',
       outputBuffer = [''],
       inputBuffer = '',
       inputHistory = [],
       inputHistoryPosition = -1,
       maxX = 32,
       maxY = 32,
       fitToScreen = true;
   
   if(fitToScreen) {
     stdout.on('resize', function() {
       maxX = stdout.columns - 1;
       maxY = stdout.rows - 2;
     });
     maxX = stdout.columns - 1;
     maxY = stdout.rows - 2;
   }
   
   cursor = ansi(stdout);
   
   // setup
   
   em.start = function() {
     stdin.resume();
     stdin.setRawMode(true);
     stdin.on('data', onDataInput);
     setTimeout(function() {
       em.emit('start');
     });
     return em;
   };
   
   em.stop = function() {
     stdin.removeListener('data', onDataInput);
     stdin.setRawMode(false);
     stdin.pause();
     em.emit('stop');
     return em;
   };
   
   var KEY_ETX = 3,
       KEY_BS = 8,
       KEY_ESC = 27,
       KEY_CR = 13,
       KEY_US = 31,
       KEY_OPENING_SQUARE_BRACKET = 91,
       KEY_DEL = 127;
   
   function onDataInput(b) {
     switch(b[0]) {
       case KEY_ETX: // [Ctrl+C]
         em.stop();
         stdout.write(nl + 'Hit [Ctrl+C] again to quit.' + nl);
         break;
       case KEY_CR:
         pushToHistory(inputBuffer);
         em.emit('line', inputBuffer);
         inputBuffer = '';
         displayRefresh();
         break;
       case KEY_BS:
       case KEY_DEL:
         inputBuffer = inputBuffer.slice(0, -1);
         displayRefresh();
         break;
       case KEY_ESC:
         onEscapeSeqInput(b);
         break;
       default:
         if(KEY_US < b[0] && b[0] < 127) { // Printable ascii chars
           inputBuffer += b.toString();
         } else {
           em.writeln(b.length + ': ' + b[0] + ' ' + b[1] + ' ' + b[2]);
         }
         displayRefresh();
         break;
     }
   }
   
   var ESC_SEQ_UP = 65,
       ESC_SEQ_DOWN = 66,
       ESC_SEQ_RIGHT = 67,
       ESC_SEQ_LEFT = 68;
   
   function onEscapeSeqInput(b) {
     if(
       b[0] === KEY_ESC &&
       b[1] === KEY_OPENING_SQUARE_BRACKET
     ) {
       switch(b[2]) {
         case ESC_SEQ_UP:
           inputBuffer = getPreviousFromHistory();
           break;
         case ESC_SEQ_DOWN:
           inputBuffer = getNextFromHistory();
           break;
         case ESC_SEQ_RIGHT:
           em.writeln('ESC_SEQ_RIGHT');
           em.position(function(err, pos) {
             em.writeln(pos[0]);
           });
           break;
         case ESC_SEQ_LEFT:
         default:
           debugPrint(b);
           break;
       }
       displayRefresh();
     } else {
       debugPrint(b);
     }
   }
   
   // functions
   
   em.getWindowSize = function() {
     return stdout.getWindowSize();
   };
   
   em.clear = function() {
     cursor.eraseData(2);
     return em;
   };
   
   em.write = function(data) {
     writeToOuptuBuffer(data);
     displayRefresh();
     return em;
   };
   
   em.writeln = function(data) {
     if(data == null) data = '';
     writeToOuptuBuffer(data.toString() + nl);
     displayRefresh();
     return em;
   };
   
   em.position = function(cb) {
     stdin.once('data', function(b) {
       var match = /\[(\d+)\;(\d+)R$/.exec(b.toString());
       if(match) {
         var xy = match.slice(1, 3).reverse().map(Number);
         cb(null, xy);
       } else {
         cb(new Error('Could not retrieve cursor position.'));
       }
     });
     cursor.queryPosition();
   };
   
   em.goto = function(x, y) {
     cursor.goto(x, y);
     return em;
   };
   
   em.setMaxXY = function(x, y) {
     maxX = x;
     maxY = y;
     return em;
   };
  
   // ---
   
   function writeToOuptuBuffer(data) {
     data = data.toString().split(nl);
     data[0] = outputBuffer[outputBuffer.length-1] + data[0];
     data = wrapLines(data);
     outputBuffer[outputBuffer.length-1] = data.shift();
     outputBuffer = outputBuffer.concat(data);
   }
   
   function displayRefresh() {
     trimOutputBuffer();
     cursor
       .eraseData(1)
       .goto(1, 1)
       .write(outputBuffer.join(nl))
       .write(nl + prompt() + inputBuffer);
   }
   
   function wrapLines(lines) {
     var pos = 0, newLines = [];
     lines.forEach(function(line) {
       if(line.length <= maxX) {
         newLines.push(line);
       } else {
         pos = 0;
         while(pos < line.length) {
           newLines.push(line.slice(pos, pos + maxX));
           pos += maxX + 1;
         }
       }
     });
     return newLines;
   }
   
   function trimOutputBuffer() {
     if(outputBuffer.length > maxY) {
       outputBuffer = outputBuffer.slice(outputBuffer.length - maxY);
     }
   }
   
   // Prompt
   
   var promptPrefix = '$ ';
   
   function prompt(prefix) {
     if(prefix != null) {
       promptPrefix = prefix;
     }
     return promptPrefix;
   }
   
   function debugPrint(chunk) {
     var c = Array.prototype.slice.call(chunk, 0);
     em.writeln(chunk.slice(1).toString());
     em.writeln(c.join(', '));
   }
   
   // History
   
   function pushToHistory(line) {
     if(line.length > 0) {
       if(inputHistory.indexOf(line) !== -1) {
         inputHistory.splice(inputHistory.indexOf(line), 1);
       }
       inputHistory.push(line);
       inputHistoryPosition = inputHistory.length;
     }
   }
   
   function getPreviousFromHistory() {
     if(inputHistory[--inputHistoryPosition] == null) ++inputHistoryPosition;
     return getFromHistory(inputHistoryPosition);
   }
   
   function getNextFromHistory() {
     if(inputHistory[++inputHistoryPosition] == null) {
       inputHistoryPosition = inputHistory.length;
       return '';
     }
     return getFromHistory(inputHistoryPosition);
   }
   
   function getFromHistory(index) {
     if(index == null) index = inputHistoryPosition;
     if(inputHistory[index] == null) return '';
     return inputHistory[index];
   }
   
   // Exports
   
   em.prompt = prompt;
   
   return em.start();
 };
Пример #17
0
(function($module, $process) {

    "use strict";

    /**
     * Since Restler doesn't allow rejectUnauthorized.
     * @reference https://github.com/danwrong/restler/pull/132
     */
    if ($process) {
        $process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
    }

    // Dependencies, baby!
    var fs          = require('fs'),
        yaml        = require('js-yaml'),
        util        = require('util'),
        request     = require('request'),
        q           = require('q'),
        mime        = require('mime'),
        restler     = require('restler'),
        ansi        = require('ansi'),
        cursor      = ansi(process.stdout);

    /**
     * @module CloudConvert
     * @constructor
     */
    var CloudConvert = function CloudConvert(configFile) {
        this._options.config = configFile;
    };

    /**
     * @property prototype
     * @type {Object}
     */
    CloudConvert.prototype = {

        /**
         * @property _urlProcess
         * @type {String}
         * @private
         */
        _urlProcess: 'https://api.cloudconvert.org/process?inputformat=%s&outputformat=%s&apikey=%s',

        /**
         * @property _urlActions
         * @type {Object}
         * @private
         */
        _urlActions: { delete: 'delete', cancel: 'cancel' },

        /**
         * @property _options
         * @type {Object}
         * Containers data that has been specified by the user.
         * @private
         */
            _options: { file: null, from: null, into: null, config: null },

        /**
         * @property _task
         * @type {Object}
         * Contains data that has been retrieved from the CloudConvert servers.
         * @private
         */
        _task: { id: null, url: null },

        /**
         * @property _apiKey
         * @type {String}
         * @private
         */
        _apiKey: '',

        /**
         * @property _defaultInterval
         * @type {Number}
         * @private
         */
        _defaultInterval: 2500,

        /**
         * @property _errorCodes
         * @type {Object}
         * @private
         */
        _errorCodes: {

            /**
             * @property invalidConfig
             * Thrown when the YAML configuration file cannot be loaded.
             * @type {Number}
             * @default 1
             */
            invalidConfig: 1,

            /**
             * @property configKey
             * Thrown when the "apiKey" key cannot be found in the YAML config.
             * @type {Number}
             * @default 2
             */
            configKey: 2,

            /**
             * @property invalidJobId
             * Thrown when CloudConvert does not send us back the response with the job ID.
             * @type {Number}
             * @default 3
             */
            invalidJobId: 3,

            /**
             * @property invalidFile
             * Thrown when we're unable to locate the file wishing to be converted.
             * @type {Number}
             * @default 4
             */
            invalidFile: 4
            
        },

        /**
         * @property _callbacks
         * @type {Object}
         * @private
         */
        _callbacks: {

            /**
             * @on error
             * Invoked once when an error occurs.
             */
            error: {
                method: function(data) {
                    cursor.hex('#553c45').bg.hex('#e7a3bd')
                        .write(' CloudConvert: ').reset().write(' ' + data.message + "\n");
                }
            },

            /**
             * @on uploading
             * Invoked once when the file upload process has begun.
             */
            uploading: {
                method: function() {
                    cursor.hex('#324645').bg.hex('#9fd3d0')
                        .write(' CloudConvert: ').reset().write(" Uploading File... \n");
                }
            },

            /**
             * @on uploaded
             * Invoked once when the file has been successfully uploaded.
             */
            uploaded: {
                method: function() {
                    cursor.hex('#1f251b').bg.hex('#b4ce9e')
                        .write(' CloudConvert: ').reset().write(" File Uploaded... \n");
                }
            },

            /**
             * @on converting
             * Invoked many times when the file is being converted by CloudConvert.
             */
            converting: {
                interval: 2500,
                method  : function() {
                    cursor.hex('#324645').bg.hex('#9fd3d0')
                        .write(' CloudConvert: ').reset().write(" Converting File... \n");
                }
            },

            /**
             * @on finished
             * Invoked once when the conversion has been successfully completed.
             */
            finished: {
                method: function() {
                    cursor.hex('#1f251b').bg.hex('#b4ce9e')
                        .write(' CloudConvert: ').reset().write(" All Done! \n");
                }
            }

        },

        /**
         * @method when
         * @param observerName {String}
         * @param method {Function}
         * @param interval {Number}
         * @return {void}
         */
        when: function when(observerName, method, interval) {

            this._callbacks[observerName] = {
                method      : method,
                interval    : interval || this._defaultInterval
            };

        },

        /**
         * @method convert
         * @param file {String}
         * @return {CloudConvert}
         */
        convert: function convert(file) {
            this._options.file = file;
            return this;
        },

        /**
         * @method from
         * @param format {String}
         * @return {CloudConvert}
         */
        from: function from(format) {
            this._options.from = format;
            return this;
        },

        /**
         * @method into
         * @param format {String}
         * @return {CloudConvert}
         */
        into: function into(format) {
            this._options.into = format;
            return this;
        },

        /**
         * @method process
         * Responsible for initiating the whole conversion process.
         * @return {void}
         */
        process: function process() {

            // First we need to read the "config.yaml" file to access the API information.
            fs.readFile(this._options.config, 'utf-8', function parseYamlConfig(error, data) {

                try {

                    // Attempt to load and parse the YAML config file.
                    var config = yaml.load(data);

                    // Determine if the "apiKey" key is in the configuration.
                    if (!('apiKey' in config)) {

                        this._callbacks.error.method({
                            code    : this._errorCodes.configKey,
                            message : 'Cannot find "apiKey" in configuration!'
                        });

                        return false;

                    }

                    // Otherwise we can load the API key, and continue processing.
                    this._apiKey = config.apiKey;
                    this._convert.apply(this);

                } catch (e) {

                    this._callbacks.error.method({
                        code    : this._errorCodes.invalidConfig,
                        message : 'Unable to parse YAML configuration!'
                    });

                    return false;

                }

            }.bind(this));

        },

        /**
         * @method _convert
         * Responsible for converting the uploaded file into the desired file format.
         * @return {void}
         * @private
         */
        _convert: function _convert() {

            // Prepare the URL to notify CloudConvert of the impending conversion.
            var url = util.format(this._urlProcess, this._options.from, this._options.into, this._apiKey);

            // Begin the process using Q's promises!
            this._getContent(url)

                // Initiate the call to the CloudConvert servers to notify them of the impending conversion.
                .then(this._prepareConversion.bind(this))

                // Send the file to the CloudConvert servers so they can begin the process.
                .then(this._sendFile.bind(this))

                // Apply the callbacks to notify Node of the status.
                .then(this._applyCallbacks.bind(this))

                // Fallback if any errors occur in the process.
                .fail(function(error) {

                    this._callbacks.error.method(error);

                }.bind(this));

        },

        /**
         * @method _prepareConversion
         * @param content {Object}
         * Responsible for making the initial call to the CloudConvert servers to retrieve the job ID.
         * @return {Q.promise}
         * @private
         */
        _prepareConversion: function _prepareConversion(content) {

            var deferred = q.defer();

            if ('id' in content) {

                // We've found the "id" in the JSON content, so we can resolve our promise
                // and jump to the next stage!
                this._task.id  = content.id;
                this._task.url = util.format('https:%s', content.url);

                deferred.resolve();

            }

            // Boohoo! We weren't able to find the "id" property in the returned content.
            deferred.reject({
                code    : this._errorCodes.invalidJobId,
                message : 'Cannot determine CloudConvert job ID!'
            });

            return deferred.promise;

        },

        /**
         * @method _sendFile
         * Responsible for sending the file to the CloudConvert server for the them to convert the
         * files into the desired format.
         * @return {Q.promise}
         * @private
         */
        _sendFile: function _sendFile() {

            var file            = this._options.file,
                deferred        = q.defer();

            fs.stat(file, function(error, stats) {

                if (error) {

                    // Determine if an error was thrown.
                    this._callbacks.error.method({
                        code    : this._errorCodes.invalidFile,
                        message : 'Unable to locate the file to convert!'
                    });

                    return;

                }

                // Gather the necessary information about the file.
                var mimeType    = mime.lookup(file),
                    size        = stats.size;

                // Invoke the callback method for uploading.
                this._callbacks.uploading.method();

                // Construct the options for the conversion.
                var options = {
                    rejectUnauthorized  : false,
                    multipart           : true,
                    data: {
                        input           : 'upload',
                        file            : restler.file(file, null, size, null, mimeType),
                        outputformat    : this._options.into
                    }
                };

                // Use Restler to submit the image along with the details to the CloudConvert server.
                restler.post(this._task.url, options).on('complete', function(data) {
                    deferred.resolve(data);
                }.bind(this));

            }.bind(this));

            return deferred.promise;

        },

        /**
         * @method _applyCallbacks
         * Responsible for applying the user configured callbacks so that the end-user knows what's going
         * on with their conversion.
         * @param data {Object}
         * @return {void}
         * @private
         */
        _applyCallbacks: function _applyCallbacks(data) {

            // Invoke the callback method for uploaded.
            this._callbacks.uploaded.method(data);

            // Periodically invoke the callback with the status.
            var interval = setInterval(function() {

                this._getContent(this._task.url).then(function(data) {

                    // Check if we're all done.
                    if (data.step === 'finished') {

                        // If we are then we'll invoke the finished callback, and clear
                        // the interval so no more callbacks are invoked.
                        clearInterval(interval);
                        this._callbacks.finished.method(data);
                        return;

                    }

                    // Otherwise we'll invoke the converting callback.
                    this._callbacks.converting.method(data);

                }.bind(this));

            }.bind(this), this._callbacks.converting.interval);

        },

        /**
         * @method _getContent
         * @param url {String}
         * @return {Q.promise}
         * @private
         */
        _getContent: function _getContent(url) {

            var deferred    = q.defer(),
                options     = {
                    url         : url,
                    strictSSL   : false
                };

            request(options, function request(error, response, body) {

                if (error && response.statusCode !== 200) {

                    // Determine if we have an error, in which case we'll reject the promise.
                    return deferred.reject(error);

                }

                // Otherwise we can resolve our promise.
                return deferred.resolve(JSON.parse(body));

            });

            return deferred.promise;

        }

    };

    // CommonJS, my dear!
    $module.exports = CloudConvert;

})(module, typeof process !== 'undefined' ? process : null);
Пример #18
0
 write: function (str) {
     var e = document.createElement("div");
     e.innerHTML = ansi(str.replace(/</g, "&lt;").replace(/>/g, "&gt;"));
     this.pre.appendChild(e);
 },
Пример #19
0
function worker (botkit, config) {
  let bot = {
    botkit: botkit,
    config: config || {},
    utterances: botkit.utterances,
    identity: { // default identity values
      id: 'shellbot',
      name: 'ShellBot'
    }
  }

  botkit.startTicking()

  let cl = cline()
  cl.on('close', () => { process.exit() })

  let cursor = ansi(process.stdout)

  let channel = '##'
  function setChannel (newChannel) {
    channel = newChannel
    cl.interact(chalk.gray(`${channel}> `))
  }

  cl.command('/dm', 'switch to DM context', () => { setChannel('DM') })
  cl.command('/ch', 'switch to channel context', () => { setChannel('##') })
  cl.command('*', (input) => {
    botkit.debug(`GOT '${input}'`)
    botkit.receiveMessage(bot, {
      type: 'message',
      channel: channel,
      user: '******',
      text: input,
      ts: new Date().getTime()
    })
    return false
  })
  setTimeout(() => { setChannel('##') }, 10)

  /**
  * Convenience method for creating a DM convo.
  */
  bot.startPrivateConversation = function (message, cb) {
    botkit.startTask(this, message, function (task, convo) {
      bot._startDM(task, message.user, function (err, dm) {
        convo.stop()
        cb(err, dm)
      })
    })
  }

  bot.startConversation = function (message, cb) {
    botkit.startConversation(this, message, cb)
  }

  /**
  * Convenience method for creating a DM convo.
  */
  bot._startDM = function (task, userId, cb) {
    bot.api.im.open({
      user: userId
    }, function (err, channel) {
      if (err) return cb(err)

      cb(null, task.startConversation({
        channel: channel.channel.id,
        user: userId
      }))
    })
  }

  bot.send = function (message, cb) {
    botkit.debug('SAY', message)

    /**
    * Construct a valid slack message.
    */
    var slackMessage = {
      type: message.type || 'message',
      channel: message.channel,
      text: message.text || null,
      username: message.username || null,
      parse: message.parse || null,
      link_names: message.link_names || null,
      attachments: message.attachments
        ? JSON.stringify(message.attachments)
        : null,
      unfurl_links: typeof message.unfurl_links !== 'undefined' ? message.unfurl_links : null,
      unfurl_media: typeof message.unfurl_media !== 'undefined' ? message.unfurl_media : null,
      icon_url: message.icon_url || null,
      icon_emoji: message.icon_emoji || null
    }
    bot.msgcount++

    if (message.icon_url || message.icon_emoji || message.username) {
      slackMessage.as_user = false
    } else {
      slackMessage.as_user = message.as_user || true
    }

    /**
    * These options are not supported by the RTM
    * so if they are specified, we use the web API to send messages.
    */
    cursor.horizontalAbsolute(0).eraseLine()
    if (message.attachments || message.icon_emoji || message.username || message.icon_url) {
      console.log(JSON.stringify(message, null, 2))
    } else {
      console.log(chalk.blue(message.text))
    }
    cl.prompt(chalk.grey(`${channel}> `))
  }

  bot.replyPublic = function (src, resp, cb) {
    if (!bot.res) {
      cb && cb('No web response object found')
    } else {
      var msg = {}

      if (typeof resp === 'string') {
        msg.text = resp
      } else {
        msg = resp
      }

      msg.channel = src.channel

      msg.response_type = 'in_channel'
      bot.res.json(msg)
      cb && cb()
    }
  }

  bot.replyPublicDelayed = function (src, resp, cb) {
    if (!src.response_url) {
      cb && cb('No response_url found')
    } else {
      var msg = {}

      if (typeof resp === 'string') {
        msg.text = resp
      } else {
        msg = resp
      }

      msg.channel = src.channel

      msg.response_type = 'in_channel'
      var requestOptions = {
        uri: src.response_url,
        method: 'POST',
        json: msg
      }
      request(requestOptions, function (err, resp, body) {
        /**
        * Do something?
        */
        if (err) {
          botkit.log.error('Error sending slash command response:', err)
          cb && cb(err)
        } else {
          cb && cb()
        }
      })
    }
  }

  bot.replyPrivate = function (src, resp, cb) {
    if (!bot.res) {
      cb && cb('No web response object found')
    } else {
      var msg = {}

      if (typeof resp === 'string') {
        msg.text = resp
      } else {
        msg = resp
      }

      msg.channel = src.channel

      msg.response_type = 'ephemeral'
      bot.res.json(msg)

      cb && cb()
    }
  }

  bot.replyPrivateDelayed = function (src, resp, cb) {
    if (!src.response_url) {
      cb && cb('No response_url found')
    } else {
      var msg = {}

      if (typeof resp === 'string') {
        msg.text = resp
      } else {
        msg = resp
      }

      msg.channel = src.channel

      msg.response_type = 'ephemeral'

      var requestOptions = {
        uri: src.response_url,
        method: 'POST',
        json: msg
      }
      request(requestOptions, function (err, resp, body) {
        /**
        * Do something?
        */
        if (err) {
          botkit.log.error('Error sending slash command response:', err)
          cb && cb(err)
        } else {
          cb && cb()
        }
      })
    }
  }

  bot.reply = function (src, resp, cb) {
    var msg = {}

    if (typeof resp === 'string') {
      msg.text = resp
    } else {
      msg = resp
    }

    msg.channel = src.channel

    bot.say(msg, cb)
  }

  /**
  * sends a typing message to the source channel
  *
  * @param {Object} src message source
  */
  bot.startTyping = function (src) {
    bot.reply(src, {
      type: 'typing'
    })
  }

  /**
  * replies with message after typing delay
  *
  * @param {Object} src message source
  * @param {(string|Object)} resp string or object
  * @param {function} cb optional request callback
  */
  bot.replyWithTyping = function (src, resp, cb) {
    var text

    if (typeof resp === 'string') {
      text = resp
    } else {
      text = resp.text
    }

    var typingLength = 1200 / 60 * text.length
    typingLength = typingLength > 2000 ? 2000 : typingLength

    bot.startTyping(src)

    setTimeout(function () {
      bot.reply(src, resp, cb)
    }, typingLength)
  }

  /**
  * This handles the particulars of finding an existing conversation or
  * topic to fit the message into...
  */
  bot.findConversation = function (message, cb) {
    botkit.debug('CUSTOM FIND CONVO', message.user, message.channel)
    if (message.type === 'message' || message.type === 'slash_command' ||
    message.type === 'outgoing_webhook') {
      for (var t = 0; t < botkit.tasks.length; t++) {
        for (var c = 0; c < botkit.tasks[t].convos.length; c++) {
          if (
            botkit.tasks[t].convos[c].isActive() &&
            botkit.tasks[t].convos[c].source_message.user === message.user &&
            botkit.tasks[t].convos[c].source_message.channel === message.channel
          ) {
            botkit.debug('FOUND EXISTING CONVO!')

            // modify message text to prune off the bot's name (@bot hey -> hey)
            // and trim whitespace that is sometimes added
            // this would otherwise happen in the handleSlackEvents function
            // which does not get called for messages attached to conversations.

            if (message.text) {
              message.text = message.text.trim()
            }

            var directMention = new RegExp(`\<\@${bot.identity.id}\>`, 'i')

            message.text = message.text.replace(directMention, '')
              .replace(/^\s+/, '').replace(/^:\s+/, '').replace(/^\s+/, '')

            cb(botkit.tasks[t].convos[c])
            return
          }
        }
      }
    }

    cb()
  }

  if (bot.config.incoming_webhook) {
    bot.configureIncomingWebhook(config.incoming_webhook)
  }

  if (bot.config.bot) {
    bot.configureRTM(config.bot)
  }

  return bot
}
Пример #20
0
    return tempfile.path;
  });

}
else {
  file_paths = program.tests.map(function(fn) {
    return path.resolve(process.cwd(), fn);
  });
}

var use_ansi = false;
if (program.color) use_ansi = true;
else if (program.disableColor) use_ansi = false;
else if (process.stdout.isTTY) use_ansi = true;

var cursor = ansi(process.stdout, { enabled: use_ansi });

if (program.outputHtml) {
  var fs = require('fs');
  file_paths.forEach(function(path, path_ind) {
    fs.readFile(path, function(err, data) {
      if (err) {
        console.warn(error.stack);
        return;
      }
      
      cursor
        .bold()
        .write(program.tests[path_ind])
        .reset()
        .write("\n")
Пример #21
0
}

//list directory, skipping hidden files
function listDir(dir) {
    return fs.readdirSync(dir)
        .filter(function(file) {
            return file.indexOf('.')!=0;
        });
}

var rl = readline.createInterface({
   input: process.stdin,
   output: process.stdout,
   completer:completer,
});
var cursor = ansi(rl.output);

var qq = clc.red('"');

function Pager(inp) {
    var self = this;
    this.count = 0;
    this.active = true;
    inp
        .pipe(es.split())
        .pipe(es.through(function(data){
            self.filter = this;
            self.count++;
            if(self.count %10 == 0) {
                self.filter.pause();
                console.log("==== more");
Пример #22
0
'use strict'
var Progress = require('are-we-there-yet')
var Gauge = require('gauge')
var EE = require('events').EventEmitter
var log = exports = module.exports = new EE
var util = require('util')

var ansi = require('ansi')
log.cursor = ansi(process.stderr)
log.stream = process.stderr

// by default, let ansi decide based on tty-ness.
var colorEnabled = undefined
log.enableColor = function () {
  colorEnabled = true
  this.cursor.enabled = true
}
log.disableColor = function () {
  colorEnabled = false
  this.cursor.enabled = false
}

// default level
log.level = 'info'

log.gauge = new Gauge(log.cursor)
log.tracker = new Progress.TrackerGroup()

// no progress bars unless asked
log.progressEnabled = false
Пример #23
0
(function(process) {
  'use strict';
  var Progress = require('are-we-there-yet');
  var Gauge = require('gauge');
  var EE = require('events').EventEmitter;
  var log = exports = module.exports = new EE;
  var util = require('util');
  var ansi = require('ansi');
  log.cursor = ansi(process.stderr);
  log.stream = process.stderr;
  var colorEnabled = undefined;
  log.enableColor = function() {
    colorEnabled = true;
    this.cursor.enabled = true;
  };
  log.disableColor = function() {
    colorEnabled = false;
    this.cursor.enabled = false;
  };
  log.level = 'info';
  log.gauge = new Gauge(log.cursor);
  log.tracker = new Progress.TrackerGroup();
  log.progressEnabled = false;
  var gaugeTheme = undefined;
  log.enableUnicode = function() {
    gaugeTheme = Gauge.unicode;
    log.gauge.setTheme(gaugeTheme);
  };
  log.disableUnicode = function() {
    gaugeTheme = Gauge.ascii;
    log.gauge.setTheme(gaugeTheme);
  };
  var gaugeTemplate = undefined;
  log.setGaugeTemplate = function(template) {
    gaugeTemplate = template;
    log.gauge.setTemplate(gaugeTemplate);
  };
  log.enableProgress = function() {
    if (this.progressEnabled)
      return;
    this.progressEnabled = true;
    if (this._pause)
      return;
    this.tracker.on('change', this.showProgress);
    this.gauge.enable();
    this.showProgress();
  };
  log.disableProgress = function() {
    if (!this.progressEnabled)
      return;
    this.clearProgress();
    this.progressEnabled = false;
    this.tracker.removeListener('change', this.showProgress);
    this.gauge.disable();
  };
  var trackerConstructors = ['newGroup', 'newItem', 'newStream'];
  var mixinLog = function(tracker) {
    Object.keys(log).forEach(function(P) {
      if (P[0] === '_')
        return;
      if (trackerConstructors.filter(function(C) {
        return C === P;
      }).length)
        return;
      if (tracker[P])
        return;
      if (typeof log[P] !== 'function')
        return;
      var func = log[P];
      tracker[P] = function() {
        return func.apply(log, arguments);
      };
    });
    if (tracker instanceof Progress.TrackerGroup) {
      trackerConstructors.forEach(function(C) {
        var func = tracker[C];
        tracker[C] = function() {
          return mixinLog(func.apply(tracker, arguments));
        };
      });
    }
    return tracker;
  };
  trackerConstructors.forEach(function(C) {
    log[C] = function() {
      return mixinLog(this.tracker[C].apply(this.tracker, arguments));
    };
  });
  log.clearProgress = function() {
    if (!this.progressEnabled)
      return;
    this.gauge.hide();
  };
  log.showProgress = function(name) {
    if (!this.progressEnabled)
      return;
    this.gauge.show(name, this.tracker.completed());
  }.bind(log);
  log.pause = function() {
    this._paused = true;
  };
  log.resume = function() {
    if (!this._paused)
      return;
    this._paused = false;
    var b = this._buffer;
    this._buffer = [];
    b.forEach(function(m) {
      this.emitLog(m);
    }, this);
    if (this.progressEnabled)
      this.enableProgress();
  };
  log._buffer = [];
  var id = 0;
  log.record = [];
  log.maxRecordSize = 10000;
  log.log = function(lvl, prefix, message) {
    var l = this.levels[lvl];
    if (l === undefined) {
      return this.emit('error', new Error(util.format('Undefined log level: %j', lvl)));
    }
    var a = new Array(arguments.length - 2);
    var stack = null;
    for (var i = 2; i < arguments.length; i++) {
      var arg = a[i - 2] = arguments[i];
      if (typeof arg === 'object' && arg && (arg instanceof Error) && arg.stack) {
        arg.stack = stack = arg.stack + '';
      }
    }
    if (stack)
      a.unshift(stack + '\n');
    message = util.format.apply(util, a);
    var m = {
      id: id++,
      level: lvl,
      prefix: String(prefix || ''),
      message: message,
      messageRaw: a
    };
    this.emit('log', m);
    this.emit('log.' + lvl, m);
    if (m.prefix)
      this.emit(m.prefix, m);
    this.record.push(m);
    var mrs = this.maxRecordSize;
    var n = this.record.length - mrs;
    if (n > mrs / 10) {
      var newSize = Math.floor(mrs * 0.9);
      this.record = this.record.slice(-1 * newSize);
    }
    this.emitLog(m);
  }.bind(log);
  log.emitLog = function(m) {
    if (this._paused) {
      this._buffer.push(m);
      return;
    }
    if (this.progressEnabled)
      this.gauge.pulse(m.prefix);
    var l = this.levels[m.level];
    if (l === undefined)
      return;
    if (l < this.levels[this.level])
      return;
    if (l > 0 && !isFinite(l))
      return;
    var style = log.style[m.level];
    var disp = log.disp[m.level] || m.level;
    this.clearProgress();
    m.message.split(/\r?\n/).forEach(function(line) {
      if (this.heading) {
        this.write(this.heading, this.headingStyle);
        this.write(' ');
      }
      this.write(disp, log.style[m.level]);
      var p = m.prefix || '';
      if (p)
        this.write(' ');
      this.write(p, this.prefixStyle);
      this.write(' ' + line + '\n');
    }, this);
    this.showProgress();
  };
  log.write = function(msg, style) {
    if (!this.cursor)
      return;
    if (this.stream !== this.cursor.stream) {
      this.cursor = ansi(this.stream, {enabled: colorEnabled});
      var options = {};
      if (gaugeTheme != null)
        options.theme = gaugeTheme;
      if (gaugeTemplate != null)
        options.template = gaugeTemplate;
      this.gauge = new Gauge(options, this.cursor);
    }
    style = style || {};
    if (style.fg)
      this.cursor.fg[style.fg]();
    if (style.bg)
      this.cursor.bg[style.bg]();
    if (style.bold)
      this.cursor.bold();
    if (style.underline)
      this.cursor.underline();
    if (style.inverse)
      this.cursor.inverse();
    if (style.beep)
      this.cursor.beep();
    this.cursor.write(msg).reset();
  };
  log.addLevel = function(lvl, n, style, disp) {
    if (!disp)
      disp = lvl;
    this.levels[lvl] = n;
    this.style[lvl] = style;
    if (!this[lvl])
      this[lvl] = function() {
        var a = new Array(arguments.length + 1);
        a[0] = lvl;
        for (var i = 0; i < arguments.length; i++) {
          a[i + 1] = arguments[i];
        }
        return this.log.apply(this, a);
      }.bind(this);
    this.disp[lvl] = disp;
  };
  log.prefixStyle = {fg: 'magenta'};
  log.headingStyle = {
    fg: 'white',
    bg: 'black'
  };
  log.style = {};
  log.levels = {};
  log.disp = {};
  log.addLevel('silly', -Infinity, {inverse: true}, 'sill');
  log.addLevel('verbose', 1000, {
    fg: 'blue',
    bg: 'black'
  }, 'verb');
  log.addLevel('info', 2000, {fg: 'green'});
  log.addLevel('http', 3000, {
    fg: 'green',
    bg: 'black'
  });
  log.addLevel('warn', 4000, {
    fg: 'black',
    bg: 'yellow'
  }, 'WARN');
  log.addLevel('error', 5000, {
    fg: 'red',
    bg: 'black'
  }, 'ERR!');
  log.addLevel('silent', Infinity);
  log.on('error', function() {});
})(require('process'));
Пример #24
0
'use strict';
const ansi   = require('ansi');
const colors = require('colors');
const cursor = ansi(process.stdout);
const args = process.argv.slice(2);

if (args.length === 0) {
    console.log('Enter 3 params: text, color, background color.');
}
else {
    let param3 = args[2];
    param3 = param3.charAt(0).toUpperCase()+param3.substr(1);
    let param = args[0][args[1]]["bg"+param3];
    
    console.log(param);
    //console.log('Hello'.red.bgYellow);
    cursor.beep();
}
Пример #25
0
(function() {

    var ansi    = require('ansi');
    var ansies  = require("ansi-escape-sequences");
    var colors  = require('colors/safe');

    CLI.define('CLI.mixin.Ansi', {

        // {{{ extend

        extend: 'CLI.Mixin',

        // }}}
        // {{{ mixinConfig

        mixinConfig: {

            // {{{ cursor

            cursor: 'cursor',

            // }}}
            // {{{ colors

            colors: 'colors',

            // }}}
            // {{{ ansies

            ansies: 'ansies',

            // }}}
            // {{{ ansi

            ansi: 'ansi'

            // }}}

        },

        // }}}
        // {{{ cursor

        cursor: ansi(process.stdout),

        // }}}
        // {{{ colors

        colors: colors,

        // }}}
        // {{{ ansies

        ansies: ansies,

        // }}}
        // {{{ ansi

        ansi: {

            // {{{ bold

            bold: function(text) {

                var me  = this,
                    f   = CLI.String.format;

                return f('{0}{2}{1}', ansies.bold, ansies.reset, text);

            },

            // }}}
            // {{{ underline

            underline: function(text) {

                var me  = this,
                    f   = CLI.String.format;

                return f('{0}{2}{1}', ansies.underline, ansies.reset, text);

            }

            // }}}

        }

        // ]}}

    });

})();
Пример #26
0
if (cluster.isMaster) {
  var wss = new WebSocketServer({port: 8181}, function() {
    cluster.fork();
  });
  wss.on('connection', function(ws) {
    ws.on('message', function(data, flags) {
      ws.send(data, {binary: flags&&flags.binary});
    });
    ws.on('close', function() {});
  });
  cluster.on('death', function(worker) {
    wss.close();
  });
}
else {
  var cursor = ansi(process.stdout);

  var configs = [
    [true, 10000, 64],
    [true, 5000, 16*1024],
    [true, 1000, 128*1024],
    [true, 100, 1024*1024],
    [true, 1, 500*1024*1024],
    [false, 10000, 64],
    [false, 5000, 16*1024],
    [false, 1000, 128*1024],
    [false, 100, 1024*1024],
  ];

  var largest = configs[0][1];
  for (var i = 0, l = configs.length; i < l; ++i) {
Пример #27
0
function wrap_logging(stream, prefix, tag, show_trace, color, text_color) {
	var cursor = ansi(stream);

	return function () {
		var settings  = this.settings;
		var timestamp = build_timestamp(settings);
		var too_fast  = (Date.now() - this.last < 500 && [ "debug", "error" ].indexOf(prefix) == -1);

		this.last = Date.now();

		if (settings.coloring === false) {
			build_tag(cursor, tag, null);

			cursor.write((too_fast ? str_repeat(" ", timestamp.length) : timestamp) + " ");

			if (this.id) {
				cursor.write(" " + this.id + "  ");
			}

			cursor.write(prefix + ":");

			if (prefix == "debug" && typeof arguments[0] == "object" && arguments[0] && !util.isError(arguments[0])) {
				cursor.write(" " + (arguments[1] || "-- output --")).write("\n");

				JSON.stringify(arguments[0], null, "  ").split("\n").forEach(function (line) {
					build_tag(cursor, tag, null).write(line).write("\n");
				});
			} else {
				cursor.write(" " + util.format.apply(util, arguments)).write("\n");
			}

			if (show_trace) {
				var stack  = traceback();
				var indent = timestamp.length + (this.id ? this.id.length + 3 : 0) + prefix.length + 3;
				var cwd    = process.cwd() + path.sep;

				for (var i = 1; i < stack.length; i++) {
					if (stack[i].path.indexOf(path.sep) == -1) break;

					build_tag(cursor, tag, null)
						.write(str_repeat(" ", indent))
						.write(stack[i].path.indexOf(cwd) === 0 ? stack[i].path.substr(cwd.length) : stack[i].path)
						.write(" , line " + stack[i].line + " , col. " + stack[i].col)
						.write("\n");
				}
			}
		} else {
			build_tag(cursor, tag, text_color || color);

			if (settings.timestamp.color) {
				cursor.hex(settings.timestamp.color);
			}

			cursor.write((too_fast ? str_repeat(" ", timestamp.length) : timestamp) + " ");

			if (this.id) {
				cursor.bg.hex("#222222").fg.hex("#dddddd").write(" " + this.id + " ").bg.reset().write(" ");
			}

			cursor.hex(color).bold().write(prefix + ":");

			if (text_color) {
				cursor.hex(text_color);
			}

			if (prefix == "debug" && typeof arguments[0] == "object" && arguments[0] && !util.isError(arguments[0])) {
				cursor.write(" " + (arguments[1] || "-- output --")).reset().write("\n");

				JSON.stringify(arguments[0], null, "  ").split("\n").forEach(function (line) {
					build_tag(cursor, tag, text_color || color).write(line).write("\n");
				});
			} else {
				cursor.write(" " + util.format.apply(util, arguments)).reset().write("\n");
			}

			if (show_trace) {
				var stack  = traceback();
				var indent = timestamp.length + (this.id ? this.id.length + 3 : 0) + prefix.length + 3;
				var cwd    = process.cwd() + path.sep;

				for (var i = 1; i < stack.length; i++) {
					if (stack[i].path.indexOf(path.sep) == -1) break;

					build_tag(cursor, tag, text_color || color)
						.hex(text_color)
						.write(str_repeat(" ", indent))
						.write(stack[i].path.indexOf(cwd) === 0 ? stack[i].path.substr(cwd.length) : stack[i].path)
						.write(" , line " + stack[i].line + " , col. " + stack[i].col)
						.reset()
						.write("\n");
				}
			}
		}

		return this;
	};
}