<commit_before>var cp = require('child_process')
var findRoot = require('find-root')
var glob = require('glob')
var Minimatch = require('minimatch').Minimatch
var parallel = require('run-parallel')
var path = require('path')
var split = require('split')
var uniq = require('uniq')

var JSCS_RC = path.join(__dirname, 'rc', '.jscsrc')
var JSCS_REPORTER = path.join(__dirname, 'lib', 'jscs-reporter.js')
var JSCS_REPORTER_VERBOSE = path.join(__dirname, 'lib', 'jscs-reporter-verbose.js')

var ESLINT_RC = path.join(__dirname, 'rc', '.eslintrc')
var ESLINT_REPORTER = path.join(__dirname, 'lib', 'eslint-reporter.js')
var ESLINT_REPORTER_VERBOSE = path.join(__dirname, 'lib', 'eslint-reporter-verbose.js')

var DEFAULT_IGNORE = [
  'node_modules/**',
  '.git/**',
  '**/*.min.js',
  '**/bundle.js',
  'coverage/**'
]

var ERROR_RE = /.*?:\d+:\d+/
var FILE_RE = /(.*?):/
var LINE_RE = /.*?:(\d+)/
var COL_RE = /.*?:\d+:(\d+)/

/**
 * JavaScript Standard Style
 * @param {Object} opts                        options object
 * @param {string|Array.<String>} opts.ignore  files to ignore
 * @param {boolean} opts.bare                  show raw linter output (for debugging)
 * @param {string} opts.cwd                    current working directory
 * @param {Array.<string>} files               files to check
 * @param {boolean} opts.stdin                 check text from stdin instead of filesystem
 * @param {boolean} opts.verbose               show error codes
 */
module.exports = function standard (opts) {
  if (!opts) opts = {}
  var errors = []

  var root
  try {
    root = findRoot(process.cwd())
  } catch (e) {}

  var ignore = [].concat(DEFAULT_IGNORE) // globs to ignore

  if (root) {
    var packageOpts = require(path.join(root, 'package.json')).standard
    if (packageOpts) ignore = ignore.concat(packageOpts.ignore)
  }

  var jscsReporter = opts.verbose ? JSCS_REPORTER_VERBOSE : JSCS_REPORTER
  var jscsArgs = ['--config', JSCS_RC, '--reporter', jscsReporter]

  var eslintReporter = opts.verbose ? ESLINT_REPORTER_VERBOSE : ESLINT_REPORTER
  var eslintArgs = ['--config', ESLINT_RC, '--format', eslintReporter]

  if (opts.verbose) {
    jscsArgs.push('--verbose')
  }

  if ((Array.isArray(opts.files) && opts.files.length > 0) || !opts.stdin) {
    var patterns = (Array.isArray(opts.files) && opts.files.length > 0)
      ? opts.files
      : [ '**/*.js' ]

    // traverse filesystem
    if (opts.ignore) ignore = ignore.concat(opts.ignore)

    ignore = ignore.map(function (pattern) {
      return new Minimatch(pattern)
    })

    parallel(patterns.map(function (pattern) {
      return function (cb) {
        glob(pattern, {
          cwd: opts.cwd || process.cwd(),
          nodir: true
        }, cb)
      }
    }), function (err, results) {
      if (err) return error(err)

      // flatten nested arrays
      var files = results.reduce(function (files, result) {
        result.forEach(function (file) {
          files.push(file)
        })
        return files
      }, [])

      // apply ignore patterns
      files = files.filter(function (file) {
        return !ignore.some(function (mm) {
          return mm.match(file)
        })
      })

      // de-dupe
      files = uniq(files)
      if (files.length > 0) {
        jscsArgs = jscsArgs.concat(files)
        eslintArgs = eslintArgs.concat(files)
        lint()
      }
    })
  } else {
    // stdin
    eslintArgs.push('--stdin')
    lint()
  }

  function lint () {
    findBinPaths(function (err, paths) {
      if (err) return error(err)
      parallel([
        spawn.bind(undefined, paths.jscs, jscsArgs),
        spawn.bind(undefined, paths.eslint, eslintArgs)
      ], function (err, r) {
        if (err) return error(err)
        if (r.some(Boolean)) printErrors()
      })
    })
  }

  function findBinPaths (cb) {
    parallel({
      eslint: findBinPath.bind(undefined, 'eslint'),
      jscs: findBinPath.bind(undefined, 'jscs')
    }, cb)
  }

  function findBinPath (bin, cb) {
    var opts = { cwd: __dirname }
    cp.exec('npm run --silent which-' + bin, opts, function (err, stdout, stderr) {
      if (err) return cb(err)
      cb(null, stdout.toString().replace(/\n/g, ''))
    })
  }

  function spawn (command, args, cb) {
    var child = cp.spawn(command, args)
    child.on('error', cb)
    child.on('close', function (code) {
      cb(null, code)
    })
    if (opts.stdin) process.stdin.pipe(child.stdin)
    stderrPipe(child.stdout)
    stderrPipe(child.stderr)
  }

  function stderrPipe (readable) {
    readable
      .pipe(split())
      .on('data', function (line) {
        if (line === '') return
        errors.push(line)
      })
  }

  function printErrors () {
    if (opts.bare) {
      errors.forEach(function (str) {
        console.error(str)
      })
      return
    }

    console.error('Error: Code style check failed:')
    var unexpectedOutput = []
    var errMap = {}
    errors
      .map(function (str) { // normalize stdin "filename"
        return str.replace(/^(<text>|input)/, 'stdin')
      })
      .filter(function (str) {
        // don't process unexpected/malformed output, just print it at the end
        if (!ERROR_RE.test(str)) {
          unexpectedOutput.push(str)
          return false
        }

        // de-duplicate errors
        if (errMap[str]) return false
        errMap[str] = true
        return true
      })
      .sort(function (a, b) {
        // sort by line number (merges output from all linters)
        var fileA = FILE_RE.exec(a)[1]
        var fileB = FILE_RE.exec(b)[1]

        var lineA = Number(LINE_RE.exec(a)[1])
        var lineB = Number(LINE_RE.exec(b)[1])

        var colA = Number(COL_RE.exec(a)[1])
        var colB = Number(COL_RE.exec(b)[1])

        if (fileA !== fileB) return fileA < fileB ? -1 : 1
        if (lineA !== lineB) return lineA - lineB
        return colA - colB
      })
      .forEach(function (str) {
        console.error('  ' + str) // indent
      })

    if (unexpectedOutput.length) console.error('\nUnexpected Linter Output:')
    unexpectedOutput.forEach(function (str) {
      console.error(str)
    })

    process.exit(1)
  }
}

function error (err) {
  console.error(err.stack || err.message || err)
  process.exit(1)
}
<commit_msg>always ignore node_modules<commit_after>var cp = require('child_process')
var findRoot = require('find-root')
var glob = require('glob')
var Minimatch = require('minimatch').Minimatch
var parallel = require('run-parallel')
var path = require('path')
var split = require('split')
var uniq = require('uniq')

var JSCS_RC = path.join(__dirname, 'rc', '.jscsrc')
var JSCS_REPORTER = path.join(__dirname, 'lib', 'jscs-reporter.js')
var JSCS_REPORTER_VERBOSE = path.join(__dirname, 'lib', 'jscs-reporter-verbose.js')

var ESLINT_RC = path.join(__dirname, 'rc', '.eslintrc')
var ESLINT_REPORTER = path.join(__dirname, 'lib', 'eslint-reporter.js')
var ESLINT_REPORTER_VERBOSE = path.join(__dirname, 'lib', 'eslint-reporter-verbose.js')

var DEFAULT_IGNORE = [
  '**/node_modules/**',
  '.git/**',
  '**/*.min.js',
  '**/bundle.js',
  'coverage/**'
]

var ERROR_RE = /.*?:\d+:\d+/
var FILE_RE = /(.*?):/
var LINE_RE = /.*?:(\d+)/
var COL_RE = /.*?:\d+:(\d+)/

/**
 * JavaScript Standard Style
 * @param {Object} opts                        options object
 * @param {string|Array.<String>} opts.ignore  files to ignore
 * @param {boolean} opts.bare                  show raw linter output (for debugging)
 * @param {string} opts.cwd                    current working directory
 * @param {Array.<string>} files               files to check
 * @param {boolean} opts.stdin                 check text from stdin instead of filesystem
 * @param {boolean} opts.verbose               show error codes
 */
