<commit_before>(function() {
'use strict';

var stream = require('readable-stream');
var assert = require('assert');
var fs = require('fs');
var util = require('util');

// node-pre-gyp magic
var nodePreGyp = require('node-pre-gyp');
var path = require('path');
var binding_path = nodePreGyp.find(path.resolve(path.join(__dirname,'./package.json')));
var native = require(binding_path);

Object.assign(exports, native);

exports.version = '3.0.0';

var Stream = exports.Stream;

Stream.curAsyncStreamsCount = 0;

Stream.prototype.getStream = function(options) {
  options = options || {};

  return new JSLzmaStream(this, options);
};

class JSLzmaStream extends stream.Transform {
  constructor(nativeStream, options) {
    super(options);

    this.nativeStream = nativeStream;
    this.synchronous = (options.synchronous || !native.asyncCodeAvailable) ? true : false;
    this.chunkCallbacks = [];

    this.totalIn_ = 0;
    this.totalOut_ = 0;

    this._writingLastChunk = false;
    this._isFinished = false;

    if (!this.synchronous) {
      Stream.curAsyncStreamsCount++;

      var oldCleanup = this.cleanup;
      var countedCleanup = false;
      this.cleanup = () => {
        if (countedCleanup === false) {
          Stream.curAsyncStreamsCount--;
          countedCleanup = true;
        }
        oldCleanup.call(this);
      };
    }

    // always clean up in case of error
    this.once('error-cleanup', this.cleanup);

    this.nativeStream.bufferHandler = (buf, processedChunks, err, totalIn, totalOut) => {
      if (totalIn !== null) {
        this.totalIn_  = totalIn;
        this.totalOut_ = totalOut;
      }

      setImmediate(() => {
        if (err) {
          this.push(null);
          this.emit('error-cleanup', err);
          this.emit('error', err);
        }

        if (totalIn !== null) {
          this.emit('progress', {
            totalIn: this.totalIn_,
            totalOut: this.totalOut_
          });
        }

        if (typeof processedChunks === 'number') {
          assert.ok(processedChunks <= this.chunkCallbacks.length);

          var chunkCallbacks = this.chunkCallbacks.splice(0, processedChunks);

          while (chunkCallbacks.length > 0)
            chunkCallbacks.shift().call(this);
        } else if (buf === null) {
          if (this._writingLastChunk) {
            this.push(null);
          } else {
            // There may be additional members in the file.
            // Reset and set _isFinished to tell `_flush()` that nothing
            // needs to be done.
            this._isFinished = true;

            if (this.nativeStream && this.nativeStream._restart) {
              this.nativeStream._restart();
            } else {
              this.push(null);
            }
          }
        } else {
          this.push(buf);
        }
      });
    };

    if (typeof options.bufsize !== 'undefined') {
      this.bufsize = options.bufsize;
    }
  }

  get bufsize() {
    return this.setBufsize(null);
  }

  set bufsize(n) {
    if (typeof n !== 'number' || n <= 0) {
      throw new TypeError('bufsize must be a positive number');
    }

    return this.setBufsize(n);
  }

  totalIn() {
    return this.totalIn_;
  }

  totalOut() {
    return this.totalOut_;
  }

  cleanup() {
    if (this.nativeStream) {
      this.nativeStream.resetUnderlying();
    }

    this.nativeStream = null;
  }

  _transform(chunk, encoding, callback) {
    // Split the chunk at 'YZ'. This is used to have a clean boundary at the
    // end of each `.xz` file stream.
    var possibleEndIndex = bufferIndexOfYZ(chunk);
    if (possibleEndIndex !== -1) {
      possibleEndIndex += 2;
      if (possibleEndIndex !== chunk.length) {
        this._transform(chunk.slice(0, possibleEndIndex), encoding, () => {
          this._transform(chunk.slice(possibleEndIndex), encoding, callback);
        });

        return;
      }
    }

    if (this._isFinished && chunk) {
      chunk = skipLeadingZeroes(chunk);

      if (chunk.length > 0) {
        // Real data from a second stream member in the file!
        this._isFinished = false;
      }
    }

    if (chunk && chunk.length === 0) {
      return callback();
    }

    this.chunkCallbacks.push(callback);

    try {
      this.nativeStream.code(chunk, !this.synchronous);
    } catch (e) {
      this.emit('error-cleanup', e);
      this.emit('error', e);
    }
  }

  _writev(chunks, callback) {
    chunks = chunks.map(chunk => chunk.chunk);
    this._write(Buffer.concat(chunks), null, callback);
  }

  _flush(callback) {
    this._writingLastChunk = true;

    if (this._isFinished) {
      this.cleanup();
      callback(null);
      return;
    }

    this._transform(null, null, function() {
      this.cleanup();
      callback.apply(this, arguments);
    });
  }
}

// add all methods from the native Stream
Object.keys(native.Stream.prototype).forEach(function(key) {
  JSLzmaStream.prototype[key] = function() {
    return this.nativeStream[key].apply(this.nativeStream, arguments);
  };
});

Stream.prototype.rawEncoder = function(options) {
  return this.rawEncoder_(options.filters || []);
};

Stream.prototype.rawDecoder = function(options) {
  return this.rawDecoder_(options.filters || []);
};

Stream.prototype.easyEncoder = function(options) {
  var preset = options.preset || exports.PRESET_DEFAULT;
  var check = options.check || exports.CHECK_CRC32;

  if (typeof options.threads !== 'undefined' && options.threads !== null) {
    return this.mtEncoder_(Object.assign({
      preset: preset,
      filters: null,
      check: check
    }, options));
  } else {
    return this.easyEncoder_(preset, check);
  }
};

Stream.prototype.streamEncoder = function(options) {
  var filters = options.filters || [];
  var check = options.check || exports.CHECK_CRC32;

  if (typeof options.threads !== 'undefined' && options.threads !== null) {
    return this.mtEncoder_(Object.assign({
      preset: null,
      filters: filters,
      check: check
    }, options));
  } else {
    return this.streamEncoder_(filters, check);
  }
};

Stream.prototype.streamDecoder = function(options) {
  this._initOptions = options;
  this._restart = function() {
    this.resetUnderlying();
    this.streamDecoder(this._initOptions);
  };

  return this.streamDecoder_(options.memlimit || null, options.flags || 0);
};

Stream.prototype.autoDecoder = function(options) {
  this._initOptions = options;
  this._restart = function() {
    this.resetUnderlying();
    this.autoDecoder(this._initOptions);
  };

  return this.autoDecoder_(options.memlimit || null, options.flags || 0);
};

Stream.prototype.aloneDecoder = function(options) {
  return this.aloneDecoder_(options.memlimit || null);
};

/* helper functions for easy creation of streams */
var createStream =
exports.createStream = function(coder, options) {
  if (['number', 'object'].indexOf(typeof coder) !== -1 && !options) {
    options = coder;
    coder = null;
  }

  if (parseInt(options) === parseInt(options))
    options = {preset: parseInt(options)};

  coder = coder || 'easyEncoder';
  options = options || {};

  var stream = new Stream();
  stream[coder](options);

  if (options.memlimit)
    stream.memlimitSet(options.memlimit);

  return stream.getStream(options);
};

exports.createCompressor = function(options) {
  return createStream('easyEncoder', options);
};

exports.createDecompressor = function(options) {
  return createStream('autoDecoder', options);
};

exports.crc32 = function(input, encoding, presetCRC32) {
  if (typeof encoding === 'number') {
    presetCRC32 = encoding;
    encoding = null;
  }

  if (typeof input === 'string')
    input = new Buffer(input, encoding);

  return exports.crc32_(input, presetCRC32 || 0);
};

/* compatibility: node-xz (https://github.com/robey/node-xz) */
exports.Compressor = function(preset, options) {
  options = Object.assign({}, options);

  if (preset)
    options.preset = preset;

  return createStream('easyEncoder', options);
};

exports.Decompressor = function(options) {
  return createStream('autoDecoder', options);
};

/* compatibility: LZMA-JS (https://github.com/nmrugg/LZMA-JS) */
function singleStringCoding(stream, string, on_finish, on_progress) {
  on_progress = on_progress || function() {};
  on_finish = on_finish || function() {};

  // possibly our input is an array of byte integers
  // or a typed array
  if (!Buffer.isBuffer(string))
    string = new Buffer(string);

  var deferred = {}, failed = false;

  stream.once('error', function(err) {
    failed = true;
    on_finish(null, err);
  });

  // emulate Promise.defer()
  deferred.promise = new Promise(function(resolve, reject) {
    deferred.resolve = resolve;
    deferred.reject = reject;
  });

  // Since using the Promise API is optional, generating unhandled
  // rejections is not okay.
  deferred.promise.catch(noop);

  stream.once('error', function(e) {
    deferred.reject(e);
  });

  var buffers = [];

  stream.on('data', function(b) {
    buffers.push(b);
  });

  stream.once('end', function() {
    var result = Buffer.concat(buffers);

    if (!failed) {
      on_progress(1.0);
      on_finish(result);
    }

    if (deferred)
      deferred.resolve(result);
  });

  on_progress(0.0);

  stream.end(string);

  if (deferred)
    return deferred.promise;
}

exports.LZMA = function() {
  return {
    compress: function(string, mode, on_finish, on_progress) {
      var opt = {};

      if (parseInt(mode) === parseInt(mode) && mode >= 1 && mode <= 9)
        opt.preset = parseInt(mode);

      var stream = createStream('aloneEncoder', opt);

      return singleStringCoding(stream, string, on_finish, on_progress);
    },
    decompress: function(byte_array, on_finish, on_progress) {
      var stream = createStream('autoDecoder');

      return singleStringCoding(stream, byte_array, on_finish, on_progress);
    },
    // dummy, we don’t use web workers
    worker: function() { return null; }
  };
};

exports.compress = function(string, opt, on_finish) {
  if (typeof opt === 'function') {
    on_finish = opt;
    opt = {};
  }

  var stream = createStream('easyEncoder', opt);
  return singleStringCoding(stream, string, on_finish);
};

exports.decompress = function(string, opt, on_finish) {
  if (typeof opt === 'function') {
    on_finish = opt;
    opt = {};
  }

  var stream = createStream('autoDecoder', opt);
  return singleStringCoding(stream, string, on_finish);
};

if (util.promisify) {
  exports.compress[util.promisify.custom] = exports.compress;
  exports.decompress[util.promisify.custom] = exports.decompress;
}

exports.isXZ = function(buf) {
  return buf && buf.length >= 6 &&
         buf[0] === 0xfd &&
         buf[1] === 0x37 &&
         buf[2] === 0x7a &&
         buf[3] === 0x58 &&
         buf[4] === 0x5a &&
         buf[5] === 0x00;
};

exports.parseFileIndex = function(options, callback) {
  if (typeof options !== 'object') {
    throw new TypeError('parseFileIndex needs an options object');
  }

  var p = new native.IndexParser();

  if (typeof options.fileSize !== 'number') {
    throw new TypeError('parseFileeIndex needs options.fileSize');
  }

  if (typeof options.read !== 'function') {
    throw new TypeError('parseFileIndex needs a read callback');
  }

  p.init(options.fileSize, options.memlimit || 0);
  p.read_cb = function(count, offset) {
    var inSameTick = true;
    var bytesRead = count;

    options.read(count, offset, function(err, buffer) {
      if (Buffer.isBuffer(err)) {
        buffer = err;
        err = null;
      }

      if (err) {
        if (typeof callback === 'undefined') {
          throw err;
        }

        return callback(err, null);
      }

      p.feed(buffer);
      bytesRead = buffer.length;

      if (inSameTick) {
        // The call to parse() is still on the call stack and will continue
        // seamlessly.
        return;
      }

      // Kick off parsing again.
      var info;

      try {
        info = p.parse();
      } catch (e) {
        return callback(e, null);
      }

      if (info !== true) {
        return callback(null, cleanupIndexInfo(info));
      }
    });

    inSameTick = false;

    return bytesRead;
  };

  var info;
  try {
    info = p.parse();
  } catch (e) {
    if (typeof callback !== 'undefined') {
      callback(e, null);
      return;
    }

    throw e;
  }

  if (info !== true) {
    info = cleanupIndexInfo(info);
    if (typeof callback !== 'undefined' && info !== true) {
      callback(null, info);
    }

    return info;
  }
};

exports.parseFileIndexFD = function(fd, callback) {
  return fs.fstat(fd, function(err, stats) {
    if (err) {
      return callback(err, null);
    }

    exports.parseFileIndex({
      fileSize: stats.size,
      read: function(count, offset, cb) {
        var buffer = new Buffer(count);

        fs.read(fd, buffer, 0, count, offset, function(err, bytesRead, buffer) {
          if (err) {
            return cb(err, null);
          }

          if (bytesRead !== count) {
            return cb(new Error('Truncated file!'), null);
          }

          cb(null, buffer);
        });
      }
    }, callback);
  });
};

function cleanupIndexInfo(info) {
  var checkFlags = info.checks;

  info.checks = [];
  for (var i = 0; i < exports.CHECK_ID_MAX; i++) {
    if (checkFlags & (1 << i))
      info.checks.push(i);
  }

  return info;
}

function skipLeadingZeroes(buffer) {
  var i;
  for (i = 0; i < buffer.length; i++) {
    if (buffer[i] !== 0x00)
      break;
  }

  return buffer.slice(i);
}

function bufferIndexOfYZ(chunk) {
  if (!chunk) {
    return -1;
  }

  if (chunk.indexOf) {
    return chunk.indexOf('YZ');
  }

  var i;
  for (i = 0; i < chunk.length - 1; i++) {
    if (chunk[i] === 0x59 && chunk[i+1] === 0x5a) {
      return i;
    }
  }

  return -1;
}

function noop() {}

})();
<commit_msg>lib: fix race condition<commit_after>(function() {
'use strict';

var stream = require('readable-stream');
var assert = require('assert');
var fs = require('fs');
var util = require('util');

// node-pre-gyp magic
var nodePreGyp = require('node-pre-gyp');
var path = require('path');
var binding_path = nodePreGyp.find(path.resolve(path.join(__dirname,'./package.json')));
var native = require(binding_path);

Object.assign(exports, native);

exports.version = '3.0.0';

var Stream = exports.Stream;

Stream.curAsyncStreamsCount = 0;

Stream.prototype.getStream = function(options) {
  options = options || {};

  return new JSLzmaStream(this, options);
};

class JSLzmaStream extends stream.Transform {
  constructor(nativeStream, options) {
    super(options);

    this.nativeStream = nativeStream;
    this.synchronous = (options.synchronous || !native.asyncCodeAvailable) ? true : false;
    this.chunkCallbacks = [];

    this.totalIn_ = 0;
    this.totalOut_ = 0;

    this._writingLastChunk = false;
    this._isFinished = false;

    if (!this.synchronous) {
      Stream.curAsyncStreamsCount++;

      var oldCleanup = this.cleanup;
      var countedCleanup = false;
      this.cleanup = () => {
        if (countedCleanup === false) {
          Stream.curAsyncStreamsCount--;
          countedCleanup = true;
        }
        oldCleanup.call(this);
      };
    }

    // always clean up in case of error
    this.once('error-cleanup', this.cleanup);

    this.nativeStream.bufferHandler = (buf, processedChunks, err, totalIn, totalOut) => {
      if (totalIn !== null) {
        this.totalIn_  = totalIn;
        this.totalOut_ = totalOut;
      }

      setImmediate(() => {
        if (err) {
          this.push(null);
          this.emit('error-cleanup', err);
          this.emit('error', err);
          return;
        }

        if (totalIn !== null) {
          this.emit('progress', {
            totalIn: this.totalIn_,
            totalOut: this.totalOut_
          });
        }

        if (typeof processedChunks === 'number') {
          assert.ok(processedChunks <= this.chunkCallbacks.length);

          var chunkCallbacks = this.chunkCallbacks.splice(0, processedChunks);

          while (chunkCallbacks.length > 0)
            chunkCallbacks.shift().call(this);
        } else if (buf === null) {
          if (this._writingLastChunk) {
            this.push(null);
          } else {
            // There may be additional members in the file.
            // Reset and set _isFinished to tell `_flush()` that nothing
            // needs to be done.
            this._isFinished = true;

            if (this.nativeStream && this.nativeStream._restart) {
              this.nativeStream._restart();
            } else {
              this.push(null);
            }
          }
        } else {
          this.push(buf);
        }
      });
    };

    if (typeof options.bufsize !== 'undefined') {
      this.bufsize = options.bufsize;
    }
  }

  get bufsize() {
    return this.setBufsize(null);
  }

  set bufsize(n) {
    if (typeof n !== 'number' || n <= 0) {
      throw new TypeError('bufsize must be a positive number');
    }

    return this.setBufsize(n);
  }

  totalIn() {
    return this.totalIn_;
  }

  totalOut() {
    return this.totalOut_;
  }

  cleanup() {
    if (this.nativeStream) {
      this.nativeStream.resetUnderlying();
    }

    this.nativeStream = null;
  }

  _transform(chunk, encoding, callback) {
    // Split the chunk at 'YZ'. This is used to have a clean boundary at the
    // end of each `.xz` file stream.
    var possibleEndIndex = bufferIndexOfYZ(chunk);
    if (possibleEndIndex !== -1) {
      possibleEndIndex += 2;
      if (possibleEndIndex !== chunk.length) {
        this._transform(chunk.slice(0, possibleEndIndex), encoding, () => {
          this._transform(chunk.slice(possibleEndIndex), encoding, callback);
        });

        return;
      }
    }

    if (this._isFinished && chunk) {
      chunk = skipLeadingZeroes(chunk);

      if (chunk.length > 0) {
        // Real data from a second stream member in the file!
        this._isFinished = false;
      }
    }

    if (chunk && chunk.length === 0) {
      return callback();
    }

    this.chunkCallbacks.push(callback);

    try {
      this.nativeStream.code(chunk, !this.synchronous);
    } catch (e) {
      this.emit('error-cleanup', e);
      this.emit('error', e);
    }
  }

  _writev(chunks, callback) {
    chunks = chunks.map(chunk => chunk.chunk);
    this._write(Buffer.concat(chunks), null, callback);
  }

  _flush(callback) {
    this._writingLastChunk = true;

    if (this._isFinished) {
      this.cleanup();
      callback(null);
      return;
    }

    this._transform(null, null, function() {
      this.cleanup();
      callback.apply(this, arguments);
    });
  }
}

// add all methods from the native Stream
Object.keys(native.Stream.prototype).forEach(function(key) {
  JSLzmaStream.prototype[key] = function() {
    return this.nativeStream[key].apply(this.nativeStream, arguments);
  };
});

Stream.prototype.rawEncoder = function(options) {
  return this.rawEncoder_(options.filters || []);
};

Stream.prototype.rawDecoder = function(options) {
  return this.rawDecoder_(options.filters || []);
};

Stream.prototype.easyEncoder = function(options) {
  var preset = options.preset || exports.PRESET_DEFAULT;
  var check = options.check || exports.CHECK_CRC32;

  if (typeof options.threads !== 'undefined' && options.threads !== null) {
    return this.mtEncoder_(Object.assign({
      preset: preset,
      filters: null,
      check: check
    }, options));
  } else {
    return this.easyEncoder_(preset, check);
  }
};

Stream.prototype.streamEncoder = function(options) {
  var filters = options.filters || [];
  var check = options.check || exports.CHECK_CRC32;

  if (typeof options.threads !== 'undefined' && options.threads !== null) {
    return this.mtEncoder_(Object.assign({
      preset: null,
      filters: filters,
      check: check
    }, options));
  } else {
    return this.streamEncoder_(filters, check);
  }
};

Stream.prototype.streamDecoder = function(options) {
  this._initOptions = options;
  this._restart = function() {
    this.resetUnderlying();
    this.streamDecoder(this._initOptions);
  };

  return this.streamDecoder_(options.memlimit || null, options.flags || 0);
};

Stream.prototype.autoDecoder = function(options) {
  this._initOptions = options;
  this._restart = function() {
    this.resetUnderlying();
    this.autoDecoder(this._initOptions);
  };

  return this.autoDecoder_(options.memlimit || null, options.flags || 0);
};

Stream.prototype.aloneDecoder = function(options) {
  return this.aloneDecoder_(options.memlimit || null);
};

/* helper functions for easy creation of streams */
var createStream =
exports.createStream = function(coder, options) {
  if (['number', 'object'].indexOf(typeof coder) !== -1 && !options) {
    options = coder;
    coder = null;
  }

  if (parseInt(options) === parseInt(options))
    options = {preset: parseInt(options)};

  coder = coder || 'easyEncoder';
  options = options || {};

  var stream = new Stream();
  stream[coder](options);

  if (options.memlimit)
    stream.memlimitSet(options.memlimit);

  return stream.getStream(options);
};

exports.createCompressor = function(options) {
  return createStream('easyEncoder', options);
};

exports.createDecompressor = function(options) {
  return createStream('autoDecoder', options);
};

exports.crc32 = function(input, encoding, presetCRC32) {
  if (typeof encoding === 'number') {
    presetCRC32 = encoding;
    encoding = null;
  }

  if (typeof input === 'string')
    input = new Buffer(input, encoding);

  return exports.crc32_(input, presetCRC32 || 0);
};

/* compatibility: node-xz (https://github.com/robey/node-xz) */
exports.Compressor = function(preset, options) {
  options = Object.assign({}, options);

  if (preset)
    options.preset = preset;

  return createStream('easyEncoder', options);
};

exports.Decompressor = function(options) {
  return createStream('autoDecoder', options);
};

/* compatibility: LZMA-JS (https://github.com/nmrugg/LZMA-JS) */
function singleStringCoding(stream, string, on_finish, on_progress) {
  on_progress = on_progress || function() {};
  on_finish = on_finish || function() {};

  // possibly our input is an array of byte integers
  // or a typed array
  if (!Buffer.isBuffer(string))
    string = new Buffer(string);

  var deferred = {}, failed = false;

  stream.once('error', function(err) {
    failed = true;
    on_finish(null, err);
  });

  // emulate Promise.defer()
  deferred.promise = new Promise(function(resolve, reject) {
    deferred.resolve = resolve;
    deferred.reject = reject;
  });

  // Since using the Promise API is optional, generating unhandled
  // rejections is not okay.
  deferred.promise.catch(noop);

  stream.once('error', function(e) {
    deferred.reject(e);
  });

  var buffers = [];

  stream.on('data', function(b) {
    buffers.push(b);
  });

  stream.once('end', function() {
    var result = Buffer.concat(buffers);

    if (!failed) {
      on_progress(1.0);
      on_finish(result);
    }

    if (deferred)
      deferred.resolve(result);
  });

  on_progress(0.0);

  stream.end(string);

  if (deferred)
    return deferred.promise;
}

exports.LZMA = function() {
  return {
    compress: function(string, mode, on_finish, on_progress) {
      var opt = {};

      if (parseInt(mode) === parseInt(mode) && mode >= 1 && mode <= 9)
        opt.preset = parseInt(mode);

      var stream = createStream('aloneEncoder', opt);

      return singleStringCoding(stream, string, on_finish, on_progress);
    },
    decompress: function(byte_array, on_finish, on_progress) {
      var stream = createStream('autoDecoder');

      return singleStringCoding(stream, byte_array, on_finish, on_progress);
    },
    // dummy, we don’t use web workers
    worker: function() { return null; }
  };
};

exports.compress = function(string, opt, on_finish) {
  if (typeof opt === 'function') {
    on_finish = opt;
    opt = {};
  }

  var stream = createStream('easyEncoder', opt);
  return singleStringCoding(stream, string, on_finish);
};

exports.decompress = function(string, opt, on_finish) {
  if (typeof opt === 'function') {
    on_finish = opt;
    opt = {};
  }

  var stream = createStream('autoDecoder', opt);
  return singleStringCoding(stream, string, on_finish);
};

if (util.promisify) {
  exports.compress[util.promisify.custom] = exports.compress;
  exports.decompress[util.promisify.custom] = exports.decompress;
}

exports.isXZ = function(buf) {
  return buf && buf.length >= 6 &&
         buf[0] === 0xfd &&
         buf[1] === 0x37 &&
         buf[2] === 0x7a &&
         buf[3] === 0x58 &&
         buf[4] === 0x5a &&
         buf[5] === 0x00;
};

exports.parseFileIndex = function(options, callback) {
  if (typeof options !== 'object') {
    throw new TypeError('parseFileIndex needs an options object');
  }

  var p = new native.IndexParser();

  if (typeof options.fileSize !== 'number') {
    throw new TypeError('parseFileeIndex needs options.fileSize');
  }

  if (typeof options.read !== 'function') {
    throw new TypeError('parseFileIndex needs a read callback');
  }

  p.init(options.fileSize, options.memlimit || 0);
  p.read_cb = function(count, offset) {
    var inSameTick = true;
    var bytesRead = count;

    options.read(count, offset, function(err, buffer) {
      if (Buffer.isBuffer(err)) {
        buffer = err;
        err = null;
      }

      if (err) {
        if (typeof callback === 'undefined') {
          throw err;
        }

        return callback(err, null);
      }

      p.feed(buffer);
      bytesRead = buffer.length;

      if (inSameTick) {
        // The call to parse() is still on the call stack and will continue
        // seamlessly.
        return;
      }

      // Kick off parsing again.
      var info;

      try {
        info = p.parse();
      } catch (e) {
        return callback(e, null);
      }

      if (info !== true) {
        return callback(null, cleanupIndexInfo(info));
      }
    });

    inSameTick = false;

    return bytesRead;
  };

  var info;
  try {
    info = p.parse();
  } catch (e) {
    if (typeof callback !== 'undefined') {
      callback(e, null);
      return;
    }

    throw e;
  }

  if (info !== true) {
    info = cleanupIndexInfo(info);
    if (typeof callback !== 'undefined' && info !== true) {
      callback(null, info);
    }

    return info;
  }
};

exports.parseFileIndexFD = function(fd, callback) {
  return fs.fstat(fd, function(err, stats) {
    if (err) {
      return callback(err, null);
    }

    exports.parseFileIndex({
      fileSize: stats.size,
      read: function(count, offset, cb) {
        var buffer = new Buffer(count);

        fs.read(fd, buffer, 0, count, offset, function(err, bytesRead, buffer) {
          if (err) {
            return cb(err, null);
          }

          if (bytesRead !== count) {
            return cb(new Error('Truncated file!'), null);
          }

          cb(null, buffer);
        });
      }
    }, callback);
  });
};

function cleanupIndexInfo(info) {
  var checkFlags = info.checks;

  info.checks = [];
  for (var i = 0; i < exports.CHECK_ID_MAX; i++) {
    if (checkFlags & (1 << i))
      info.checks.push(i);
  }

  return info;
}

function skipLeadingZeroes(buffer) {
  var i;
  for (i = 0; i < buffer.length; i++) {
    if (buffer[i] !== 0x00)
      break;
  }

  return buffer.slice(i);
}

function bufferIndexOfYZ(chunk) {
  if (!chunk) {
    return -1;
  }

  if (chunk.indexOf) {
    return chunk.indexOf('YZ');
  }

  var i;
  for (i = 0; i < chunk.length - 1; i++) {
    if (chunk[i] === 0x59 && chunk[i+1] === 0x5a) {
      return i;
    }
  }

  return -1;
}

function noop() {}

})();
<|endoftext|>