module.exports = function standard (opts) {
  if (!opts) opts = {}
  var errors = []

  var root
  try {
    root = findRoot(process.cwd())
  } catch (e) {}

  var ignore = [].concat(DEFAULT_IGNORE) // globs to ignore

  if (root) {
    var packageOpts = require(path.join(root, 'package.json')).standard
    if (packageOpts) ignore = ignore.concat(packageOpts.ignore)
  }

  var jscsReporter = opts.verbose ? JSCS_REPORTER_VERBOSE : JSCS_REPORTER
  var jscsArgs = ['--config', JSCS_RC, '--reporter', jscsReporter]

  var eslintReporter = opts.verbose ? ESLINT_REPORTER_VERBOSE : ESLINT_REPORTER
  var eslintArgs = ['--config', ESLINT_RC, '--format', eslintReporter]

  if (opts.verbose) {
    jscsArgs.push('--verbose')
  }

  if ((Array.isArray(opts.files) && opts.files.length > 0) || !opts.stdin) {
    var patterns = (Array.isArray(opts.files) && opts.files.length > 0)
      ? opts.files
      : [ '**/*.js' ]

    // traverse filesystem
    if (opts.ignore) ignore = ignore.concat(opts.ignore)

    ignore = ignore.map(function (pattern) {
      return new Minimatch(pattern)
    })

    parallel(patterns.map(function (pattern) {
      return function (cb) {
        glob(pattern, {
          cwd: opts.cwd || process.cwd(),
          nodir: true
        }, cb)
      }
    }), function (err, results) {
      if (err) return error(err)

      // flatten nested arrays
      var files = results.reduce(function (files, result) {
        result.forEach(function (file) {
          files.push(file)
        })
        return files
      }, [])

      // apply ignore patterns
      files = files.filter(function (file) {
        return !ignore.some(function (mm) {
          return mm.match(file)
        })
      })

      // de-dupe
      files = uniq(files)
      if (files.length > 0) {
        jscsArgs = jscsArgs.concat(files)
        eslintArgs = eslintArgs.concat(files)
        lint()
      }
    })
  } else {
    // stdin
    eslintArgs.push('--stdin')
    lint()
  }

  function lint () {
    findBinPaths(function (err, paths) {
      if (err) return error(err)
      parallel([
        spawn.bind(undefined, paths.jscs, jscsArgs),
        spawn.bind(undefined, paths.eslint, eslintArgs)
      ], function (err, r) {
        if (err) return error(err)
        if (r.some(Boolean)) printErrors()
      })
    })
  }

  function findBinPaths (cb) {
    parallel({
      eslint: findBinPath.bind(undefined, 'eslint'),
      jscs: findBinPath.bind(undefined, 'jscs')
    }, cb)
  }

  function findBinPath (bin, cb) {
    var opts = { cwd: __dirname }
    cp.exec('npm run --silent which-' + bin, opts, function (err, stdout, stderr) {
      if (err) return cb(err)
      cb(null, stdout.toString().replace(/\n/g, ''))
    })
  }

  function spawn (command, args, cb) {
    var child = cp.spawn(command, args)
    child.on('error', cb)
    child.on('close', function (code) {
      cb(null, code)
    })
    if (opts.stdin) process.stdin.pipe(child.stdin)
    stderrPipe(child.stdout)
    stderrPipe(child.stderr)
  }

  function stderrPipe (readable) {
    readable
      .pipe(split())
      .on('data', function (line) {
        if (line === '') return
        errors.push(line)
      })
  }

  function printErrors () {
    if (opts.bare) {
      errors.forEach(function (str) {
        console.error(str)
      })
      return
    }

    console.error('Error: Code style check failed:')
    var unexpectedOutput = []
    var errMap = {}
    errors
      .map(function (str) { // normalize stdin "filename"
        return str.replace(/^(<text>|input)/, 'stdin')
      })
      .filter(function (str) {
        // don't process unexpected/malformed output, just print it at the end
        if (!ERROR_RE.test(str)) {
          unexpectedOutput.push(str)
          return false
        }

        // de-duplicate errors
        if (errMap[str]) return false
        errMap[str] = true
        return true
      })
      .sort(function (a, b) {
        // sort by line number (merges output from all linters)
        var fileA = FILE_RE.exec(a)[1]
        var fileB = FILE_RE.exec(b)[1]

        var lineA = Number(LINE_RE.exec(a)[1])
        var lineB = Number(LINE_RE.exec(b)[1])

        var colA = Number(COL_RE.exec(a)[1])
        var colB = Number(COL_RE.exec(b)[1])

        if (fileA !== fileB) return fileA < fileB ? -1 : 1
        if (lineA !== lineB) return lineA - lineB
        return colA - colB
      })
      .forEach(function (str) {
        console.error('  ' + str) // indent
      })

    if (unexpectedOutput.length) console.error('\nUnexpected Linter Output:')
    unexpectedOutput.forEach(function (str) {
      console.error(str)
    })

    process.exit(1)
  }
}

function error (err) {
  console.error(err.stack || err.message || err)
  process.exit(1)
}
<|endoftext|>


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

module.exports = {
  name: 'ember-cli-respond',
  contentFor: function(type, config) {
    if (type === 'head-footer') {
        var output = '<script src="' + config.respond.externalUrl + 'ember-cli-respond/respond.min.js"></script>';
        if (typeof config.respond !== 'undefined' && config.respond.proxy === true) {
            output += '<link href="' + config.respond.externalUrl + '/ember-cli-respond/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />' +
            '<link href="' + config.respond.externalUrl + 'ember-cli-respond/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />' +
            '<script src="' + config.respond.externalUrl + 'ember-cli-respond/respond.proxy.js"></script>';
        }
        return output;
    }
  }
};
<commit_msg>Remove extra forward slash<commit_after>/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-cli-respond',
  contentFor: function(type, config) {
    if (type === 'head-footer') {
        var output = '<script src="' + config.respond.externalUrl + 'ember-cli-respond/respond.min.js"></script>';
        if (typeof config.respond !== 'undefined' && config.respond.proxy === true) {
            output += '<link href="' + config.respond.externalUrl + 'ember-cli-respond/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />' +
            '<link href="' + config.respond.externalUrl + 'ember-cli-respond/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />' +
            '<script src="' + config.respond.externalUrl + 'ember-cli-respond/respond.proxy.js"></script>';
        }
        return output;
    }
  }
};
<|endoftext|>


<commit_before>/* eslint-env node */
/** global: Buffer */
'use strict';

const gutil = require('gulp-util');
const through = require('through2');
const wpPot = require('wp-pot');

const PluginError = gutil.PluginError;

/**
 * Determine if `obj` is a object or not.
 *
 * @param  {object}  obj
 *
 * @return {boolean}
 */
function isObject (obj) {
  return Object.prototype.toString.call(obj) === '[object Object]';
}

/**
 * Run the wp pot generator.
 *
 * @param  {object} options
 *
 * @return {object}
 */
function gulpWPpot (options) {
  if (options !== undefined && !isObject(options)) {
    throw new PluginError('gulp-wp-pot', 'Require a argument of type object.');
  }

  let files = [];

  const stream = through.obj(function (file, enc, cb) {
    if (file.isStream()) {
      throw new PluginError('gulp-wp-pot', 'Streams are not supported.');
    }

    files.push(file.path);
    cb();
  }, function (cb) {
    if (!options) {
      options = {};
    }

    options.src = files;
    options.writeFile = false;

    const potContents = wpPot(options);

    const potFile = new gutil.File({
      contents: new Buffer(potContents)
    });

    this.push(potFile);
    cb();
  });

  return stream;
}

module.exports = gulpWPpot;
<commit_msg>Fix broken path for destination<commit_after>/* eslint-env node */
/** global: Buffer */
'use strict';

const gutil = require('gulp-util');
const through = require('through2');
const wpPot = require('wp-pot');

const PluginError = gutil.PluginError;

/**
 * Determine if `obj` is a object or not.
 *
 * @param  {object}  obj
 *
 * @return {boolean}
 */
function isObject (obj) {
  return Object.prototype.toString.call(obj) === '[object Object]';
}

/**
 * Run the wp pot generator.
 *
 * @param  {object} options
 *
 * @return {object}
 */
function gulpWPpot (options) {
  if (options !== undefined && !isObject(options)) {
    throw new PluginError('gulp-wp-pot', 'Require a argument of type object.');
  }

  let files = [];

  const stream = through.obj(function (file, enc, cb) {
    if (file.isStream()) {
      throw new PluginError('gulp-wp-pot', 'Streams are not supported.');
    }

    files.push(file.path);
    cb();
  }, function (cb) {
    if (!options) {
      options = {};
    }

    options.src = files;
    options.writeFile = false;

    const potContents = wpPot(options);

    const potFile = new gutil.File({
      contents: new Buffer(potContents),
      path: '.'
    });

    this.push(potFile);
    cb();
  });

  return stream;
}

module.exports = gulpWPpot;
<|endoftext|>


<commit_before>'use strict';
var through = require('through2'),
	uglify = require('uglify-js'),
	merge = require('deepmerge'),
	PluginError = require('gulp-util/lib/PluginError'),
	applySourceMap = require('vinyl-sourcemaps-apply'),
	reSourceMapComment = /\n\/\/# sourceMappingURL=.+?$/,
	pluginName = 'gulp-uglify';

function minify(file, options, cb) {
	var mangled;

	try {
		mangled = uglify.minify(String(file.contents), options);
		mangled.code = new Buffer(mangled.code.replace(reSourceMapComment, ''));
		cb(null, mangled);
	} catch (e) {
		cb(new PluginError(pluginName, e.message || e.msg, {
			fileName: file.path,
			lineNumber: e.line,
			stack: e.stack,
			showStack: false
		}));
	}
}

function setup(opts) {
	var options = merge(opts || {}, {
		fromString: true,
		output: {}
	});

	if (options.preserveComments === 'all') {
		options.output.comments = true;
	} else if (options.preserveComments === 'some') {
		// preserve comments with directives or that start with a bang (!)
		options.output.comments = /^!|@preserve|@license|@cc_on/i;
	} else if (typeof options.preserveComments === 'function') {
		options.output.comments = options.preserveComments;
	}

	return options;
}

module.exports = function(opt) {

	var options = setup(opt);

	function uglify(file, encoding, callback) {
		/*jshint validthis:true */

		if (file.isNull()) {
			return callback(null, file);
		}

		if (file.isStream()) {
			return callback(new PluginError(pluginName, 'Streaming not supported', {
				fileName: file.path,
				showStack: false
			}));
		}

		if (file.sourceMap) {
			options = merge(options, {
				outSourceMap: file.relative,
				inSourceMap: file.sourceMap.mappings !== '' ? file.sourceMap : undefined
			});
		}

		minify(file, options, function(err, mangled) {
			if (err) {
				return callback(err);
			}

			file.contents = mangled.code;

			if (file.sourceMap) {
				applySourceMap(file, mangled.map);
			}

			callback(null, file);
		});
	}

	return through.obj(uglify);
};
<commit_msg>Recreate options for each file.<commit_after>'use strict';
var through = require('through2'),
	uglify = require('uglify-js'),
	merge = require('deepmerge'),
	PluginError = require('gulp-util/lib/PluginError'),
	applySourceMap = require('vinyl-sourcemaps-apply'),
	reSourceMapComment = /\n\/\/# sourceMappingURL=.+?$/,
	pluginName = 'gulp-uglify';

function minify(file, options, cb) {
	var mangled;

	try {
		mangled = uglify.minify(String(file.contents), options);
		mangled.code = new Buffer(mangled.code.replace(reSourceMapComment, ''));
		cb(null, mangled);
	} catch (e) {
		cb(new PluginError(pluginName, e.message || e.msg, {
			fileName: file.path,
			lineNumber: e.line,
			stack: e.stack,
			showStack: false
		}));
	}
}

function setup(opts) {
	var options = merge(opts || {}, {
		fromString: true,
		output: {}
	});

	if (options.preserveComments === 'all') {
		options.output.comments = true;
	} else if (options.preserveComments === 'some') {
		// preserve comments with directives or that start with a bang (!)
		options.output.comments = /^!|@preserve|@license|@cc_on/i;
	} else if (typeof options.preserveComments === 'function') {
		options.output.comments = options.preserveComments;
	}

	return options;
}