<commit_before>/*

index.js - "tart-marshal": Send messages between memory domains (tart module)

The MIT License (MIT)

Copyright (c) 2013 Dale Schumacher

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var marshal = module.exports;

marshal.router = function router(defaultRoute) {  // table-based routing transport
    var self = {};

    self.defaultRoute = defaultRoute || function route(message) {
        throw Error('No route for ' + message.address);
    };

    self.routingTable = {};  // mapping from domains to transports

    self.transport = function transport(message) {
        // { address:<token>, content:<json> }
        var remote = message.address;
        var parsed = remote.split('#');
        if (parsed.length != 2) { throw Error('Bad address format: ' + remote); }
        var domain = parsed[0];
        var route = self.routingTable[domain];
        if (!route) {
            route = self.defaultRoute;
        }
        route(message);
    };

    self.domain = function domain(name) {
        var dom = marshal.domain(name, self.transport);
        self.routingTable[name] = function route(message) {
            dom.receptionist(message);  // call domain endpoint
        };
        return dom;
    };

    return self;
};

marshal.domain = function domain(name, transport) {
    var self = {};
    var tokenMap = {};

    self.name = name;
    self.transport = transport;

    self.receptionist = function endpoint(message) {
        // { address:<token>, content:<json> }
        var local = tokenMap[message.address];
        if (!local) { throw Error('Unknown address: ' + message.address); }
        local(decode(message.content));
    };

    var bindLocal = function bindLocal(remote, local) {
        tokenMap[remote] = local;
    };

    var localToRemote = function localToRemote(local) {
        var remote;
        for (remote in tokenMap) {
            if (tokenMap[remote] === local) {
                return remote;
            }
        }
        /* not found, create a new entry */
        remote = name + '#' + generateCapability();
        bindLocal(remote, local);
        return remote;
    };
    var generateCapability = function generateCapability() {
        try {
            return require('crypto').randomBytes(42).toString('base64');
        } catch (exception) {
            // FIXME: if the system runs out of entropy, an exception will be thrown;
            //        we need to define system behavior when we are out of entropy,
            //        remembering that the entire OS crypto activity
            //        (including any encrypted network traffic)
            //        will grind to a halt while waiting for entropy to be available
            throw exception;
        }
    };

    var remoteToLocal = function remoteToLocal(remote) {
        var local = tokenMap[remote];
        if (local === undefined) {
            local = newProxy(remote);  // create new proxy function
            bindLocal(remote, local);
        }
        return local;
    };
    var newProxy = function newProxy(remote) {
        return function proxy(message) {
            self.transport({
                address: remote,
                content: encode(message)
            });
        };
    };

    var encode = function encode(message) {
        var json;
        json = JSON.stringify(message, replacer);
        return json;
    };
    var replacer = function replacer(key, value) {
        if (typeof value === 'function') {
            return localToRemote(value);
        }
        if (typeof value === 'string') {
            return encodeString(value);
        }
        if (value instanceof Error) {
            return {
                message: value.message,
                stack: value.stack
            };
        }
        return value;
    };
    var encodeString = function encodeString(value) {
        return ":" + value;
    };

    var decode = function decode(json) {
        var message;
        message = JSON.parse(json, reviver);
        return message;
    };
    var reviver = function reviver(key, value) {
        if (typeof value === 'string') {
            if (isString(value)) {
                return decodeString(value);
            } else {
                return remoteToLocal(value);
            }
        }
        return value;
    };
    var isString = function isString(value) {
        return (value.charAt(0) === ":");
    };
    var decodeString = function decodeString(value) {
        return value.slice(1);
    };

    self.encode = encode;
    self.decode = decode;
    self.localToRemote = localToRemote;
    self.remoteToLocal = remoteToLocal;
    self.bindLocal = bindLocal;
    return self;
};
<commit_msg>Empty arglist yields undefined<commit_after>/*

index.js - "tart-marshal": Send messages between memory domains (tart module)

The MIT License (MIT)

Copyright (c) 2013 Dale Schumacher

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var marshal = module.exports;

marshal.router = function router(defaultRoute) {  // table-based routing transport
    var self = {};

    self.defaultRoute = defaultRoute || function route(message) {
        throw Error('No route for ' + message.address);
    };

    self.routingTable = {};  // mapping from domains to transports

    self.transport = function transport(message) {
        // { address:<token>, content:<json> }
        var remote = message.address;
        var parsed = remote.split('#');
        if (parsed.length != 2) { throw Error('Bad address format: ' + remote); }
        var domain = parsed[0];
        var route = self.routingTable[domain];
        if (!route) {
            route = self.defaultRoute;
        }
        route(message);
    };

    self.domain = function domain(name) {
        var dom = marshal.domain(name, self.transport);
        self.routingTable[name] = function route(message) {
            dom.receptionist(message);  // call domain endpoint
        };
        return dom;
    };

    return self;
};

marshal.domain = function domain(name, transport) {
    var self = {};
    var tokenMap = {};

    self.name = name;
    self.transport = transport;

    self.receptionist = function endpoint(message) {
        // { address:<token>, content:<json> }
        var local = tokenMap[message.address];
        if (!local) { throw Error('Unknown address: ' + message.address); }
        local(decode(message.content));
    };

    var bindLocal = function bindLocal(remote, local) {
        tokenMap[remote] = local;
    };

    var localToRemote = function localToRemote(local) {
        var remote;
        for (remote in tokenMap) {
            if (tokenMap[remote] === local) {
                return remote;
            }
        }
        /* not found, create a new entry */
        remote = name + '#' + generateCapability();
        bindLocal(remote, local);
        return remote;
    };
    var generateCapability = function generateCapability() {
        try {
            return require('crypto').randomBytes(42).toString('base64');
        } catch (exception) {
            // FIXME: if the system runs out of entropy, an exception will be thrown;
            //        we need to define system behavior when we are out of entropy,
            //        remembering that the entire OS crypto activity
            //        (including any encrypted network traffic)
            //        will grind to a halt while waiting for entropy to be available
            throw exception;
        }
    };

    var remoteToLocal = function remoteToLocal(remote) {
        var local = tokenMap[remote];
        if (local === undefined) {
            local = newProxy(remote);  // create new proxy function
            bindLocal(remote, local);
        }
        return local;
    };
    var newProxy = function newProxy(remote) {
        return function proxy(message) {
            self.transport({
                address: remote,
                content: encode(message)
            });
        };
    };

    var encode = function encode(message) {
        return JSON.stringify(message, replacer);
    };
    var replacer = function replacer(key, value) {
        if (typeof value === 'function') {
            return localToRemote(value);
        }
        if (typeof value === 'string') {
            return encodeString(value);
        }
        if (value instanceof Error) {
            return {
                message: value.message,
                stack: value.stack
            };
        }
        return value;
    };
    var encodeString = function encodeString(value) {
        return ":" + value;
    };

    var decode = function decode(json) {
        if (json === undefined) {
            return undefined;
        }
        return JSON.parse(json, reviver);
    };
    var reviver = function reviver(key, value) {
        if (typeof value === 'string') {
            if (isString(value)) {
                return decodeString(value);
            } else {
                return remoteToLocal(value);
            }
        }
        return value;
    };
    var isString = function isString(value) {
        return (value.charAt(0) === ":");
    };
    var decodeString = function decodeString(value) {
        return value.slice(1);
    };

    self.encode = encode;
    self.decode = decode;
    self.localToRemote = localToRemote;
    self.remoteToLocal = remoteToLocal;
    self.bindLocal = bindLocal;
    return self;
};
<|endoftext|>