module.exports = function(opt) {

	function uglify(file, encoding, callback) {
		/*jshint validthis:true */

		var options = setup(opt);

		if (file.isNull()) {
			return callback(null, file);
		}

		if (file.isStream()) {
			return callback(new PluginError(pluginName, 'Streaming not supported', {
				fileName: file.path,
				showStack: false
			}));
		}

		if (file.sourceMap) {
			options = merge(options, {
				outSourceMap: file.relative,
				inSourceMap: file.sourceMap.mappings !== '' ? file.sourceMap : undefined
			});
		}

		minify(file, options, function(err, mangled) {
			if (err) {
				return callback(err);
			}

			file.contents = mangled.code;

			if (file.sourceMap) {
				applySourceMap(file, mangled.map);
			}

			callback(null, file);
		});
	}

	return through.obj(uglify);
};
<|endoftext|>


<commit_before>var normalize = require('./normalize')
var createVAO = require('gl-vao')

module.exports = GLGeometry

function GLGeometry(gl) {
  if (!(this instanceof GLGeometry))
    return new GLGeometry(gl)

  this._attributes = []
  this._dirty = true
  this._length = 0
  this._index = null
  this._vao = null
  this._keys = []
  this.gl = gl
}

GLGeometry.prototype.dispose = function() {
  for (var i = 0; i < this._attributes.length; i++) {
    this._attributes[i].buffer.dispose()
  }

  this._attributes = []

  if (this._index) {
    this._index.dispose()
    this._index = null
  }

  if (this._vao) {
    this._vao.dispose()
    this._vao = null
  }
}

GLGeometry.prototype.faces = function faces(attr, opts) {
  var size = opts && opts.size || 3
  attr = attr.cells ? attr.cells : attr

  this._dirty = true

  if (this._index) {
    this._index.dispose()
  }

  this._index = normalize(this.gl
    , attr
    , size
    , this.gl.ELEMENT_ARRAY_BUFFER
    , 'uint16'
  )

  this._length = this._index.length * size
  this._index = this._index.buffer

  return this
}

GLGeometry.prototype.attr = function attr(name, attr, opts) {
  opts = opts || {}
  this._dirty = true

  var gl = this.gl
  var first = !this._attributes.length
  var size = opts.size || 3

  var attribute = normalize(gl, attr, size, gl.ARRAY_BUFFER, 'float32')
  if (!attribute) {
    throw new Error(
        'Unexpected attribute format: needs an ndarray, array, typed array, '
      + 'gl-buffer or simplicial complex'
    )
  }

  var buffer = attribute.buffer
  var length = attribute.length
  var index  = attribute.index

  this._keys.push(name)
  this._attributes.push({
      size: size
    , buffer: buffer
  })

  if (first) {
    this._length = length
  }

  if (first && index) {
    this._index = index
  }

  return this
}

GLGeometry.prototype.bind = function bind(shader) {
  this.update()
  this._vao.bind()

  if (!shader) return
  shader.bind()

  if (!this._keys) return
  for (var i = 0; i < this._keys.length; i++) {
    var attr = shader.attributes[this._keys[i]]
    if (attr) attr.location = i
  }
}

GLGeometry.prototype.draw = function draw(mode) {
  this.update()
  this._vao.draw(mode || this.gl.TRIANGLES, this._length)
}

GLGeometry.prototype.unbind = function unbind() {
  this.update()
  this._vao.unbind()
}

GLGeometry.prototype.update = function update() {
  if (!this._dirty) return
  this._dirty = false
  if (this._vao) this._vao.dispose()

  this._vao = createVAO(
      this.gl
    , this._attributes
    , this._index
  )
}
<commit_msg>enable GLGeometry.prototype.draw to draw gl.POINTS<commit_after>var normalize = require('./normalize')
var createVAO = require('gl-vao')

module.exports = GLGeometry

function GLGeometry(gl) {
  if (!(this instanceof GLGeometry))
    return new GLGeometry(gl)

  this._attributes = []
  this._dirty = true
  this._length = 0
  this._index = null
  this._vao = null
  this._keys = []
  this.gl = gl
}

GLGeometry.prototype.dispose = function() {
  for (var i = 0; i < this._attributes.length; i++) {
    this._attributes[i].buffer.dispose()
  }

  this._attributes = []

  if (this._index) {
    this._index.dispose()
    this._index = null
  }

  if (this._vao) {
    this._vao.dispose()
    this._vao = null
  }
}

GLGeometry.prototype.faces = function faces(attr, opts) {
  var size = opts && opts.size || 3
  attr = attr.cells ? attr.cells : attr

  this._dirty = true

  if (this._index) {
    this._index.dispose()
  }

  this._index = normalize(this.gl
    , attr
    , size
    , this.gl.ELEMENT_ARRAY_BUFFER
    , 'uint16'
  )

  this._length = this._index.length * size
  this._index = this._index.buffer

  return this
}

GLGeometry.prototype.attr = function attr(name, attr, opts) {
  opts = opts || {}
  this._dirty = true

  var gl = this.gl
  var first = !this._attributes.length
  var size = opts.size || 3

  var attribute = normalize(gl, attr, size, gl.ARRAY_BUFFER, 'float32')
  if (!attribute) {
    throw new Error(
        'Unexpected attribute format: needs an ndarray, array, typed array, '
      + 'gl-buffer or simplicial complex'
    )
  }

  var buffer = attribute.buffer
  var length = attribute.length
  var index  = attribute.index

  this._keys.push(name)
  this._attributes.push({
      size: size
    , buffer: buffer
  })

  if (first) {
    this._length = length
  }

  if (first && index) {
    this._index = index
  }

  return this
}

GLGeometry.prototype.bind = function bind(shader) {
  this.update()
  this._vao.bind()

  if (!shader) return
  shader.bind()

  if (!this._keys) return
  for (var i = 0; i < this._keys.length; i++) {
    var attr = shader.attributes[this._keys[i]]
    if (attr) attr.location = i
  }
}

GLGeometry.prototype.draw = function draw(mode) {
  this.update()
  if(mode === undefnied) {
    mode = this.gl.TRIANGLES
  }
  this._vao.draw(mode, this._length)
}

GLGeometry.prototype.unbind = function unbind() {
  this.update()
  this._vao.unbind()
}

GLGeometry.prototype.update = function update() {
  if (!this._dirty) return
  this._dirty = false
  if (this._vao) this._vao.dispose()

  this._vao = createVAO(
      this.gl
    , this._attributes
    , this._index
  )
}
<|endoftext|>


<commit_before>'use strict'

/*
  Node type
    static: 0,
    param: 1,
    matchAll: 2,
    regex: 3

  Char codes:
    '/': 47
    ':': 58
    '*': 42
    '?': 63
    '#': 35
*/

const assert = require('assert')
const Node = require('./node')
const httpMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS', 'TRACE', 'CONNECT']
var errored = false

function Router (opts) {
  if (!(this instanceof Router)) {
    return new Router(opts)
  }
  opts = opts || {}

  if (opts.defaultRoute) {
    assert.equal(typeof opts.defaultRoute, 'function', 'The default route must be a function')
    this.defaultRoute = opts.defaultRoute
  }

  this.tree = new Node()
}

Router.prototype.on = function (method, path, handler, store) {
  assert.equal(typeof method, 'string', 'Method should be a string')
  assert.equal(typeof path, 'string', 'Path should be a string')
  assert.equal(typeof handler, 'function', 'Handler should be a function')
  assert.notEqual(httpMethods.indexOf(method), -1, `Method '${method}' is not an http method.`)

  const params = []
  var j = 0

  for (var i = 0, len = path.length; i < len; i++) {
    // search for parametric or wildcard routes
    // parametric route
    if (path.charCodeAt(i) === 58) {
      j = i + 1
      this._insert(method, path.slice(0, i), 0, null, null, null)

      // isolate the parameter name
      while (i < len && path.charCodeAt(i) !== 47) i++
      var parameter = path.slice(j, i)
      var isRegex = parameter.indexOf('(') > -1
      var regex = isRegex ? parameter.slice(parameter.indexOf('('), i) : null
      if (isRegex) regex = new RegExp(regex)
      params.push(parameter.slice(0, isRegex ? parameter.indexOf('(') : i))

      path = path.slice(0, j) + path.slice(i)
      i = j
      len = path.length

      // if the path is ended
      if (i === len) {
        return this._insert(method, path.slice(0, i), regex ? 3 : 1, params, handler, store, regex)
      }
      this._insert(method, path.slice(0, i), regex ? 3 : 1, params, null, null, regex)

    // wildcard route
    } else if (path.charCodeAt(i) === 42) {
      this._insert(method, path.slice(0, i), 0, null, null, null)
      params.push('*')
      return this._insert(method, path.slice(0, len), 2, params, handler, store)
    }
  }
  // static route
  this._insert(method, path, 0, params, handler, store)
}

Router.prototype._insert = function (method, path, kind, params, handler, store, regex) {
  var prefix = ''
  var pathLen = 0
  var prefixLen = 0
  var len = 0
  var max = 0
  var node = null
  var currentNode = this.tree

  while (true) {
    prefix = currentNode.prefix
    prefixLen = prefix.length
    pathLen = path.length
    len = 0

    // search for the longest common prefix
    max = pathLen < prefixLen ? pathLen : prefixLen
    while (len < max && path[len] === prefix[len]) len++

    if (len < prefixLen) {
      // split the node in the radix tree and add it to the parent
      node = new Node(prefix.slice(len), currentNode.children, currentNode.kind, currentNode.map, currentNode.regex)

      // reset the parent
      currentNode.children = [node]
      currentNode.numberOfChildren = 1
      currentNode.prefix = prefix.slice(0, len)
      currentNode.label = currentNode.prefix[0]
      currentNode.map = null
      currentNode.kind = 0
      currentNode.regex = null

      if (len === pathLen) {
        // add the handler to the parent node
        assert(!currentNode.getHandler(method), `Method '${method}' already declared for route '${path}'`)
        currentNode.setHandler(method, handler, params, store)
        currentNode.kind = kind
      } else {
        // create a child node and add an handler to it
        node = new Node(path.slice(len), [], kind, null, regex)
        node.setHandler(method, handler, params, store)
        // add the child to the parent
        currentNode.add(node)
      }
    } else if (len < pathLen) {
      path = path.slice(len)
      node = currentNode.findByLabel(path[0])
      if (node) {
        // we must go deeper in the tree
        currentNode = node
        continue
      }
      // create a new child node
      node = new Node(path, [], kind, null, regex)
      node.setHandler(method, handler, params, store)
      // add the child to the parent
      currentNode.add(node)
    } else if (handler) {
      // the node already exist
      assert(!currentNode.getHandler(method), `Method '${method}' already declared for route '${path}'`)
      currentNode.setHandler(method, handler, params, store)
    }
    return
  }
}

Router.prototype.lookup = function (req, res) {
  var handle = this.find(req.method, sanitizeUrl(req.url))
  if (!handle) return this._defaultRoute(req, res)
  return handle.handler(req, res, handle.params, handle.store)
}

Router.prototype.find = function (method, path) {
  var currentNode = this.tree
  var node = null
  var kind = 0
  var decoded = null
  var pindex = 0
  var params = []
  var pathLen = 0
  var prefix = ''
  var prefixLen = 0
  var len = 0
  var i = 0

  while (true) {
    pathLen = path.length
    prefix = currentNode.prefix
    prefixLen = prefix.length
    len = 0

    // found the route
    if (pathLen === 0 || path === prefix) {
      var handle = currentNode.getHandler(method)
      if (!handle) return null

      var paramNames = handle.params
      var paramsObj = {}

      for (i = 0; i < paramNames.length; i++) {
        paramsObj[paramNames[i]] = params[i]
      }

      return {
        handler: handle.handler,
        params: paramsObj,
        store: handle.store
      }
    }

    // search for the longest common prefix
    i = pathLen < prefixLen ? pathLen : prefixLen
    while (len < i && path[len] === prefix[len]) len++

    if (len === prefixLen) {
      path = path.slice(len)
      pathLen = path.length
    }

    node = currentNode.find(path[0])
    if (!node) return null
    kind = node.kind

    // static route
    if (kind === 0) {
      currentNode = node
      continue
    }

    if (len !== prefixLen) return null

    // parametric route
    if (kind === 1) {
      currentNode = node
      i = 0
      while (i < pathLen && path.charCodeAt(i) !== 47) i++
      decoded = fastDecode(path.slice(0, i))
      if (errored) {
        return null
      }
      params[pindex++] = decoded
      path = path.slice(i)
      continue
    }

    // wildcard route
    if (kind === 2) {
      decoded = fastDecode(path)
      if (errored) {
        return null
      }
      params[pindex] = decoded
      currentNode = node
      path = ''
      continue
    }

    // parametric(regex) route
    if (kind === 3) {
      currentNode = node
      i = 0
      while (i < pathLen && path.charCodeAt(i) !== 47) i++
      decoded = fastDecode(path.slice(0, i))
      if (errored) {
        return null
      }
      if (!node.regex.test(decoded)) return
      params[pindex++] = decoded
      path = path.slice(i)
      continue
    }

    // route not found
    if (len !== prefixLen) return null
  }
}

Router.prototype._defaultRoute = function (req, res) {
  if (this.defaultRoute) {
    this.defaultRoute(req, res)
  } else {
    res.statusCode = 404
    res.end()
  }
}

Router.prototype.prettyPrint = function () {
  return this.tree.prettyPrint('', true)
}

Router.prototype.get = function (path, handler, store) {
  return this.on('GET', path, handler, store)
}

Router.prototype.delete = function (path, handler, store) {
  return this.on('DELETE', path, handler, store)
}

Router.prototype.head = function (path, handler, store) {
  return this.on('HEAD', path, handler, store)
}

Router.prototype.patch = function (path, handler, store) {
  return this.on('PATCH', path, handler, store)
}

Router.prototype.post = function (path, handler, store) {
  return this.on('POST', path, handler, store)
}

Router.prototype.put = function (path, handler, store) {
  return this.on('PUT', path, handler, store)
}

Router.prototype.options = function (path, handler, store) {
  return this.on('OPTIONS', path, handler, store)
}

Router.prototype.trace = function (path, handler, store) {
  return this.on('TRACE', path, handler, store)
}

Router.prototype.connect = function (path, handler, store) {
  return this.on('CONNECT', path, handler, store)
}

module.exports = Router

function sanitizeUrl (url) {
  for (var i = 0, len = url.length; i < len; i++) {
    var charCode = url.charCodeAt(i)
    if (charCode === 63 || charCode === 35) {
      return url.slice(0, i)
    }
  }
  return url
}

function fastDecode (path) {
  errored = false
  try {
    return decodeURIComponent(path)
  } catch (err) {
    errored = true
  }
}
<commit_msg>Added support for #23<commit_after>'use strict'

/*
  Node type
    static: 0,
    param: 1,
    matchAll: 2,
    regex: 3

  Char codes:
    '/': 47
    ':': 58
    '*': 42
    '?': 63
    '#': 35
*/

const assert = require('assert')
const Node = require('./node')
const httpMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS', 'TRACE', 'CONNECT']
var errored = false

function Router (opts) {
  if (!(this instanceof Router)) {
    return new Router(opts)
  }
  opts = opts || {}

  if (opts.defaultRoute) {
    assert.equal(typeof opts.defaultRoute, 'function', 'The default route must be a function')
    this.defaultRoute = opts.defaultRoute
  }

  this.tree = new Node()
}

Router.prototype.on = function (method, path, handler, store) {
  if (Array.isArray(method)) {
    for (var k = 0; k < method.length; k++) {
      this.on(method[k], path, handler, store)
    }
    return
  }

  assert.equal(typeof method, 'string', 'Method should be a string')
  assert.equal(typeof path, 'string', 'Path should be a string')
  assert.equal(typeof handler, 'function', 'Handler should be a function')
  assert.notEqual(httpMethods.indexOf(method), -1, `Method '${method}' is not an http method.`)

  const params = []
  var j = 0

  for (var i = 0, len = path.length; i < len; i++) {
    // search for parametric or wildcard routes
    // parametric route
    if (path.charCodeAt(i) === 58) {
      j = i + 1
      this._insert(method, path.slice(0, i), 0, null, null, null)

      // isolate the parameter name
      while (i < len && path.charCodeAt(i) !== 47) i++
      var parameter = path.slice(j, i)
      var isRegex = parameter.indexOf('(') > -1
      var regex = isRegex ? parameter.slice(parameter.indexOf('('), i) : null
      if (isRegex) regex = new RegExp(regex)
      params.push(parameter.slice(0, isRegex ? parameter.indexOf('(') : i))

      path = path.slice(0, j) + path.slice(i)
      i = j
      len = path.length

      // if the path is ended
      if (i === len) {
        return this._insert(method, path.slice(0, i), regex ? 3 : 1, params, handler, store, regex)
      }
      this._insert(method, path.slice(0, i), regex ? 3 : 1, params, null, null, regex)

    // wildcard route
    } else if (path.charCodeAt(i) === 42) {
      this._insert(method, path.slice(0, i), 0, null, null, null)
      params.push('*')
      return this._insert(method, path.slice(0, len), 2, params, handler, store)
    }
  }
  // static route
  this._insert(method, path, 0, params, handler, store)
}

Router.prototype._insert = function (method, path, kind, params, handler, store, regex) {
  var prefix = ''
  var pathLen = 0
  var prefixLen = 0
  var len = 0
  var max = 0
  var node = null
  var currentNode = this.tree

  while (true) {
    prefix = currentNode.prefix
    prefixLen = prefix.length
    pathLen = path.length
    len = 0

    // search for the longest common prefix
    max = pathLen < prefixLen ? pathLen : prefixLen
    while (len < max && path[len] === prefix[len]) len++

    if (len < prefixLen) {
      // split the node in the radix tree and add it to the parent
      node = new Node(prefix.slice(len), currentNode.children, currentNode.kind, currentNode.map, currentNode.regex)

      // reset the parent
      currentNode.children = [node]
      currentNode.numberOfChildren = 1
      currentNode.prefix = prefix.slice(0, len)
      currentNode.label = currentNode.prefix[0]
      currentNode.map = null
      currentNode.kind = 0
      currentNode.regex = null

      if (len === pathLen) {
        // add the handler to the parent node
        assert(!currentNode.getHandler(method), `Method '${method}' already declared for route '${path}'`)
        currentNode.setHandler(method, handler, params, store)
        currentNode.kind = kind
      } else {
        // create a child node and add an handler to it
        node = new Node(path.slice(len), [], kind, null, regex)
        node.setHandler(method, handler, params, store)
        // add the child to the parent
        currentNode.add(node)
      }
    } else if (len < pathLen) {
      path = path.slice(len)
      node = currentNode.findByLabel(path[0])
      if (node) {
        // we must go deeper in the tree
        currentNode = node
        continue
      }
      // create a new child node
      node = new Node(path, [], kind, null, regex)
      node.setHandler(method, handler, params, store)
      // add the child to the parent
      currentNode.add(node)
    } else if (handler) {
      // the node already exist
      assert(!currentNode.getHandler(method), `Method '${method}' already declared for route '${path}'`)
      currentNode.setHandler(method, handler, params, store)
    }
    return
  }
}

Router.prototype.lookup = function (req, res) {
  var handle = this.find(req.method, sanitizeUrl(req.url))
  if (!handle) return this._defaultRoute(req, res)
  return handle.handler(req, res, handle.params, handle.store)
}

Router.prototype.find = function (method, path) {
  var currentNode = this.tree
  var node = null
  var kind = 0
  var decoded = null
  var pindex = 0
  var params = []
  var pathLen = 0
  var prefix = ''
  var prefixLen = 0
  var len = 0
  var i = 0

  while (true) {
    pathLen = path.length
    prefix = currentNode.prefix
    prefixLen = prefix.length
    len = 0

    // found the route
    if (pathLen === 0 || path === prefix) {
      var handle = currentNode.getHandler(method)
      if (!handle) return null

      var paramNames = handle.params
      var paramsObj = {}

      for (i = 0; i < paramNames.length; i++) {
        paramsObj[paramNames[i]] = params[i]
      }

      return {
        handler: handle.handler,
        params: paramsObj,
        store: handle.store
      }
    }

    // search for the longest common prefix
    i = pathLen < prefixLen ? pathLen : prefixLen
    while (len < i && path[len] === prefix[len]) len++

    if (len === prefixLen) {
      path = path.slice(len)
      pathLen = path.length
    }

    node = currentNode.find(path[0])
    if (!node) return null
    kind = node.kind

    // static route
    if (kind === 0) {
      currentNode = node
      continue
    }

    if (len !== prefixLen) return null

    // parametric route
    if (kind === 1) {
      currentNode = node
      i = 0
      while (i < pathLen && path.charCodeAt(i) !== 47) i++
      decoded = fastDecode(path.slice(0, i))
      if (errored) {
        return null
      }
      params[pindex++] = decoded
      path = path.slice(i)
      continue
    }

    // wildcard route
    if (kind === 2) {
      decoded = fastDecode(path)
      if (errored) {
        return null
      }
      params[pindex] = decoded
      currentNode = node
      path = ''
      continue
    }

    // parametric(regex) route
    if (kind === 3) {
      currentNode = node
      i = 0
      while (i < pathLen && path.charCodeAt(i) !== 47) i++
      decoded = fastDecode(path.slice(0, i))
      if (errored) {
        return null
      }
      if (!node.regex.test(decoded)) return
      params[pindex++] = decoded
      path = path.slice(i)
      continue
    }

    // route not found
    if (len !== prefixLen) return null
  }
}