<commit_before>/**
 * https://github.com/loopline-systems/electron-builder
 * Licensed under the MIT license.
 */
var fs = require('fs');
var path = require('path');
var os = require('os');
var debug = require('debug')('electron-installer-dmg');

function build(opts, done) {
  var appdmg = require('appdmg');
  var spec = {
    title: opts.name,
    contents: opts.contents,
    icon: opts.icon,
    'icon-size': opts['icon-size'],
    background: opts.background
  };
  var contents = JSON.stringify(spec, null, 2);

  debug('DMG spec is:\n', spec);

  var src = path.resolve(os.tmpDir(), 'appdmg.json');
  debug('writing config to `%s`', src);

  fs.writeFile(src, contents, function(err) {
    if (err) return done(err);
    debug('creating dmg...');
    appdmg({
      source: src,
      target: opts.dmgPath
    }).on('progress', function(info) {
      if (info.type === 'step-begin') {
        debug('appdmg [%d/%d]: %s...', info.current, info.total, info.title);
      }
    }).on('finish', function() {
      debug('appdmg finished!');
      debug('cleaning up temp config at `%s`', src);
      fs.unlink(src, function(err) {
        if (err) return done(err);
        done(null, opts);
      });
    }).on('error', function(err) {
      done(err);
    });
  });
}