Router.prototype._defaultRoute = function (req, res) {
  if (this.defaultRoute) {
    this.defaultRoute(req, res)
  } else {
    res.statusCode = 404
    res.end()
  }
}

Router.prototype.prettyPrint = function () {
  return this.tree.prettyPrint('', true)
}

Router.prototype.get = function (path, handler, store) {
  return this.on('GET', path, handler, store)
}

Router.prototype.delete = function (path, handler, store) {
  return this.on('DELETE', path, handler, store)
}

Router.prototype.head = function (path, handler, store) {
  return this.on('HEAD', path, handler, store)
}

Router.prototype.patch = function (path, handler, store) {
  return this.on('PATCH', path, handler, store)
}

Router.prototype.post = function (path, handler, store) {
  return this.on('POST', path, handler, store)
}

Router.prototype.put = function (path, handler, store) {
  return this.on('PUT', path, handler, store)
}

Router.prototype.options = function (path, handler, store) {
  return this.on('OPTIONS', path, handler, store)
}

Router.prototype.trace = function (path, handler, store) {
  return this.on('TRACE', path, handler, store)
}

Router.prototype.connect = function (path, handler, store) {
  return this.on('CONNECT', path, handler, store)
}

Router.prototype.all = function (path, handler, store) {
  this.on(httpMethods, path, handler, store)
}

module.exports = Router

function sanitizeUrl (url) {
  for (var i = 0, len = url.length; i < len; i++) {
    var charCode = url.charCodeAt(i)
    if (charCode === 63 || charCode === 35) {
      return url.slice(0, i)
    }
  }
  return url
}

function fastDecode (path) {
  errored = false
  try {
    return decodeURIComponent(path)
  } catch (err) {
    errored = true
  }
}
<|endoftext|>


<commit_before>var pull     = require('pull-stream')
var toPull   = require('stream-to-pull-stream')
var pushable = require('pull-pushable')
var cat      = require('pull-cat')
var window   = require('pull-window')
var fixRange = require('level-fix-range')
var post     = require('level-post')

function read(db, opts) {
  return toPull(db.createReadStream(fixRange(opts)))
}

var live =
exports.live =
function (db, opts) {
  opts = opts || {}
  fixRange(opts)

  var l = pushable()

  var cleanup = post(db, opts, function (ch) {
    l.push(ch)
  })

  return l.pipe(pull.through(null, cleanup))

}

exports.read =
exports.readStream =
exports.createReadStream = function (db, opts) {
  opts = opts || {}
  fixRange(opts)
  if(!opts.tail)
    return read(db, opts)

  //optionally notify when we switch from reading history to realtime
  var sync = opts.onSync && function (abort, cb) {
      opts.onSync(); cb(true)
    }

  return cat([read(db, opts), sync, live(db, opts)])
}

exports.write =
exports.writeStream =
exports.createWriteStream = function (db, opts, done) {
  if('function' === typeof opts)
    done = opts, opts = null
  opts = opts || {}
  return pull.map(function (e) {
    if(e.type) return e
    return {
      key   : e.key,
      value : e.value,
      type  : e.value == null ? 'del' : 'put'
    }
  })
  .pipe(window(opts.windowSize, opts.windowTime))
  .pipe(pull.asyncMap(function (batch, cb) {
    db.batch(batch, cb)
  }))
  .pipe(pull.onEnd(done))
}

<commit_msg>update pull api<commit_after>var pull     = require('pull-stream')
var toPull   = require('stream-to-pull-stream')
var pushable = require('pull-pushable')
var cat      = require('pull-cat')
var pw       = require('pull-window')
var fixRange = require('level-fix-range')
var post     = require('level-post')

function read(db, opts) {
  return toPull(db.createReadStream(fixRange(opts)))
}

var live =
exports.live =
function (db, opts) {
  opts = opts || {}
  fixRange(opts)

  var l = pushable()

  var cleanup = post(db, opts, function (ch) {
    console.log('post!', ch)
    l.push(ch)
  })

  return pull(l, pull.through(null, cleanup))

}

exports.read =
exports.readStream =
exports.createReadStream = function (db, opts) {
  opts = opts || {}
  fixRange(opts)
  if(!opts.tail)
    return read(db, opts)

  //optionally notify when we switch from reading history to realtime
  var sync = opts.onSync && function (abort, cb) {
      opts.onSync(abort); cb(abort || true)
    }

  return cat([read(db, opts), sync, live(db, opts)])
}

exports.write =
exports.writeStream =
exports.createWriteStream = function (db, opts, done) {
  if('function' === typeof opts)
    done = opts, opts = null
  opts = opts || {}
  return pull(
    pull.map(function (e) {
      if(e.type) return e
      return {
        key   : e.key,
        value : e.value,
        type  : e.value == null ? 'del' : 'put'
      }
    }),
    pw.recent(opts.windowSize, opts.windowTime),
    pull.asyncMap(function (batch, cb) {
      console.log('write batch', batch)
      db.batch(batch, cb)
    }),
    pull.drain(null, done)
  )
}

<|endoftext|>


<commit_before>var net = require('net')
var es  = require('event-stream')

exports.createServer = function (lookup, modify, errback) {
  return net.createServer(exports.handler(lookup, modify, errback))
}

exports.createStickyServer = function (lookup, errback) {
  return net.createServer(exports.handler(function (req) {
    var cookie, sticky, m
    if(cookie = req.headers.Cookie) {
      if(m = /sticky=([\w\d]+)[;$]/.exec(cookie))
       sticky = m[1]
    }
    return lookup(req, sticky)
  }, function (res, dest) {
    var setCookie
    if(setCookie = res.headers['Set-Cookie']) {
      if(!/sticky=[\w\d]+[;$]/.test(setCookie))
       res.headers['Set-Cookie'] = 'sticky='+dest.sticky+'; ' + setCookie
    }
  }, errback))
}

/*
  a sync through stream that matches and replaces only ONCE
  before a pattern.
  the intension is to match the empty line that marks the
  end of the first header.
*/

var replace =
exports.replace = function (match, replace) {
  var soFar = ''
  var matched = false
  return es.through(function (data) {
    if(!matched) {
      soFar += data
      matched = match.exec(soFar)
      if(matched) {
        this.emit('data', replace(soFar.substring(0, matched.index)))
        this.emit('data', soFar.substring(matched.index))
      }
    } else
      this.emit('data', data)
  }, function () {
    if(!matched && soFar)
      this.emit('data', soFar)
    this.emit('end')
  })
}

var parse =
exports.parse = function (header) {
  var lines = header.split('\r\n')
    , first = lines.shift(), headers = {}
  lines.forEach(function (l) {
    var i = l.indexOf(':')
    headers[l.substring(0, i).trim()] = l.substring(i + 1).trim()
  })
  return {first: first, headers: headers}
}

var stringify = exports.stringify = function (header) {
  var r = [header.first]
  for(var h in header.headers)
    r.push(h + ': ' + header.headers[h])
  return r.join('\r\n')
}

exports.handler = function (lookup, modify, errback) {
  return function (con) {
    var first
    con.pipe(first = replace(/\r\n\r\n/, function (header) {
      var req, dest = lookup(req = parse(header))
      var outs =
        first.pipe(
          dest.path ? net.connect(dest.path) : net.connect(dest.port, dest.host)
          .on('error', function (err) { //will this be gc'd?
            if(errback) errback(err, dest)
            else console.error(err)
          })
        )
      if(modify)
        outs = outs.pipe(replace(/\r\n\r\n/, function (header) {
          var res = parse(header)
          modify(res, dest)
          return stringify(res)
        }))

        outs.pipe(con)
        return stringify(req)
    }))
  }
}
<commit_msg>ensure destruction of client connection if server is not up. if errback returns a stream, pipe it to client as error message.<commit_after>var net = require('net')
var es  = require('event-stream')
var Stream = require('stream').Stream

exports.createServer = function (lookup, modify, errback) {
  return net.createServer(exports.handler(lookup, modify, errback))
}

exports.createStickyServer = function (lookup, errback) {
  return net.createServer(exports.handler(function (req) {
    var cookie, sticky, m
    if(cookie = req.headers.Cookie) {
      if(m = /sticky=([\w\d]+)[;$]/.exec(cookie))
       sticky = m[1]
    }
    return lookup(req, sticky)
  }, function (res, dest) {
    var setCookie
    if(setCookie = res.headers['Set-Cookie']) {
      if(!/sticky=[\w\d]+[;$]/.test(setCookie))
       res.headers['Set-Cookie'] = 'sticky='+dest.sticky+'; ' + setCookie
    }
  }, errback))
}

/*
  a sync through stream that matches and replaces only ONCE
  before a pattern.
  the intension is to match the empty line that marks the
  end of the first header.
*/

var replace =
exports.replace = function (match, replace) {
  var soFar = ''
  var matched = false
  return es.through(function (data) {
    if(!matched) {
      soFar += data
      matched = match.exec(soFar)
      if(matched) {
        this.emit('data', replace(soFar.substring(0, matched.index)))
        this.emit('data', soFar.substring(matched.index))
      }
    } else
      this.emit('data', data)
  }, function () {
    if(!matched && soFar)
      this.emit('data', soFar)
    this.emit('end')
  })
}

var parse =
exports.parse = function (header) {
  var lines = header.split('\r\n')
    , first = lines.shift(), headers = {}
  lines.forEach(function (l) {
    var i = l.indexOf(':')
    headers[l.substring(0, i).trim()] = l.substring(i + 1).trim()
  })
  return {first: first, headers: headers}
}

var stringify = exports.stringify = function (header) {
  var r = [header.first]
  for(var h in header.headers)
    r.push(h + ': ' + header.headers[h])
  return r.join('\r\n')
}