module.exports = function(opts, done) {
  if (process.platform !== 'darwin') {
    return done(new Error('Must be run on OSX'));
  }
  if (!opts.background) {
    opts.background = path.resolve(__dirname, 'resources/mac/background.png');
  } else {
    opts.background = path.resolve(opts.background);
  }
  if (!opts.icon) {
    opts.icon = path.resolve(__dirname, 'resources/mac/atom.icns');
  } else {
    opts.icon = path.resolve(opts.icon);
  }

  opts['icon-size'] = opts['icon-size'] || 80;

  opts.appPath = path.resolve(process.cwd(), opts.appPath);
  opts.dmgPath = path.resolve(opts.dmgPath || path.join(opts.out, opts.name + '.dmg'));

  opts.overwrite = opts.overwrite || false;

  opts.contents = opts.contents || [
      {
        x: 448,
        y: 344,
        type: 'link',
        path: '/Applications'
      },
      {
        x: 192,
        y: 344,
        type: 'file',
        path: opts.appPath
      }
      // {
      //   x: 512,
      //   y: 128,
      //   type: 'file',
      //   path: 'release-notes'
      // }
    ];

  fs.exists(opts.dmgPath, function(exists) {
    if (exists && !opts.overwrite) {
      debug('DMG already exists at `%s` and overwrite is false', opts.dmgPath);
      var msg = 'DMG already exists.  Run electron-installer-dmg again with '
        + '`--overwrite` or remove the file and rerun. ' + opts.dmgPath;
      return done(new Error(msg));
    } else if (exists && opts.overwrite) {
      debug('DMG already exists at `%s`.  Removing...', opts.dmgPath);
      fs.unlink(opts.dmgPath, function(err) {
        if (err) return done(err);
        build(opts, done);
      });
    } else {
      build(opts, done);
    }
  });
};
<commit_msg>More flexible title<commit_after>/**
 * https://github.com/loopline-systems/electron-builder
 * Licensed under the MIT license.
 */