exports.handler = function (lookup, modify, errback) {
  return function (con) {
    var first
    con.pipe(first = replace(/\r\n\r\n/, function (header) {
      var req, dest = lookup(req = parse(header))
      var outs =
        first.pipe(
          (dest.path ? net.connect(dest.path) : net.connect(dest.port, dest.host))
          .on('error', function (err) { //will this be gc'd?
            /*
              this only gets called if there is a ECONNREFUSED
              i.e. if there is no server where we've tried to proxy.
              if the server or the client close/crash, it will not produce an error
              but will appear to close normally.

              so: errback means that the server is down.
            */
            var maybe
            if(errback) maybe = errback(err, dest)
            else console.error('server down', err, dest)
            //it would actually be possible to write a propper error response here
            //if errback returns a stream then
            if(maybe instanceof Stream)
              maybe.pipe(con)
            else
              con.destroy()
          })
        )
      if(modify)
        outs = outs.pipe(replace(/\r\n\r\n/, function (header) {
          var res = parse(header)
          modify(res, dest)
          return stringify(res)
        }))

        outs
          .pipe(process.stderr, {end: false})

        outs  .pipe(con)
        return stringify(req)
    }))
  }
}
<|endoftext|>


<commit_before>/**
 * hive.js
 * Copyright (C) 2013-2016 Marcel Klehr <mklehr@gmx.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Mozilla Public License version 2
 * as published by the Mozilla Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the Mozilla Public License
 * along with this program.  If not, see <https://www.mozilla.org/en-US/MPL/2.0/>.
 */
var Primus = require('primus')
  , dataplex = require('dataplex')
  , co = require('co')
  , gulf = require('gulf')
  , through = require('through2')

module.exports = setup
module.exports.consumes = ['hooks','http','sync', 'auth', 'broadcast', 'config']
module.exports.provides = ['interfaceStream']

function setup(plugin, imports, register) {
  var hooks = imports.hooks
    , http = imports.http
    , sync = imports.sync
    , auth = imports.auth
    , broadcast = imports.broadcast
    , config = imports.config

  var primus = new Primus(server, {
    pathname:'/stream'
  , authorization: null
  , parser: 'binary'
  , transformer: config.get('interfaceStream:transport')
  })

  primus.use('client-side-binary-converter', {
    client: function(primus) {
      primus.transform('incoming', function (packet) {
        packet.data = new Buffer(packet.data)
      });

      primus.transform('outgoing', function (packet) {
        // convert node Buffers to Arraybuffers as per
        // https://stackoverflow.com/questions/8609289/convert-a-binary-nodejs-buffer-to-javascript-arraybuffer#12101012
        // var arrayBuffer = new Uint8Array(nodeBuffer).buffer
        packet.data = (new Uint8Array(packet.data)).buffer
      });
    }
  })

  primus.on('connection',function(stream) {
    var plex = dataplex()
    stream.pipe(plex).pipe(stream)

    plex.add('/document/:id/sync', function(opts) {
      // Set up link authorization
      var link = new gulf.Link({
        authenticate: function(credentials, cb) {
          co(function*() {
            return yield auth.authenticate('token', credentials)
          })
          .then((user) => {
            cb(null, user.id)
          })
          .catch(cb)
        }
      , authorizeWrite: function(msg, user, cb) {
          co(function*() {
            if(!plex.user) return false
            var allowed = false
            switch(msg[0]) {
        case 'edit':
          allowed = yield auth.authorize(plex.user, 'document:change', {document: opts.id})
          break;
        case 'ack':
        case 'requestInit':
          allowed = yield auth.authorize(plex.user, 'document:read', {document: opts.id})
          break;
            }
            return allowed
          })
          .then(function(allowed) {
            cb(null, allowed)
          })
          .catch(cb)
        }
      , authorizeRead:function(msg, user, cb) {
          co(function*() {
            if(!plex.user) return false
            var allowed = false
            switch(msg[0]) {
        case 'edit':
          allowed = yield auth.authorize(plex.user, 'document:read', {document: opts.id})
          break;
        case 'ack':
        case 'init':
          allowed = yield auth.authorize(plex.user, 'document:read', {document: opts.id})
          break;
            }
            return allowed
          })
          .then(function(allowed) {
            cb(null, allowed)
          })
          .catch(cb)
        }
      })

      co(function*() {
        // load document and add slave link
        var doc = yield sync.getDocument(opts.id)
        doc.attachSlaveLink(link)
      })
      .then(function() {}, function(er) { console.log(er.stack || er)})

      return link
    })

    plex.add('/document/:id/broadcast', function(opts) {
      var b = broadcast.document(opts.id, plex.user)
      stream.on('end', function() {
        b.emit('close')
      })
      return b
    })

    plex.add('/authenticate', function() {
      return through(function(chunk, enc, cb) {
        var that = this
        co(function*() {
          try {
            plex.user = yield auth.authenticate('token', chunk.toString('utf8'))
            if(plex.user) return that.push(JSON.stringify({authenticated: true}))
          }catch(e) { }
          that.push(JSON.stringify({authenticated: false }))
        })
        .then(cb)
        .catch(cb)
      })
    })

    co(function*() {
      yield hooks.callHook('interface-stream:connect', plex)
    }).then(function() {})
  })

  register(null, {interfaceStream: {primus: primus}})
}
<commit_msg>Use http.server to setup primus<commit_after>/**
 * hive.js
 * Copyright (C) 2013-2016 Marcel Klehr <mklehr@gmx.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Mozilla Public License version 2
 * as published by the Mozilla Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the Mozilla Public License
 * along with this program.  If not, see <https://www.mozilla.org/en-US/MPL/2.0/>.
 */
var Primus = require('primus')
  , dataplex = require('dataplex')
  , co = require('co')
  , gulf = require('gulf')
  , through = require('through2')

module.exports = setup
module.exports.consumes = ['hooks','http','sync', 'auth', 'broadcast', 'config']
module.exports.provides = ['interfaceStream']

function setup(plugin, imports, register) {
  var hooks = imports.hooks
    , http = imports.http
    , sync = imports.sync
    , auth = imports.auth
    , broadcast = imports.broadcast
    , config = imports.config

  var primus = new Primus(http.server, {
    pathname:'/stream'
  , authorization: null
  , parser: 'binary'
  , transformer: config.get('interfaceStream:transport')
  })

  primus.use('client-side-binary-converter', {
    client: function(primus) {
      primus.transform('incoming', function (packet) {
        packet.data = new Buffer(packet.data)
      });

      primus.transform('outgoing', function (packet) {
        // convert node Buffers to Arraybuffers as per
        // https://stackoverflow.com/questions/8609289/convert-a-binary-nodejs-buffer-to-javascript-arraybuffer#12101012
        // var arrayBuffer = new Uint8Array(nodeBuffer).buffer
        packet.data = (new Uint8Array(packet.data)).buffer
      });
    }
  })

  primus.on('connection',function(stream) {
    var plex = dataplex()
    stream.pipe(plex).pipe(stream)

    plex.add('/document/:id/sync', function(opts) {
      // Set up link authorization
      var link = new gulf.Link({
        authenticate: function(credentials, cb) {
          co(function*() {
            return yield auth.authenticate('token', credentials)
          })
          .then((user) => {
            cb(null, user.id)
          })
          .catch(cb)
        }
      , authorizeWrite: function(msg, user, cb) {
          co(function*() {
            if(!plex.user) return false
            var allowed = false
            switch(msg[0]) {
        case 'edit':
          allowed = yield auth.authorize(plex.user, 'document:change', {document: opts.id})
          break;
        case 'ack':
        case 'requestInit':
          allowed = yield auth.authorize(plex.user, 'document:read', {document: opts.id})
          break;
            }
            return allowed
          })
          .then(function(allowed) {
            cb(null, allowed)
          })
          .catch(cb)
        }
      , authorizeRead:function(msg, user, cb) {
          co(function*() {
            if(!plex.user) return false
            var allowed = false
            switch(msg[0]) {
        case 'edit':
          allowed = yield auth.authorize(plex.user, 'document:read', {document: opts.id})
          break;
        case 'ack':
        case 'init':
          allowed = yield auth.authorize(plex.user, 'document:read', {document: opts.id})
          break;
            }
            return allowed
          })
          .then(function(allowed) {
            cb(null, allowed)
          })
          .catch(cb)
        }
      })

      co(function*() {
        // load document and add slave link
        var doc = yield sync.getDocument(opts.id)
        doc.attachSlaveLink(link)
      })
      .then(function() {}, function(er) { console.log(er.stack || er)})

      return link
    })

    plex.add('/document/:id/broadcast', function(opts) {
      var b = broadcast.document(opts.id, plex.user)
      stream.on('end', function() {
        b.emit('close')
      })
      return b
    })

    plex.add('/authenticate', function() {
      return through(function(chunk, enc, cb) {
        var that = this
        co(function*() {
          try {
            plex.user = yield auth.authenticate('token', chunk.toString('utf8'))
            if(plex.user) return that.push(JSON.stringify({authenticated: true}))
          }catch(e) { }
          that.push(JSON.stringify({authenticated: false }))
        })
        .then(cb)
        .catch(cb)
      })
    })

    co(function*() {
      yield hooks.callHook('interface-stream:connect', plex)
    }).then(function() {})
  })

  register(null, {interfaceStream: {primus: primus}})
}
<|endoftext|>


<commit_before>// Requires
var display = require('screen').getPrimaryDisplay();
var superb = require('superb');

var package = require('./package.json');
var wallpaper = require('./lib/wallpaper.js');
var schedule = require('./lib/schedule.js');
var utils = require('./lib/utils.js');

// Variables
var config = {
    version: package.version,
    width: display.size.width,
    height: display.size.height,
    online: null
};

var user = {
    name: null,
    timer: null,
    favorites: [],
    scheduled: [],
    added: []
}

// Functions
function checkAdd(object, id) {
    if(user[object].indexOf(id) === -1) {
        user[object].push(id);

        if(wallpaper.checkWallpaper(id) === false) {
            wallpaper.downloadWallpaper({
                method: 'specific',
                id: id
            });
        }
    }
}

// Binds
$('#menu-schedule').on('click', function() {
    schedule.startSchedule(2, 's');
    console.log('Scheduled: ' + user.scheduled);
});

$('#menu-favorites').on('click', function() {
    console.log('Favorites: ' + user.favorites);
});

$('#menu-settings').on('click', function() {
    console.log('Settings');
});

function bindClicks() {
    $('.action').on('click', function() {
        var id = $(this).parent().parent().attr('data-id');
        switch($(this).data('action')) {
            case 'set':
                if(wallpaper.checkWallpaper(id) === true) {
                    wallpaper.setWallpaper(id);
                } else {
                    wallpaper.downloadWallpaper({
                        method: 'specific',
                        id: id,
                        set: true
                    });
                }
                break;

            case 'add':
                checkAdd('scheduled', id);
                break;

            case 'fav':
                checkAdd('favorites', id);
                break;
        }
    })
}