var fs = require('fs');
var path = require('path');
var os = require('os');
var debug = require('debug')('electron-installer-dmg');

function build(opts, done) {
  var appdmg = require('appdmg');
  var spec = {
    title: opts.title || opts.productName || opts.name,
    contents: opts.contents,
    icon: opts.icon,
    'icon-size': opts['icon-size'],
    background: opts.background
  };
  var contents = JSON.stringify(spec, null, 2);

  debug('DMG spec is:\n', spec);

  var src = path.resolve(os.tmpDir(), 'appdmg.json');
  debug('writing config to `%s`', src);

  fs.writeFile(src, contents, function(err) {
    if (err) return done(err);
    debug('creating dmg...');
    appdmg({
      source: src,
      target: opts.dmgPath
    }).on('progress', function(info) {
      if (info.type === 'step-begin') {
        debug('appdmg [%d/%d]: %s...', info.current, info.total, info.title);
      }
    }).on('finish', function() {
      debug('appdmg finished!');
      debug('cleaning up temp config at `%s`', src);
      fs.unlink(src, function(err) {
        if (err) return done(err);
        done(null, opts);
      });
    }).on('error', function(err) {
      done(err);
    });
  });
}

module.exports = function(opts, done) {
  if (process.platform !== 'darwin') {
    return done(new Error('Must be run on OSX'));
  }
  if (!opts.background) {
    opts.background = path.resolve(__dirname, 'resources/mac/background.png');
  } else {
    opts.background = path.resolve(opts.background);
  }
  if (!opts.icon) {
    opts.icon = path.resolve(__dirname, 'resources/mac/atom.icns');
  } else {
    opts.icon = path.resolve(opts.icon);
  }

  opts['icon-size'] = opts['icon-size'] || 80;

  opts.appPath = path.resolve(process.cwd(), opts.appPath);
  opts.dmgPath = path.resolve(opts.dmgPath || path.join(opts.out, opts.name + '.dmg'));

  opts.overwrite = opts.overwrite || false;

  opts.contents = opts.contents || [
      {
        x: 448,
        y: 344,
        type: 'link',
        path: '/Applications'
      },
      {
        x: 192,
        y: 344,
        type: 'file',
        path: opts.appPath
      }
      // {
      //   x: 512,
      //   y: 128,
      //   type: 'file',
      //   path: 'release-notes'
      // }
    ];

  fs.exists(opts.dmgPath, function(exists) {
    if (exists && !opts.overwrite) {
      debug('DMG already exists at `%s` and overwrite is false', opts.dmgPath);
      var msg = 'DMG already exists.  Run electron-installer-dmg again with '
        + '`--overwrite` or remove the file and rerun. ' + opts.dmgPath;
      return done(new Error(msg));
    } else if (exists && opts.overwrite) {
      debug('DMG already exists at `%s`.  Removing...', opts.dmgPath);
      fs.unlink(opts.dmgPath, function(err) {
        if (err) return done(err);
        build(opts, done);
      });
    } else {
      build(opts, done);
    }
  });
};
<|endoftext|>


<commit_before>function start_game() {
	//load elements
	sprite = document.getElementById("sprite");
	jump = 0;
	var x = parseInt(sprite.getAttribute("cx").slice(0,-1));
	move_sprite(2, 0.1, x );
			//velocity, gravity, x
}

function check_bounds(x, velocity) {
	//return true if sprite is in bounds
	if (0 < x + velocity && x + velocity < 100) {
		return true;
	} else {
		return false;
	}
}

function move_sprite(velocity, gravity, x) {
	var new_x = x + velocity;	//sets x

	//rest of the function gets new variables for next function call

	//swing back and forth
	if (new_x < 50) {
		if (!check_bounds(new_x, velocity)) {
			velocity = Math.abs(velocity) + gravity - jump;
		}else {
			velocity = velocity + gravity - jump;
		}
	} else {
		if (!check_bounds(new_x, velocity)) {
			velocity = -(velocity) - gravity + jump;
		} else {
			velocity = velocity - gravity + jump;
		}
	}

	//reset any jumps
	if (jump !== 0) {
		jump = 0;
	}

	sprite.setAttribute("cx", new_x + "%");
	//window.setTimeout(move_sprite, 50, velocity, gravity, new_x);
	window.requestAnimationFrame( function() {
		move_sprite(velocity, gravity, new_x);
	});
}

function entry() {
	jump = 2;
}
<commit_msg>Changed new_x and x to use in-function calculations<commit_after>function start_game() {
	//load elements
	sprite = document.getElementById("sprite");
	jump = 0;
	var x = parseInt(sprite.getAttribute("cx").slice(0,-1));
	move_sprite(2, 0.1, x );
			//velocity, gravity, x
}

function check_bounds(x, velocity) {
	//return true if sprite is in bounds
	if (0 < x + velocity && x + velocity < 100) {
		return true;
	} else {
		return false;
	}
}

function move_sprite(velocity, gravity, x) {

	//gets new velocity to swing sprite from center
	if (x < 50) {
		if (!check_bounds(x, velocity)) {
			velocity = Math.abs(velocity) + gravity - jump;
		}else {
			velocity = velocity + gravity - jump;
		}
	} else {
		if (!check_bounds(x, velocity)) {
			velocity = -(velocity) - gravity + jump;
		} else {
			velocity = velocity - gravity + jump;
		}
	}

	//reset any jumps
	if (jump !== 0) {
		jump = 0;
	}

	var new_x = x + velocity;	//sets x
	sprite.setAttribute("cx", new_x + "%");

	window.requestAnimationFrame( function() {
		move_sprite(velocity, gravity, new_x);
	});
}

function entry() {
	jump = 2;
}
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-flexberry',

  included: function(app) {
    this._super.included.apply(this._super, arguments);

    app.import('vendor/flexberry/register-version.js');

    app.import({
      development: 'bower_components/moment/min/moment-with-locales.js',
      production:  'bower_components/moment/min/moment-with-locales.min.js'
    });

    app.import({
      development: 'bower_components/blueimp-file-upload/js/vendor/jquery.ui.widget.js',
      production:  'bower_components/blueimp-file-upload/js/vendor/jquery.ui.widget.js'
    });

    app.import({
      development: 'bower_components/blueimp-file-upload/js/jquery.iframe-transport.js',
      production:  'bower_components/blueimp-file-upload/js/jquery.iframe-transport.js'
    });

    app.import({
      development: 'bower_components/blueimp-file-upload/js/jquery.fileupload.js',
      production:  'bower_components/blueimp-file-upload/js/jquery.fileupload.js'
    });

    app.import({
      development: 'bower_components/semantic-ui-daterangepicker/daterangepicker.js',
      production:  'bower_components/semantic-ui-daterangepicker/daterangepicker.min.js'
    });

    app.import({
      development: 'bower_components/semantic-ui-daterangepicker/daterangepicker.css',
      production:  'bower_components/semantic-ui-daterangepicker/daterangepicker.min.css'
    });

    app.import({
      development: 'bower_components/devicejs/lib/device.js',
      production:  'bower_components/devicejs/lib/device.min.js'
    });

    // Custom script which fixes some jQuery 1.10.x+ AJAX bugs with code from newer jQuery.3.0.0-alpha1+compat version.
    app.import('vendor/jquery.3.0.0-alpha1+compat/jquery.ajaxreplacement.js');

    // Script for column resize.
    app.import('vendor/jquery.colResizable/colResizable-1.5.min.js');

    // JQuery file download plugin with error callbacks support.
    app.import('vendor/jquery.flexberry.downloadFile/jquery.flexberry.downloadFile.js');
  }
};
<commit_msg>Fix wrong import of `register-version.js`<commit_after>/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-flexberry',

  included: function(app) {
    this._super.included.apply(this._super, arguments);

    app.import('vendor/ember-flexberry/register-version.js');

    app.import({
      development: 'bower_components/moment/min/moment-with-locales.js',
      production:  'bower_components/moment/min/moment-with-locales.min.js'
    });

    app.import({
      development: 'bower_components/blueimp-file-upload/js/vendor/jquery.ui.widget.js',
      production:  'bower_components/blueimp-file-upload/js/vendor/jquery.ui.widget.js'
    });

    app.import({
      development: 'bower_components/blueimp-file-upload/js/jquery.iframe-transport.js',
      production:  'bower_components/blueimp-file-upload/js/jquery.iframe-transport.js'
    });

    app.import({
      development: 'bower_components/blueimp-file-upload/js/jquery.fileupload.js',
      production:  'bower_components/blueimp-file-upload/js/jquery.fileupload.js'
    });

    app.import({
      development: 'bower_components/semantic-ui-daterangepicker/daterangepicker.js',
      production:  'bower_components/semantic-ui-daterangepicker/daterangepicker.min.js'
    });

    app.import({
      development: 'bower_components/semantic-ui-daterangepicker/daterangepicker.css',
      production:  'bower_components/semantic-ui-daterangepicker/daterangepicker.min.css'
    });

    app.import({
      development: 'bower_components/devicejs/lib/device.js',
      production:  'bower_components/devicejs/lib/device.min.js'
    });

    // Custom script which fixes some jQuery 1.10.x+ AJAX bugs with code from newer jQuery.3.0.0-alpha1+compat version.
    app.import('vendor/jquery.3.0.0-alpha1+compat/jquery.ajaxreplacement.js');

    // Script for column resize.
    app.import('vendor/jquery.colResizable/colResizable-1.5.min.js');

    // JQuery file download plugin with error callbacks support.
    app.import('vendor/jquery.flexberry.downloadFile/jquery.flexberry.downloadFile.js');
  }
};
<|endoftext|>


<commit_before>var _ = require("lodash");
var q = require("q");

var utils = require("./utils");

function isLeftBorder(opt, x, y) {
    if (!opt.borders) return false;

    return x >= opt.startX && x < (opt.startX + opt.borders.left);
}

function isRightBorder(opt, x, y) {
    if (!opt.borders) return false;

    return x <= opt.endX && x > (opt.endX - opt.borders.left);
}

function isTopBorder(opt, x, y) {
    if (!opt.borders) return false;

    return y >= opt.startY && y < (opt.startY + opt.borders.top);
}

function isBottomBorder(opt, x, y) {
    if (!opt.borders) return false;

    return y <= opt.endY && y > (opt.endY - opt.borders.bottom);
}

function isBorder(opt, x, y) {
    return isLeftBorder(opt, x, y) || isRightBorder(opt, x, y) || isTopBorder(opt, x, y) || isBottomBorder(opt, x, y);
}

function isCenter(opt, x, y) {
    if (!opt.center || !opt.centerSize || opt.sizeX < opt.centerSize || opt.sizeY < opt.centerSize) return false;

    x = x - opt.startX;
    y = y - opt.startY;
    var c = opt.centerSize;
    var mx = Math.floor((opt.sizeX - opt.centerSize) / 2);
    var my = Math.floor((opt.sizeY - opt.centerSize) / 2);

    return x > mx && x <= (mx + c) && y > my && y <= (my + c);
}

function createGenerateOptions(opt, x, y) {
    var template = opt.default;

    if (isBorder(opt, x, y)) {
        template = opt.border;
    } else if (isCenter(opt, x, y)) {
        template = opt.center;
    }

    var roomOpt = _.assign({ exits: {} }, template);

    if (x == opt.startX && opt.closed.left) {
        roomOpt.exits.left = [];
    }
    if (x == opt.endX && opt.closed.right) {
        roomOpt.exits.right = [];
    }
    if (y == opt.startY && opt.closed.top) {
        roomOpt.exits.top = [];
    }
    if (y == opt.endY && opt.closed.bottom) {
        roomOpt.exits.bottom = [];
    }

    if (template.terrainType && (typeof template.terrainType === 'function')) {
        roomOpt.terrainType = template.terrainType();
    }

    if (template.swampType && (typeof template.swampType === 'function')) {
        roomOpt.swampType = template.swampType();
    }

    return roomOpt;
}

function findMapRange(opt, rooms) {
    var findStart = !opt.start;
    var findEnd = !(opt.end || opt.sizeX || opt.sizeY);

    if (rooms && (findStart || findEnd)) {
        for (var room of rooms) {
            var [x, y] = utils.roomNameToXY(room._id);

            if (!opt.start || x < opt.startX || y < opt.startY) {
                opt.start = room._id;
                opt.startX = x;
                opt.startY = y;
            }

            if (findEnd && (!opt.end || x > opt.startX || y > opt.startY)) {
                opt.end = room._id;
                opt.endX = x;
                opt.endY = y;
            }
        }
    }

    if (!opt.startX || !opt.startY) {
        [opt.startX, opt.startY] = utils.roomNameToXY(opt.start);
    }

    if (!opt.end) {
        opt.sizeX = opt.sizeX || 0;
        opt.sizeY = opt.sizeY || 0;

        opt.endX = opt.startX + opt.sizeX;
        opt.endY = opt.startY + opt.sizeY;
        opt.end = utils.roomNameFromXY(opt.endX, opt.endY);
    } else if (!opt.endX || !opt.endY) {
        [opt.endX, opt.endY] = utils.roomNameToXY(opt.end);
    }

    if (opt.startX > opt.endX) {
        [opt.endX, opt.startX] = [opt.startX, opt.endX];
    }
    if (opt.startY > opt.endY) {
        [opt.endY, opt.startY] = [opt.startY, opt.endY];
    }

    opt.start = utils.roomNameFromXY(opt.startX, opt.startY);
    opt.end = utils.roomNameFromXY(opt.endX, opt.endY);

    opt.sizeX = opt.endX - opt.startX;
    opt.sizeY = opt.endY - opt.startY;
}