// Intern
function startApp() {
    document.getElementById('subtitle').innerHTML = ' | ' + superb() + ' wallpapers';
    window.addEventListener('offline',  utils.checkConnection);
    window.addEventListener('online',  utils.checkConnection);
    utils.checkConnection();
    utils.getList();

    $('#schedule').hide();
    $('#settings').hide();
}

startApp();<commit_msg>Added visual aid when add and fav a picture<commit_after>// Requires
var display = require('screen').getPrimaryDisplay();
var superb = require('superb');

var package = require('./package.json');
var wallpaper = require('./lib/wallpaper.js');
var schedule = require('./lib/schedule.js');
var utils = require('./lib/utils.js');

// Variables
var config = {
    version: package.version,
    width: display.size.width,
    height: display.size.height,
    online: null
};

var user = {
    name: null,
    timer: null,
    favorites: [],
    scheduled: [],
    added: []
}

// Functions
function checkAdd(object, id) {
    var index = user[object].indexOf(id);
    if(index === -1) {
        user[object].push(id);

        if(wallpaper.checkWallpaper(id) === false) {
            wallpaper.downloadWallpaper({
                method: 'specific',
                id: id
            });
        }
        // Returns true, element added
        return true;
    }
    // If it's already added, we remove it
    user[object].splice(index, 1);
    // Returns false, element removed
    return false;
}

// Binds
$('#menu-schedule').on('click', function() {
    schedule.startSchedule(2, 's');
    console.log('Scheduled: ' + user.scheduled);
});

$('#menu-favorites').on('click', function() {
    console.log('Favorites: ' + user.favorites);
});

$('#menu-settings').on('click', function() {
    console.log('Settings');
});

function bindClicks() {
    $('.action').on('click', function() {
        var id = $(this).parent().parent().attr('data-id');
        switch($(this).data('action')) {
            case 'set':
                if(wallpaper.checkWallpaper(id) === true) {
                    wallpaper.setWallpaper(id);
                } else {
                    wallpaper.downloadWallpaper({
                        method: 'specific',
                        id: id,
                        set: true
                    });
                }
                break;

            case 'add':
                if(checkAdd('scheduled', id)){
                    $(this).addClass("teal-text");
                }else{
                    $(this).removeClass("teal-text");
                }
                break;

            case 'fav':
                // Toggles a favorite and set icon color
                if(checkAdd('favorites', id)){
                    $(this).addClass("red-text");
                }else{
                    $(this).removeClass("red-text");
                }
                break;
        }
    })
}

// Intern
function startApp() {
    document.getElementById('subtitle').innerHTML = ' | ' + superb() + ' wallpapers';
    window.addEventListener('offline',  utils.checkConnection);
    window.addEventListener('online',  utils.checkConnection);
    utils.checkConnection();
    utils.getList();

    $('#schedule').hide();
    $('#settings').hide();
}

startApp();
<|endoftext|>


<commit_before>'use strict'

const path = require('path')
const fs = require('fs')
const mkdirp = require('mkdirp')
const assign = require('object-assign')
const includePathSearcher = require('include-path-searcher')
const CachingWriter = require('broccoli-caching-writer')
const postcss = require('postcss')

function PostcssCompiler (inputNodes, inputFile, outputFile, options) {
  if (!(this instanceof PostcssCompiler)) {
    return new PostcssCompiler(inputNodes, inputFile, outputFile, options)
  }

  CachingWriter.call(this, Array.isArray(inputNodes) ? inputNodes : [inputNodes], options)

  this.inputFile = inputFile
  this.outputFile = outputFile
  this.warningStream = process.stderr

  this.plugins = options.plugins || []
  this.map = options.map
  this.browsers = options.browsers
  this.parser = options.parser
  this.errors = options.errors || { showSourceCode: true, terminalColors: true }
}

PostcssCompiler.prototype = Object.create(CachingWriter.prototype)
PostcssCompiler.prototype.constructor = PostcssCompiler

PostcssCompiler.prototype.build = function () {
  const toFilePath = `${this.outputPath}/${this.outputFile}`
  const fromFilePath = includePathSearcher.findFileSync(this.inputFile, this.inputPaths)

  if (!this.plugins || this.plugins.length < 1) {
    throw new Error('You must provide at least 1 plugin in the plugin array')
  }

  const processor = postcss()
  const css = fs.readFileSync(fromFilePath, 'utf8')
  const options = {
    from: fromFilePath,
    to: toFilePath,
    map: this.map,
    parser: this.parser,
    browsers: this.browsers
  }
  const showSourceCode = this.errors.showSourceCode
  const terminalColors = this.errors.terminalColors

  this.plugins.forEach((plugin) => {
    let pluginInstance

    if (plugin.module) {
      const pluginOptions = assign(options, plugin.options || {})
      pluginInstance = plugin.module(pluginOptions)
    } else {
      pluginInstance = plugin
    }

    processor.use(pluginInstance)
  })

  return processor.process(css, options)
    .then((result) => {
      result.warnings().forEach(warn => this.warningStream.write(warn.toString()))

      mkdirp.sync(path.dirname(toFilePath))
      fs.writeFileSync(toFilePath, result.css, {
        encoding: 'utf8'
      })

      if (result.map) {
        fs.writeFileSync(`${toFilePath}.map`, result.map, {
          encoding: 'utf8'
        })
      }
    })
    .catch((err) => {
      if (err.name === 'CssSyntaxError') {
        if (showSourceCode) {
          err.message += `\n${err.showSourceCode(terminalColors)}`
        }
      }

      throw err
    })
}

module.exports = PostcssCompiler
<commit_msg>fix missing caching options<commit_after>'use strict'

const path = require('path')
const fs = require('fs')
const mkdirp = require('mkdirp')
const assign = require('object-assign')
const includePathSearcher = require('include-path-searcher')
const CachingWriter = require('broccoli-caching-writer')
const postcss = require('postcss')

function PostcssCompiler (inputNodes, inputFile, outputFile, _options) {
  var options = Object.assign({
    cacheInclude: [/.*\.(js|css)$/]
  }, _options)

  if (!(this instanceof PostcssCompiler)) {
    return new PostcssCompiler(inputNodes, inputFile, outputFile, options)
  }

  CachingWriter.call(this, Array.isArray(inputNodes) ? inputNodes : [inputNodes], options)

  this.inputFile = inputFile
  this.outputFile = outputFile
  this.warningStream = process.stderr

  this.plugins = options.plugins || []
  this.map = options.map
  this.browsers = options.browsers
  this.parser = options.parser
  this.errors = options.errors || { showSourceCode: true, terminalColors: true }
}

PostcssCompiler.prototype = Object.create(CachingWriter.prototype)
PostcssCompiler.prototype.constructor = PostcssCompiler

PostcssCompiler.prototype.build = function () {
  const toFilePath = `${this.outputPath}/${this.outputFile}`
  const fromFilePath = includePathSearcher.findFileSync(this.inputFile, this.inputPaths)

  if (!this.plugins || this.plugins.length < 1) {
    throw new Error('You must provide at least 1 plugin in the plugin array')
  }

  const processor = postcss()
  const css = fs.readFileSync(fromFilePath, 'utf8')
  const options = {
    from: fromFilePath,
    to: toFilePath,
    map: this.map,
    parser: this.parser,
    browsers: this.browsers
  }
  const showSourceCode = this.errors.showSourceCode
  const terminalColors = this.errors.terminalColors

  this.plugins.forEach((plugin) => {
    let pluginInstance

    if (plugin.module) {
      const pluginOptions = assign(options, plugin.options || {})
      pluginInstance = plugin.module(pluginOptions)
    } else {
      pluginInstance = plugin
    }

    processor.use(pluginInstance)
  })

  return processor.process(css, options)
    .then((result) => {
      result.warnings().forEach(warn => this.warningStream.write(warn.toString()))

      mkdirp.sync(path.dirname(toFilePath))
      fs.writeFileSync(toFilePath, result.css, {
        encoding: 'utf8'
      })

      if (result.map) {
        fs.writeFileSync(`${toFilePath}.map`, result.map, {
          encoding: 'utf8'
        })
      }
    })
    .catch((err) => {
      if (err.name === 'CssSyntaxError') {
        if (showSourceCode) {
          err.message += `\n${err.showSourceCode(terminalColors)}`
        }
      }

      throw err
    })
}

module.exports = PostcssCompiler
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';
var path             = require('path');
var Promise          = require('ember-cli/lib/ext/promise');
var DeployPluginBase = require('ember-cli-deploy-plugin');
var S3               = require('./lib/s3');

module.exports = {
  name: 'ember-cli-deploy-s3-index',

  createDeployPlugin: function(options) {
    var DeployPlugin = DeployPluginBase.extend({
      name: options.name,

      defaultConfig: {
        filePattern: 'index.html',
        prefix: '',
        acl: 'public-read',
        distDir: function(context) {
          return context.distDir;
        },
        revisionKey: function(context) {
          var revisionKey = context.revisionData && context.revisionData.revisionKey;
          return context.commandOptions.revision || revisionKey;
        },
        s3Client: function(context) {
          return context.s3Client; // if you want to provide your own S3 client to be used instead of one from aws-sdk
        },
        allowOverwrite: false
      },
      requiredConfig: ['accessKeyId', 'secretAccessKey', 'bucket', 'region'],

      upload: function(context) {
        var bucket         = this.readConfig('bucket');
        var prefix         = this.readConfig('prefix');
        var acl            = this.readConfig('acl');
        var revisionKey    = this.readConfig('revisionKey');
        var distDir        = this.readConfig('distDir');
        var filePattern    = this.readConfig('filePattern');
        var allowOverwrite = this.readConfig('allowOverwrite');
        var filePath    = path.join(distDir, filePattern);

        var options = {
          bucket: bucket,
          prefix: prefix,
          acl: acl,
          filePattern: filePattern,
          filePath: filePath,
          revisionKey: revisionKey,
          allowOverwrite: allowOverwrite
        };

        this.log('preparing to upload revision to S3 bucket `' + bucket + '`', { verbose: true });

        var s3 = new S3({ plugin: this });
        return s3.upload(options);
      },

      activate: function(context) {
        var bucket      = this.readConfig('bucket');
        var prefix      = this.readConfig('prefix');
        var revisionKey = this.readConfig('revisionKey');
        var filePattern = this.readConfig('filePattern');

        var options = {
          bucket: bucket,
          prefix: prefix,
          filePattern: filePattern,
          revisionKey: revisionKey,
        };

        this.log('preparing to activate `' + revisionKey + '`', { verbose: true });

        var s3 = new S3({ plugin: this });
        return s3.activate(options);
      },

      fetchRevisions: function(context) {
        var bucket      = this.readConfig('bucket');
        var prefix      = this.readConfig('prefix');
        var filePattern = this.readConfig('filePattern');

        var options = {
          bucket: bucket,
          prefix: prefix,
          filePattern: filePattern,
        };

        var s3 = new S3({ plugin: this });
        return s3.fetchRevisions(options)
          .then(function(revisions) {
            context.revisions = revisions;
          });
      },
    });

    return new DeployPlugin();
  }
};
<commit_msg>Remove AWS Credentials from required options<commit_after>/* jshint node: true */
'use strict';
var path             = require('path');
var Promise          = require('ember-cli/lib/ext/promise');
var DeployPluginBase = require('ember-cli-deploy-plugin');
var S3               = require('./lib/s3');