const defaultOptions = {
    centerSize: 3,

    default: {},

    quiet: false,

    borders: { top: 1, bottom: 1, left: 1, right: 1 },
    closed: { top: true, bottom: true, left: true, right: true },

    border: {
        sources: 0,
        mineral: false,
        controller: false,
        terrainType: () => Math.floor(Math.random() * 2) + 1,
        swampType: () => Math.floor(Math.random() * 3)
    },

    center: {
        sources: 4,
        keeperLairs: true,
        controller: false
    }
}

function register(sandbox) {
    sandbox.map.createMap = utils.withHelp([
        `createMap([opts]) - Generates a dictionary of options for 'generateMap'. 'opts' is an object with the following optional properties:\r
    * [start] - name of starting room corner
    * [end] - name of ending room corner
    * [size] - size of the map
    * [sizeX] - size of map in X direction
    * [sizeY] - size of map in Y direction
    * [quiet] - suppress printing of progress messages

    If you don't specify a square ('start' and 'end' or 'start' and 'size') then will use whole map
    Borders Closed:
    * [closed] -
        * [top] - true
        * [bottom] - true
        * [left] - true
        * [right] - true
    Size of borders
    * [borders] -
        * [top] - 1
        * [bottom] - 1
        * [left] - 1
        * [right] - 1
    * [centerSize] - (default: 3) the size of the center room area square

    * [default], [border], [center] - the options for these types of rooms, see 'generateRoom' for details
      Note that 'terrainType' and 'swampType' can be functions.

    Example:
        Add a new 10 x 10 EAST NORTH sector to the default WEST NORTH sector and make a two border 'highway' between the two

        map.createMap({start: 'W0N0', end: 'E10N10', closed: { left: false }, borders { left: 2 }})
    `,
        function (options) {
            var opt = _.merge({}, defaultOptions, options || {});
            if (opt.size) {
                opt.sizeX = opt.size;
                opt.sizeY = opt.size;
            }

            var configureTask = opt.start && (opt.end || opt.size || opt.sizeX || opt.sizeY)
                ? q.when()
                : sandbox.storage.db.rooms.find({});

            return configureTask
                .then(rooms => {
                    findMapRange(opt, rooms);

                    var map = {};
                    for (var x = opt.startX; x <= opt.endX; ++x) {
                        for (var y = opt.startY; y <= opt.endY; ++y) {
                            var roomName = utils.roomNameFromXY(x, y);
                            var roomOpt = createGenerateOptions(opt, x, y);

                            map[roomName] = roomOpt;
                        }
                    }

                    map._map = true;

                    return q.when(map);
                });
        }]);

    sandbox.map.generateMap = utils.withHelp([
        `generateMap([opts]) - generates a new map.
        * [opt] - can be either the options object passed to 'createMap' or the result of 'createMap'`,
        function (options) {
            options = options || {};

            var opt = options._map ? options : _.merge({}, defaultOptions, options);

            var wasPaused = false;
            return sandbox.storage.env.get(sandbox.storage.env.keys.MAIN_LOOP_PAUSED)
                .then(paused => {
                    if (paused === '1') {
                        wasPaused = true;
                        return q.when();
                    }
                    if (!opt.quiet) sandbox.print('pausing simulation');

                    return sandbox.system.pauseSimulation();
                })
                .then(() => opt._map ? q.when(opt) : sandbox.map.createMap(opt))
                .then(map => {
                    var work = [];

                    if (map._map) {
                        delete map._map;
                    }

                    for (var roomName in map) {
                        work.push({ roomName: roomName, opt: map[roomName] });
                    }

                    return _.reduce(
                        work,
                        (soFar, w) => soFar
                            .then(() => sandbox.storage.db.rooms.findOne({ _id: w.roomName }))
                            .then(obj => {
                                if (obj) {
                                    if (!opt.quiet) sandbox.print('Removing ' + obj._id);
                                    return sandbox.map.removeRoom(obj._id);
                                }

                                return q.when();
                            })
                            .then(() => {
                                if (!opt.quiet) sandbox.print('Generating ' + w.roomName);
                                return sandbox.map.generateRoom(w.roomName, w.opt)
                            }),
                        q.when());
                })
                .then(() => wasPaused ? q.when() : sandbox.system.resumeSimulation())
                .then(() => 'OK');
        }]);

    sandbox.map._help = utils.generateCliHelp('map.', sandbox.map);
}