module.exports = {
  name: 'ember-cli-deploy-s3-index',

  createDeployPlugin: function(options) {
    var DeployPlugin = DeployPluginBase.extend({
      name: options.name,

      defaultConfig: {
        filePattern: 'index.html',
        prefix: '',
        acl: 'public-read',
        distDir: function(context) {
          return context.distDir;
        },
        revisionKey: function(context) {
          var revisionKey = context.revisionData && context.revisionData.revisionKey;
          return context.commandOptions.revision || revisionKey;
        },
        s3Client: function(context) {
          return context.s3Client; // if you want to provide your own S3 client to be used instead of one from aws-sdk
        },
        allowOverwrite: false
      },
      requiredConfig: ['bucket', 'region'],

      upload: function(context) {
        var bucket         = this.readConfig('bucket');
        var prefix         = this.readConfig('prefix');
        var acl            = this.readConfig('acl');
        var revisionKey    = this.readConfig('revisionKey');
        var distDir        = this.readConfig('distDir');
        var filePattern    = this.readConfig('filePattern');
        var allowOverwrite = this.readConfig('allowOverwrite');
        var filePath    = path.join(distDir, filePattern);

        var options = {
          bucket: bucket,
          prefix: prefix,
          acl: acl,
          filePattern: filePattern,
          filePath: filePath,
          revisionKey: revisionKey,
          allowOverwrite: allowOverwrite
        };

        this.log('preparing to upload revision to S3 bucket `' + bucket + '`', { verbose: true });

        var s3 = new S3({ plugin: this });
        return s3.upload(options);
      },

      activate: function(context) {
        var bucket      = this.readConfig('bucket');
        var prefix      = this.readConfig('prefix');
        var revisionKey = this.readConfig('revisionKey');
        var filePattern = this.readConfig('filePattern');

        var options = {
          bucket: bucket,
          prefix: prefix,
          filePattern: filePattern,
          revisionKey: revisionKey,
        };

        this.log('preparing to activate `' + revisionKey + '`', { verbose: true });

        var s3 = new S3({ plugin: this });
        return s3.activate(options);
      },

      fetchRevisions: function(context) {
        var bucket      = this.readConfig('bucket');
        var prefix      = this.readConfig('prefix');
        var filePattern = this.readConfig('filePattern');

        var options = {
          bucket: bucket,
          prefix: prefix,
          filePattern: filePattern,
        };

        var s3 = new S3({ plugin: this });
        return s3.fetchRevisions(options)
          .then(function(revisions) {
            context.revisions = revisions;
          });
      },
    });

    return new DeployPlugin();
  }
};
<|endoftext|>


<commit_before>var AmpersandModel = require('ampersand-model');
var AmpersandCollection = require('ampersand-rest-collection');
var IndexCollection = require('mongodb-index-model').Collection;
var ns = require('mongodb-ns');
var _ = require('ldodash');

var Collection = AmpersandModel.extend({
  modelType: 'Collection',
  idAttribute: '_id',
  props: {
    _id: {
      type: 'string',
      required: true
    },
    database: 'string',
    document_count: 'number',
    document_size: 'number',
    storage_size: 'number',
    index_count: 'number',
    index_size: 'number',
    padding_factor: 'number',
    extent_count: 'number',
    extent_last_size: 'number',
    /**
     * http://docs.mongodb.org/manual/reference/command/collStats/#collStats.userFlags
     */
    flags_user: 'number',
    flags_system: 'number',
    /**
     * Is this a capped collection?
     */
    capped: {
      type: 'boolean',
      default: false
    },
    /**
     * Is this collection using power of 2 allocation?
     *
     * http://docs.mongodb.org/manual/core/storage/#power-of-2-allocation
     */
    power_of_two: {
      type: 'boolean',
      default: true
    },
    /**
     * The total size in memory of all records in a collection. This value does
     * not include the record header, which is 16 bytes per record, but does
     * include the record’s padding. Additionally size does not include the
     * size of any indexes associated with the collection, which the
     * totalIndexSize field reports..
     *
     * http://docs.mongodb.org/manual/reference/command/collStats/#collStats.size
     */
    size: 'number',
    /**
     * New in version 3.0.0.
     *
     * A document that reports data from the storage engine for each index
     * in the collection.
     *
     * The fields in this document are the names of the indexes, while the
     * values themselves are documents that contain statistics for the index
     * provided by the storage engine. These statistics are for
     * internal diagnostic use.
     *
     * http://docs.mongodb.org/manual/reference/command/collStats/#collStats.indexDetails
     */
    index_details: 'object',
    /**
     * New in version 3.0.0.
     *
     * wiredTiger only appears when using the wiredTiger storage engine. This
     * document contains data reported directly by the WiredTiger engine and
     * other data for internal diagnostic use.
     *
     * http://docs.mongodb.org/manual/reference/command/collStats/#collStats.wiredTiger
     */
    wired_tiger: 'object'
  },
  collections: {
    indexes: IndexCollection
  },
  derived: {
    document_size_average: {
      deps: ['document_size', 'document_count'],
      fn: function() {
        return this.document_size / this.document_count;
      }
    },
    index_size_average: {
      deps: ['index_size', 'index_count'],
      fn: function() {
        return this.index_size / this.index_count;
      }
    },
    name: {
      deps: ['_id'],
      fn: function() {
        if (!this._id) {
          return undefined;
        }
        return ns(this._id).collection;
      }
    },
    specialish: {
      deps: ['_id'],
      fn: function() {
        if (!this._id) {
          return undefined;
        }
        return ns(this._id).specialish;
      }
    }
  },
  serialize: function() {
    var res = this.getAttributes({
      props: true,
      derived: true
    }, true);

    _.each(this._children, function(value, key) {
      res[key] = this[key].serialize();
    }, this);
    _.each(this._collections, function(value, key) {
      res[key] = this[key].serialize();
    }, this);
    return res;
  }
});

var CollectionCollection = AmpersandCollection.extend({
  comparator: '_id',
  model: Collection,
  modelType: 'CollectionCollection'
});

module.exports = Collection;
module.exports.Collection = CollectionCollection;
<commit_msg>:green_heart: fix typo<commit_after>var AmpersandModel = require('ampersand-model');
var AmpersandCollection = require('ampersand-rest-collection');
var IndexCollection = require('mongodb-index-model').Collection;
var ns = require('mongodb-ns');
var _ = require('lodash');

var Collection = AmpersandModel.extend({
  modelType: 'Collection',
  idAttribute: '_id',
  props: {
    _id: {
      type: 'string',
      required: true
    },
    database: 'string',
    document_count: 'number',
    document_size: 'number',
    storage_size: 'number',
    index_count: 'number',
    index_size: 'number',
    padding_factor: 'number',
    extent_count: 'number',
    extent_last_size: 'number',
    /**
     * http://docs.mongodb.org/manual/reference/command/collStats/#collStats.userFlags
     */
    flags_user: 'number',
    flags_system: 'number',
    /**
     * Is this a capped collection?
     */
    capped: {
      type: 'boolean',
      default: false
    },
    /**
     * Is this collection using power of 2 allocation?
     *
     * http://docs.mongodb.org/manual/core/storage/#power-of-2-allocation
     */
    power_of_two: {
      type: 'boolean',
      default: true
    },
    /**
     * The total size in memory of all records in a collection. This value does
     * not include the record header, which is 16 bytes per record, but does
     * include the record’s padding. Additionally size does not include the
     * size of any indexes associated with the collection, which the
     * totalIndexSize field reports..
     *
     * http://docs.mongodb.org/manual/reference/command/collStats/#collStats.size
     */
    size: 'number',
    /**
     * New in version 3.0.0.
     *
     * A document that reports data from the storage engine for each index
     * in the collection.
     *
     * The fields in this document are the names of the indexes, while the
     * values themselves are documents that contain statistics for the index
     * provided by the storage engine. These statistics are for
     * internal diagnostic use.
     *
     * http://docs.mongodb.org/manual/reference/command/collStats/#collStats.indexDetails
     */
    index_details: 'object',
    /**
     * New in version 3.0.0.
     *
     * wiredTiger only appears when using the wiredTiger storage engine. This
     * document contains data reported directly by the WiredTiger engine and
     * other data for internal diagnostic use.
     *
     * http://docs.mongodb.org/manual/reference/command/collStats/#collStats.wiredTiger
     */
    wired_tiger: 'object'
  },
  collections: {
    indexes: IndexCollection
  },
  derived: {
    document_size_average: {
      deps: ['document_size', 'document_count'],
      fn: function() {
        return this.document_size / this.document_count;
      }
    },
    index_size_average: {
      deps: ['index_size', 'index_count'],
      fn: function() {
        return this.index_size / this.index_count;
      }
    },
    name: {
      deps: ['_id'],
      fn: function() {
        if (!this._id) {
          return undefined;
        }
        return ns(this._id).collection;
      }
    },
    specialish: {
      deps: ['_id'],
      fn: function() {
        if (!this._id) {
          return undefined;
        }
        return ns(this._id).specialish;
      }
    }
  },
  serialize: function() {
    var res = this.getAttributes({
      props: true,
      derived: true
    }, true);

    _.each(this._children, function(value, key) {
      res[key] = this[key].serialize();
    }, this);
    _.each(this._collections, function(value, key) {
      res[key] = this[key].serialize();
    }, this);
    return res;
  }
});

var CollectionCollection = AmpersandCollection.extend({
  comparator: '_id',
  model: Collection,
  modelType: 'CollectionCollection'
});

module.exports = Collection;
module.exports.Collection = CollectionCollection;
<|endoftext|>