module.exports = function (config) {
    if (config.cli) {
        config.cli.on('cliSandbox', function (sandbox) {
            register(sandbox);
        });
    }
};
<commit_msg>Update index.js (#3)<commit_after>var _ = require("lodash");
var q = require("q");

var utils = require("./utils");

function isLeftBorder(opt, x, y) {
    if (!opt.borders) return false;

    return x >= opt.startX && x < (opt.startX + opt.borders.left);
}

function isRightBorder(opt, x, y) {
    if (!opt.borders) return false;

    return x <= opt.endX && x > (opt.endX - opt.borders.left);
}

function isTopBorder(opt, x, y) {
    if (!opt.borders) return false;

    return y >= opt.startY && y < (opt.startY + opt.borders.top);
}

function isBottomBorder(opt, x, y) {
    if (!opt.borders) return false;

    return y <= opt.endY && y > (opt.endY - opt.borders.bottom);
}

function isBorder(opt, x, y) {
    return isLeftBorder(opt, x, y) || isRightBorder(opt, x, y) || isTopBorder(opt, x, y) || isBottomBorder(opt, x, y);
}

function isCenter(opt, x, y) {
    if (!opt.center || !opt.centerSize || opt.sizeX < opt.centerSize || opt.sizeY < opt.centerSize) return false;

    x = x - opt.startX;
    y = y - opt.startY;
    var c = opt.centerSize;
    var mx = Math.floor((opt.sizeX - opt.centerSize) / 2);
    var my = Math.floor((opt.sizeY - opt.centerSize) / 2);

    return x > mx && x <= (mx + c) && y > my && y <= (my + c);
}

function createGenerateOptions(opt, x, y) {
    var template = opt.default;

    if (isBorder(opt, x, y)) {
        template = opt.border;
    } else if (isCenter(opt, x, y)) {
        template = opt.center;
    }

    var roomOpt = _.assign({ exits: {} }, template);

    if (x == opt.startX && opt.closed.left) {
        roomOpt.exits.left = [];
    }
    if (x == opt.endX && opt.closed.right) {
        roomOpt.exits.right = [];
    }
    if (y == opt.startY && opt.closed.top) {
        roomOpt.exits.top = [];
    }
    if (y == opt.endY && opt.closed.bottom) {
        roomOpt.exits.bottom = [];
    }

    if (template.terrainType && (typeof template.terrainType === 'function')) {
        roomOpt.terrainType = template.terrainType();
    }

    if (template.swampType && (typeof template.swampType === 'function')) {
        roomOpt.swampType = template.swampType();
    }

    return roomOpt;
}

function findMapRange(opt, rooms) {
    var findStart = !opt.start;
    var findEnd = !(opt.end || opt.sizeX || opt.sizeY);

    if (rooms && (findStart || findEnd)) {
        for (var room of rooms) {
            var [x, y] = utils.roomNameToXY(room._id);

            if (!opt.start || x < opt.startX || y < opt.startY) {
                opt.start = room._id;
                opt.startX = x;
                opt.startY = y;
            }

            if (findEnd && (!opt.end || x > opt.startX || y > opt.startY)) {
                opt.end = room._id;
                opt.endX = x;
                opt.endY = y;
            }
        }
    }

    if (!opt.startX || !opt.startY) {
        [opt.startX, opt.startY] = utils.roomNameToXY(opt.start);
    }

    if (!opt.end) {
        opt.sizeX = opt.sizeX || 0;
        opt.sizeY = opt.sizeY || 0;

        opt.endX = opt.startX + opt.sizeX;
        opt.endY = opt.startY + opt.sizeY;
        opt.end = utils.roomNameFromXY(opt.endX, opt.endY);
    } else if (!opt.endX || !opt.endY) {
        [opt.endX, opt.endY] = utils.roomNameToXY(opt.end);
    }

    if (opt.startX > opt.endX) {
        [opt.endX, opt.startX] = [opt.startX, opt.endX];
    }
    if (opt.startY > opt.endY) {
        [opt.endY, opt.startY] = [opt.startY, opt.endY];
    }

    opt.start = utils.roomNameFromXY(opt.startX, opt.startY);
    opt.end = utils.roomNameFromXY(opt.endX, opt.endY);

    opt.sizeX = opt.endX - opt.startX;
    opt.sizeY = opt.endY - opt.startY;
}

const defaultOptions = {
    centerSize: 3,

    default: {},

    quiet: false,

    borders: { top: 1, bottom: 1, left: 1, right: 1 },
    closed: { top: true, bottom: true, left: true, right: true },

    border: {
        sources: 0,
        mineral: false,
        controller: false,
        terrainType: () => Math.floor(Math.random() * 2) + 1,
        swampType: () => Math.floor(Math.random() * 3)
    },

    center: {
        sources: 4,
        keeperLairs: true,
        controller: false
    }
}

function register(sandbox) {
    sandbox.map.createMap = utils.withHelp([
        `createMap([opts]) - Generates a dictionary of options for 'generateMap'. 'opts' is an object with the following optional properties:\r
    * [start] - name of starting room corner
    * [end] - name of ending room corner
    * [size] - size of the map
    * [sizeX] - size of map in X direction
    * [sizeY] - size of map in Y direction
    * [quiet] - suppress printing of progress messages

    If you don't specify a square ('start' and 'end' or 'start' and 'size') then will use whole map
    Borders Closed:
    * [closed] -
        * [top] - true
        * [bottom] - true
        * [left] - true
        * [right] - true
    Size of borders
    * [borders] -
        * [top] - 1
        * [bottom] - 1
        * [left] - 1
        * [right] - 1
    * [centerSize] - (default: 3) the size of the center room area square

    * [default], [border], [center] - the options for these types of rooms, see 'generateRoom' for details
      Note that 'terrainType' and 'swampType' can be functions.

    Example:
        Add a new 10 x 10 EAST NORTH sector to the default WEST NORTH sector and make a two border 'highway' between the two

        map.createMap({start: 'W0N0', end: 'E10N10', closed: { left: false }, borders: { left: 2 }})
    `,
        function (options) {
            var opt = _.merge({}, defaultOptions, options || {});
            if (opt.size) {
                opt.sizeX = opt.size;
                opt.sizeY = opt.size;
            }

            var configureTask = opt.start && (opt.end || opt.size || opt.sizeX || opt.sizeY)
                ? q.when()
                : sandbox.storage.db.rooms.find({});

            return configureTask
                .then(rooms => {
                    findMapRange(opt, rooms);

                    var map = {};
                    for (var x = opt.startX; x <= opt.endX; ++x) {
                        for (var y = opt.startY; y <= opt.endY; ++y) {
                            var roomName = utils.roomNameFromXY(x, y);
                            var roomOpt = createGenerateOptions(opt, x, y);

                            map[roomName] = roomOpt;
                        }
                    }

                    map._map = true;

                    return q.when(map);
                });
        }]);

    sandbox.map.generateMap = utils.withHelp([
        `generateMap([opts]) - generates a new map.
        * [opt] - can be either the options object passed to 'createMap' or the result of 'createMap'`,
        function (options) {
            options = options || {};

            var opt = options._map ? options : _.merge({}, defaultOptions, options);

            var wasPaused = false;
            return sandbox.storage.env.get(sandbox.storage.env.keys.MAIN_LOOP_PAUSED)
                .then(paused => {
                    if (paused === '1') {
                        wasPaused = true;
                        return q.when();
                    }
                    if (!opt.quiet) sandbox.print('pausing simulation');

                    return sandbox.system.pauseSimulation();
                })
                .then(() => opt._map ? q.when(opt) : sandbox.map.createMap(opt))
                .then(map => {
                    var work = [];

                    if (map._map) {
                        delete map._map;
                    }

                    for (var roomName in map) {
                        work.push({ roomName: roomName, opt: map[roomName] });
                    }

                    return _.reduce(
                        work,
                        (soFar, w) => soFar
                            .then(() => sandbox.storage.db.rooms.findOne({ _id: w.roomName }))
                            .then(obj => {
                                if (obj) {
                                    if (!opt.quiet) sandbox.print('Removing ' + obj._id);
                                    return sandbox.map.removeRoom(obj._id);
                                }

                                return q.when();
                            })
                            .then(() => {
                                if (!opt.quiet) sandbox.print('Generating ' + w.roomName);
                                return sandbox.map.generateRoom(w.roomName, w.opt)
                            }),
                        q.when());
                })
                .then(() => wasPaused ? q.when() : sandbox.system.resumeSimulation())
                .then(() => 'OK');
        }]);

    sandbox.map._help = utils.generateCliHelp('map.', sandbox.map);
}

module.exports = function (config) {
    if (config.cli) {
        config.cli.on('cliSandbox', function (sandbox) {
            register(sandbox);
        });
    }
};
<|endoftext|>


<commit_before>var chalk = require('chalk');

var m = {
	//////////////////
	// main methods //
	//////////////////

	// default
	d: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.white('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.white(msg));
		}
	},
	// success
	s: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.bold.green('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.bold.green(msg));
		}
	},
	// warning
	w: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.bgYellow.black('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.bgYellow.black(msg));
		}
	},
	// err
	e: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.bgRed.white('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.bgRed.white(msg));
		}
	},
	// highlight
	h: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.bgCyan.black('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.bgCyan.black(msg));
		}
	},
	//info
	i: function(msg) {
		if (typeof(msg) == 'object') {
			console.info(chalk.bold.cyan('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.info(chalk.bold.cyan(msg));
		}
	},
	//trace:
	t: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.green("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< BEGIN"));
			console.trace(chalk.green('\n' + JSON.stringify(msg, null, 2)));
			console.log(chalk.green(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END\n"));
		} else {
			console.log(chalk.green("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< BEGIN"));
			console.trace(chalk.green(msg));
			console.log(chalk.green(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END\n"));
		}
	},

	///////////
	// lines //
	///////////

	// default
	line: function(char = '-', length = 30) {
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() function can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(theLine);
		}
	},
	// default - another
	dline: function(char = '-', length = 30) {
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(theLine);
		}
	},
	// success
	sline: function(char = '-', length = 30) {
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(chalk.bold.green(theLine));
		}
	},
	// warning
	wline: function(char = '-', length = 30) {
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(chalk.bgYellow.black(theLine));
		}
	},
	// error
	eline: function(char = '-', length = 30) {
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(chalk.bgRed.white(theLine));
		}
	},
	// highlight
	hline: function(char = '-', length = 30) {
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(chalk.bgCyan.black(theLine));
		}
	}
};

module.exports = m;
<commit_msg>Optimizing code for supporting older versions of Node >4<commit_after>'use strict';

var chalk = require('chalk');

var m = {
	//////////////////
	// main methods //
	//////////////////

	// default
	d: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.white('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.white(msg));
		}
	},
	// success
	s: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.bold.green('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.bold.green(msg));
		}
	},
	// warning
	w: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.bgYellow.black('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.bgYellow.black(msg));
		}
	},
	// err
	e: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.bgRed.white('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.bgRed.white(msg));
		}
	},
	// highlight
	h: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.bgCyan.black('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.log(chalk.bgCyan.black(msg));
		}
	},
	//info
	i: function(msg) {
		if (typeof(msg) == 'object') {
			console.info(chalk.bold.cyan('\n' + JSON.stringify(msg, null, 2)));
		} else {
			console.info(chalk.bold.cyan(msg));
		}
	},
	//trace:
	t: function(msg) {
		if (typeof(msg) == 'object') {
			console.log(chalk.green("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< BEGIN"));
			console.trace(chalk.green('\n' + JSON.stringify(msg, null, 2)));
			console.log(chalk.green(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END\n"));
		} else {
			console.log(chalk.green("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< BEGIN"));
			console.trace(chalk.green(msg));
			console.log(chalk.green(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END\n"));
		}
	},

	///////////
	// lines //
	///////////

	// default
	line: function(char, length) {
		if(!char) {
			char = '-';
		};
		if(!length) {
			length = 30;
		};
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() function can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(theLine);
		}
	},
	// default - another
	dline: function(char, length) {
		if(!char) {
			char = '-';
		};
		if(!length) {
			length = 30;
		};
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(theLine);
		}
	},
	// success
	sline: function(char, length) {
		if(!char) {
			char = '-';
		};
		if(!length) {
			length = 30;
		};
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(chalk.bold.green(theLine));
		}
	},
	// warning
	wline: function(char, length) {
		if(!char) {
			char = '-';
		};
		if(!length) {
			length = 30;
		};
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(chalk.bgYellow.black(theLine));
		}
	},
	// error
	eline: function(char, length) {
		if(!char) {
			char = '-';
		};
		if(!length) {
			length = 30;
		};
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(chalk.bgRed.white(theLine));
		}
	},
	// highlight
	hline: function(char, length) {
		if(!char) {
			char = '-';
		};
		if(!length) {
			length = 30;
		};
		if (typeof(char) == 'object') {
			this.e("ERROR: the line() functions can't accept objects!");
			char = '-';
		} else {
			if (length > 100) {
				// this.w("WARNING: ");
			}
			var theLine = "";
			for (var i = 0; i < length; i++) {
				theLine = theLine + char;
			};
			console.log(chalk.bgCyan.black(theLine));
		}
	}
};

module.exports = m;
<|endoftext|>