<commit_before>var packet = require('dns-packet')
var dgram = require('dgram')
var thunky = require('thunky')
var events = require('events')
var os = require('os')

var noop = function () {}

module.exports = function (opts) {
  if (!opts) opts = {}

  var that = new events.EventEmitter()
  var port = typeof opts.port === 'number' ? opts.port : 5353
  var type = opts.type || 'udp4'
  var ip = opts.ip || opts.host || (type === 'udp4' ? '224.0.0.251' : null)
  var me = {address: ip, port: port}
  var memberships = {}
  var destroyed = false
  var interval = null

  if (type === 'udp6' && (!ip || !opts.interface)) {
    throw new Error('For IPv6 multicast you must specify `ip` and `interface`')
  }

  var socket = opts.socket || dgram.createSocket({
    type: type,
    reuseAddr: opts.reuseAddr !== false,
    toString: function () {
      return type
    }
  })

  socket.on('error', function (err) {
    if (err.code === 'EACCES' || err.code === 'EADDRINUSE') that.emit('error', err)
    else that.emit('warning', err)
  })

  socket.on('message', function (message, rinfo) {
    try {
      message = packet.decode(message)
    } catch (err) {
      that.emit('warning', err)
      return
    }

    that.emit('packet', message, rinfo)

    if (message.type === 'query') that.emit('query', message, rinfo)
    if (message.type === 'response') that.emit('response', message, rinfo)
  })

  socket.on('listening', function () {
    if (!port) port = me.port = socket.address().port
    if (opts.multicast !== false) {
      that.update()
      interval = setInterval(that.update, 5000)
      socket.setMulticastTTL(opts.ttl || 255)
      socket.setMulticastLoopback(opts.loopback !== false)
    }
  })

  var bind = thunky(function (cb) {
    if (!port) return cb(null)
    socket.once('error', cb)
    socket.bind(port, opts.interface, function () {
      socket.removeListener('error', cb)
      cb(null)
    })
  })

  bind(function (err) {
    if (err) return that.emit('error', err)
    that.emit('ready')
  })

  that.send = function (value, rinfo, cb) {
    if (typeof rinfo === 'function') return that.send(value, null, rinfo)
    if (!cb) cb = noop
    if (!rinfo) rinfo = me

    bind(onbind)

    function onbind (err) {
      if (destroyed) return cb()
      if (err) return cb(err)
      var message = packet.encode(value)
      socket.send(message, 0, message.length, rinfo.port, rinfo.address || rinfo.host, cb)
    }
  }

  that.response =
  that.respond = function (res, rinfo, cb) {
    if (Array.isArray(res)) res = {answers: res}

    res.type = 'response'
    res.flags = (res.flags || 0) | packet.AUTHORITATIVE_ANSWER
    that.send(res, rinfo, cb)
  }

  that.query = function (q, type, rinfo, cb) {
    if (typeof type === 'function') return that.query(q, null, null, type)
    if (typeof type === 'object' && type && type.port) return that.query(q, null, type, rinfo)
    if (typeof rinfo === 'function') return that.query(q, type, null, rinfo)
    if (!cb) cb = noop

    if (typeof q === 'string') q = [{name: q, type: type || 'ANY'}]
    if (Array.isArray(q)) q = {type: 'query', questions: q}

    q.type = 'query'
    that.send(q, rinfo, cb)
  }

  that.destroy = function (cb) {
    if (!cb) cb = noop
    if (destroyed) return process.nextTick(cb)
    destroyed = true
    clearInterval(interval)
    socket.once('close', cb)
    socket.close()
  }

  that.update = function () {
    var ifaces = opts.interface ? [].concat(opts.interface) : allInterfaces()
    var updated = false

    for (var i = 0; i < ifaces.length; i++) {
      var addr = ifaces[i]

      if (memberships[addr]) continue
      memberships[addr] = true
      updated = true

      try {
        socket.addMembership(ip, addr)
      } catch (err) {
        that.emit('warning', err)
      }
    }

    if (!updated || !socket.setMulticastInterface) return
    socket.setMulticastInterface(opts.interface || defaultInterface())
  }

  return that
}

function defaultInterface () {
  var networks = os.networkInterfaces()
  var names = Object.keys(networks)

  for (var i = 0; i < names.length; i++) {
    var net = networks[names[i]]
    for (var j = 0; j < net.length; j++) {
      var iface = net[j]
      if (iface.family === 'IPv4' && !iface.internal) return iface.address
    }
  }

  return '127.0.0.1'
}

function allInterfaces () {
  var networks = os.networkInterfaces()
  var names = Object.keys(networks)
  var res = []

  for (var i = 0; i < names.length; i++) {
    var net = networks[names[i]]
    for (var j = 0; j < net.length; j++) {
      var iface = net[j]
      if (iface.family === 'IPv4') {
        res.push(iface.address)
        // could only addMembership once per interface (https://nodejs.org/api/dgram.html#dgram_socket_addmembership_multicastaddress_multicastinterface)
        break
      }
    }
  }

  return res
}
<commit_msg>Use `0.0.0.0` for setMulticastInterface (#56)<commit_after>var packet = require('dns-packet')
var dgram = require('dgram')
var thunky = require('thunky')
var events = require('events')
var os = require('os')

var noop = function () {}

module.exports = function (opts) {
  if (!opts) opts = {}

  var that = new events.EventEmitter()
  var port = typeof opts.port === 'number' ? opts.port : 5353
  var type = opts.type || 'udp4'
  var ip = opts.ip || opts.host || (type === 'udp4' ? '224.0.0.251' : null)
  var me = {address: ip, port: port}
  var memberships = {}
  var destroyed = false
  var interval = null

  if (type === 'udp6' && (!ip || !opts.interface)) {
    throw new Error('For IPv6 multicast you must specify `ip` and `interface`')
  }

  var socket = opts.socket || dgram.createSocket({
    type: type,
    reuseAddr: opts.reuseAddr !== false,
    toString: function () {
      return type
    }
  })

  socket.on('error', function (err) {
    if (err.code === 'EACCES' || err.code === 'EADDRINUSE') that.emit('error', err)
    else that.emit('warning', err)
  })

  socket.on('message', function (message, rinfo) {
    try {
      message = packet.decode(message)
    } catch (err) {
      that.emit('warning', err)
      return
    }

    that.emit('packet', message, rinfo)

    if (message.type === 'query') that.emit('query', message, rinfo)
    if (message.type === 'response') that.emit('response', message, rinfo)
  })

  socket.on('listening', function () {
    if (!port) port = me.port = socket.address().port
    if (opts.multicast !== false) {
      that.update()
      interval = setInterval(that.update, 5000)
      socket.setMulticastTTL(opts.ttl || 255)
      socket.setMulticastLoopback(opts.loopback !== false)
    }
  })

  var bind = thunky(function (cb) {
    if (!port) return cb(null)
    socket.once('error', cb)
    socket.bind(port, opts.interface, function () {
      socket.removeListener('error', cb)
      cb(null)
    })
  })

  bind(function (err) {
    if (err) return that.emit('error', err)
    that.emit('ready')
  })

  that.send = function (value, rinfo, cb) {
    if (typeof rinfo === 'function') return that.send(value, null, rinfo)
    if (!cb) cb = noop
    if (!rinfo) rinfo = me

    bind(onbind)

    function onbind (err) {
      if (destroyed) return cb()
      if (err) return cb(err)
      var message = packet.encode(value)
      socket.send(message, 0, message.length, rinfo.port, rinfo.address || rinfo.host, cb)
    }
  }

  that.response =
  that.respond = function (res, rinfo, cb) {
    if (Array.isArray(res)) res = {answers: res}

    res.type = 'response'
    res.flags = (res.flags || 0) | packet.AUTHORITATIVE_ANSWER
    that.send(res, rinfo, cb)
  }

  that.query = function (q, type, rinfo, cb) {
    if (typeof type === 'function') return that.query(q, null, null, type)
    if (typeof type === 'object' && type && type.port) return that.query(q, null, type, rinfo)
    if (typeof rinfo === 'function') return that.query(q, type, null, rinfo)
    if (!cb) cb = noop

    if (typeof q === 'string') q = [{name: q, type: type || 'ANY'}]
    if (Array.isArray(q)) q = {type: 'query', questions: q}

    q.type = 'query'
    that.send(q, rinfo, cb)
  }

  that.destroy = function (cb) {
    if (!cb) cb = noop
    if (destroyed) return process.nextTick(cb)
    destroyed = true
    clearInterval(interval)
    socket.once('close', cb)
    socket.close()
  }

  that.update = function () {
    var ifaces = opts.interface ? [].concat(opts.interface) : allInterfaces()
    var updated = false

    for (var i = 0; i < ifaces.length; i++) {
      var addr = ifaces[i]

      if (memberships[addr]) continue
      memberships[addr] = true
      updated = true

      try {
        socket.addMembership(ip, addr)
      } catch (err) {
        that.emit('warning', err)
      }
    }

    if (!updated || !socket.setMulticastInterface) return
    socket.setMulticastInterface(opts.interface || defaultInterface())
  }

  return that
}

function defaultInterface () {
  var networks = os.networkInterfaces()
  var names = Object.keys(networks)

  for (var i = 0; i < names.length; i++) {
    var net = networks[names[i]]
    for (var j = 0; j < net.length; j++) {
      var iface = net[j]
      if (iface.family === 'IPv4' && !iface.internal) return '0.0.0.0'
    }
  }

  return '127.0.0.1'
}

function allInterfaces () {
  var networks = os.networkInterfaces()
  var names = Object.keys(networks)
  var res = []

  for (var i = 0; i < names.length; i++) {
    var net = networks[names[i]]
    for (var j = 0; j < net.length; j++) {
      var iface = net[j]
      if (iface.family === 'IPv4') {
        res.push(iface.address)
        // could only addMembership once per interface (https://nodejs.org/api/dgram.html#dgram_socket_addmembership_multicastaddress_multicastinterface)
        break
      }
    }
  }

  return res
}
<|endoftext|>


<commit_before>var promise = require('promises-a');
var emitter = require('emitter');

module.exports = imgur;
function imgur(apiKey) {
  function upload(file) {
    var def = promise();
    emitter(def.promise);

    if (!file || !file.type.match(/image.*/))
      throw new Error('Invalid file type, imgur only accepts images.');

    var fd = new FormData();
    fd.append("image", file); // Append the file
    fd.append("key", apiKey);
    // Get your own key: http://api.imgur.com/

    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http://api.imgur.com/2/upload.json"); // Boooom!
    xhr.onload = function () {
      try {
        def.fulfill(JSON.parse(xhr.responseText));
      } catch (ex) {
        def.reject(ex);
      }
    }
    xhr.onerror = def.reject;
    xhr.upload.onprogress = function (e) {
      e.perecent = e.loaded / e.total * 100;
      def.promise.emit('progress', e);
    }
    def.promise.abort = function () {
      xhr.abort();

    };

    xhr.send(fd);
    return def.promise;
  }
  return {upload: upload};
}<commit_msg>Make all errors live in the promise<commit_after>var promise = require('promises-a');
var emitter = require('emitter');

// Get your own key: http://api.imgur.com/
module.exports = imgur;
function imgur(apiKey) {
  function upload(file) {
    var def = promise();
    emitter(def.promise);
    try {
      if (!file || !file.type.match(/image.*/)) {
        var err = new Error('Invalid file type, imgur only accepts images.');
        err.code = 'InvalidFileType';
        throw err;
      }

      var fd = new FormData();
      fd.append("image", file); // Append the file
      fd.append("key", apiKey);

      var xhr = new XMLHttpRequest();
      xhr.open("POST", "http://api.imgur.com/2/upload.json"); // Boooom!
      xhr.onload = function () {
        try {
          def.fulfill(JSON.parse(xhr.responseText).upload);
        } catch (ex) {
          def.reject(ex);
        }
      }
      xhr.onerror = def.reject;
      xhr.upload.onprogress = function (e) {
        e.perecent = e.loaded / e.total * 100;
        def.promise.emit('progress', e);
      }
      def.promise.abort = function () {
        xhr.abort();
      };

      xhr.send(fd);
    } catch (ex) {
      def.reject(ex);
    }
    return def.promise;
  }
  return {upload: upload};
}<|endoftext|>


<commit_before>var libc = require("./lib/c.js");
var net = require("net");
var events = require("events");
var util = require("util");

var impl, toBuffer, toArrayBuffer;
try {
	var memcpy = require("memcpy"); // optional dependency
	toBuffer = function(ab) {
		"use strict";
		var buffer = new Buffer(ab.byteLength);
		memcpy(buffer, ab);
		return buffer;
	};
	toArrayBuffer = function(buffer) {
		"use strict";
		var ab = new ArrayBuffer(buffer.length);
		memcpy(ab, buffer);
		return ab;
	};
	impl = "memcpy";
} catch (err) {
	toBuffer = function(ab) {
		"use strict";
		var buffer = new Buffer(ab.byteLength),
			view = new Uint8Array(ab),
			i;
		for (i = 0; i < buffer.length; i += 1) {
			buffer[i] = view[i];
		}
		return buffer;
	};
	toArrayBuffer = function(buffer) {
		"use strict";
		var ab = new ArrayBuffer(buffer.length),
			view = new Uint8Array(ab),
			i;
		for (i = 0; i < buffer.length; i += 1) {
			view[i] = buffer[i];
		}
		return ab;
	};
	impl = "js";
}

function Connection(socket) {
	"use strict";
	events.EventEmitter.call(this);
	this.socket = socket;
	this.nextRequestNo = 1;
	this.nextResponseNo = 1;
	var self = this;
	this.socket.on("end", function() {
		self.emit("end");
	});
	this.socket.on("timeout", function() {
		self.emit("timeout");
	});
	this.socket.on("error", function(err) {
		self.emit("error", err);
	});
	this.socket.on("close", function(had_error) {
		self.emit("close", had_error);
	});
}
util.inherits(Connection, events.EventEmitter);
Connection.prototype.listen = function() {
	"use strict";
	var self = this;
	this.chunk = new Buffer(0);
	this.socket.on("data", function(inbuffer) {
		var buffer,
			length, // current msg length
			ab, // array buffer
			o, // deserialized object
			err; // deserialize error

		if (self.chunk.length !== 0) {
			buffer = new Buffer(self.chunk.length + inbuffer.length);
			self.chunk.copy(buffer);
			inbuffer.copy(buffer, self.chunk.length);
		} else {
			buffer = inbuffer;
		}

		while (buffer.length >= 8) {
			length = buffer.readUInt32LE(4);
			if (buffer.length >= length) {
				ab = toArrayBuffer(buffer.slice(0, length));
				try {
					o = libc.deserialize(ab);
					err = undefined;
				} catch (e) {
					o = null;
					err = e;
				}
				if (buffer.readUInt8(1) === 2) { // MsgType: 2 := response
					self.emit("response:" + self.nextResponseNo++, err, o);
				} else {
					if (err === undefined && Array.isArray(o) && o[0] === "upd") {
						self.emit("upd", o[1], o[2]);
					}
				}
				if (buffer.length > length) {
					buffer = buffer.slice(length);
				} else {
					buffer = new Buffer(0);
				}
			} else {
				break;
			}
		}

		self.chunk = buffer;
	});
};
Connection.prototype.auth = function(cb) {
	"use strict";
	var b = new Buffer(11),
		self = this;
	b.write("anonymous", 0, 9, "ascii"); // auth (username:password)
	b.writeUInt8(0x3, 9); // 3
	b.writeUInt8(0x0, 10); // zero terminated
	this.socket.write(b);
	this.socket.once("data", function(buffer) {
		if (buffer.length === 1) { // capability byte
			self.listen();
			cb();
		} else {
			cb(new Error("Invalid auth response from server"));
		}
	});
};
Connection.prototype.k = function(s, x, y, z, cb) {
	"use strict";
	cb = arguments[arguments.length -1];
	var self = this,
		payload,
		ab, // array buffer
		b,
		requestNo = this.nextRequestNo++;
	if (arguments.length === 2) {
		payload = s;
	} else if (arguments.length === 3) {
		payload = [s, x];
	} else if (arguments.length === 4) {
		payload = [s, x, y];
	} else if (arguments.length === 5) {
		payload = [s, x, y, z];
	} else {
		throw new Error("only two to five arguments allowed");
	}
	ab = libc.serialize(payload);
	b = toBuffer(ab);
	b.writeUInt8(0x1, 1); // MsgType: 1 := sync
	this.socket.write(b, function() {
		self.once("response:" + requestNo, function(err, o) {
			cb(err, o);
		});
	});
};
Connection.prototype.ks = function(s, x, y, z, cb) {
	"use strict";
	cb = arguments[arguments.length -1];
	var payload,
		ab, // array buffer
		b;
	if (arguments.length === 2) {
		payload = s;
	} else if (arguments.length === 3) {
		payload = [s, x];
	} else if (arguments.length === 4) {
		payload = [s, x, y];
	} else if (arguments.length === 5) {
		payload = [s, x, y, z];
	} else {
		throw new Error("only two to five arguments allowed");
	}
	ab = libc.serialize(payload);
	b = toBuffer(ab);
	this.socket.write(b, function() {
		cb();
	});
};
Connection.prototype.close = function(cb) {
	"use strict";
	this.socket.once("close", function() {
		if (cb) {
			cb();
		}
	});
	this.socket.end();
};

function connect(host, port, cb) {
	"use strict";
	function errorcb(err) {
		cb(err);
	}
	var socket = net.connect(port, host, function() {
		socket.removeListener("error", errorcb);
		var con = new Connection(socket);
		con.auth(function() {
			cb(undefined, con);
		});
	});
	socket.once("error", errorcb);
}
exports.connect = connect;

exports.impl = impl;
<commit_msg>linting<commit_after>var libc = require("./lib/c.js");
var net = require("net");
var events = require("events");
var util = require("util");

var impl, toBuffer, toArrayBuffer;
try {
	var memcpy = require("memcpy"); // optional dependency
	toBuffer = function(ab) {
		"use strict";
		var buffer = new Buffer(ab.byteLength);
		memcpy(buffer, ab);
		return buffer;
	};
	toArrayBuffer = function(buffer) {
		"use strict";
		var ab = new ArrayBuffer(buffer.length);
		memcpy(ab, buffer);
		return ab;
	};
	impl = "memcpy";
} catch (err) {
	toBuffer = function(ab) {
		"use strict";
		var buffer = new Buffer(ab.byteLength),
			view = new Uint8Array(ab),
			i;
		for (i = 0; i < buffer.length; i += 1) {
			buffer[i] = view[i];
		}
		return buffer;
	};
	toArrayBuffer = function(buffer) {
		"use strict";
		var ab = new ArrayBuffer(buffer.length),
			view = new Uint8Array(ab),
			i;
		for (i = 0; i < buffer.length; i += 1) {
			view[i] = buffer[i];
		}
		return ab;
	};
	impl = "js";
}

function Connection(socket) {
	"use strict";
	events.EventEmitter.call(this);
	this.socket = socket;
	this.nextRequestNo = 1;
	this.nextResponseNo = 1;
	var self = this;
	this.socket.on("end", function() {
		self.emit("end");
	});
	this.socket.on("timeout", function() {
		self.emit("timeout");
	});
	this.socket.on("error", function(err) {
		self.emit("error", err);
	});
	this.socket.on("close", function(had_error) {
		self.emit("close", had_error);
	});
}
util.inherits(Connection, events.EventEmitter);
Connection.prototype.listen = function() {
	"use strict";
	var self = this;
	this.chunk = new Buffer(0);
	this.socket.on("data", function(inbuffer) {
		var buffer,
			length, // current msg length
			ab, // array buffer
			o, // deserialized object
			err, // deserialize error
			responseNo;

		if (self.chunk.length !== 0) {
			buffer = new Buffer(self.chunk.length + inbuffer.length);
			self.chunk.copy(buffer);
			inbuffer.copy(buffer, self.chunk.length);
		} else {
			buffer = inbuffer;
		}

		while (buffer.length >= 8) {
			length = buffer.readUInt32LE(4);
			if (buffer.length >= length) {
				ab = toArrayBuffer(buffer.slice(0, length));
				try {
					o = libc.deserialize(ab);
					err = undefined;
				} catch (e) {
					o = null;
					err = e;
				}
				if (buffer.readUInt8(1) === 2) { // MsgType: 2 := response
					responseNo = self.nextResponseNo;
					self.nextResponseNo += 1;
					self.emit("response:" + responseNo, err, o);
				} else {
					if (err === undefined && Array.isArray(o) && o[0] === "upd") {
						self.emit("upd", o[1], o[2]);
					}
				}
				if (buffer.length > length) {
					buffer = buffer.slice(length);
				} else {
					buffer = new Buffer(0);
				}
			} else {
				break;
			}
		}

		self.chunk = buffer;
	});
};
Connection.prototype.auth = function(cb) {
	"use strict";
	var b = new Buffer(11),
		self = this;
	b.write("anonymous", 0, 9, "ascii"); // auth (username:password)
	b.writeUInt8(0x3, 9); // 3
	b.writeUInt8(0x0, 10); // zero terminated
	this.socket.write(b);
	this.socket.once("data", function(buffer) {
		if (buffer.length === 1) { // capability byte
			self.listen();
			cb();
		} else {
			cb(new Error("Invalid auth response from server"));
		}
	});
};
Connection.prototype.k = function(s, x, y, z, cb) {
	"use strict";
	cb = arguments[arguments.length -1];
	var self = this,
		payload,
		ab, // array buffer
		b,
		requestNo = this.nextRequestNo;
	this.nextRequestNo += 1;
	if (arguments.length === 2) {
		payload = s;
	} else if (arguments.length === 3) {
		payload = [s, x];
	} else if (arguments.length === 4) {
		payload = [s, x, y];
	} else if (arguments.length === 5) {
		payload = [s, x, y, z];
	} else {
		throw new Error("only two to five arguments allowed");
	}
	ab = libc.serialize(payload);
	b = toBuffer(ab);
	b.writeUInt8(0x1, 1); // MsgType: 1 := sync
	this.socket.write(b, function() {
		self.once("response:" + requestNo, function(err, o) {
			cb(err, o);
		});
	});
};
Connection.prototype.ks = function(s, x, y, z, cb) {
	"use strict";
	cb = arguments[arguments.length -1];
	var payload,
		ab, // array buffer
		b;
	if (arguments.length === 2) {
		payload = s;
	} else if (arguments.length === 3) {
		payload = [s, x];
	} else if (arguments.length === 4) {
		payload = [s, x, y];
	} else if (arguments.length === 5) {
		payload = [s, x, y, z];
	} else {
		throw new Error("only two to five arguments allowed");
	}
	ab = libc.serialize(payload);
	b = toBuffer(ab);
	this.socket.write(b, function() {
		cb();
	});
};
Connection.prototype.close = function(cb) {
	"use strict";
	this.socket.once("close", function() {
		if (cb) {
			cb();
		}
	});
	this.socket.end();
};

function connect(host, port, cb) {
	"use strict";
	function errorcb(err) {
		cb(err);
	}
	var socket = net.connect(port, host, function() {
		socket.removeListener("error", errorcb);
		var con = new Connection(socket);
		con.auth(function() {
			cb(undefined, con);
		});
	});
	socket.once("error", errorcb);
}
exports.connect = connect;

exports.impl = impl;
<|endoftext|>


<commit_before>var Readable = require('stream').Readable;
var util = require('util');

var echo = function(val) {
	return val;
};

var destroy = function(stream) {
	if (stream.readable && stream.destroy) stream.destroy();
};

var reader = function(self, stream, toKey) {
	var target;
	var onmatch;
	var ended = false;

	stream.pause();

	stream.on('error', function(err) {
		self.emit('error', err);
	});

	stream.on('end', function() {
		ended = true;
	});

	stream.on('data', function(data) {
		if (!onmatch) return self.emit('error', new Error('source stream does not respect pause'));
		var key = toKey(data);
		if (ended) console.error('WATA')
		if (target !== undefined && key < target) return;
		stream.pause();
		var tmp = onmatch;
		onmatch = undefined;
		tmp(data, key);
	});

	return function(key, fn) {
		if (ended) return self.push(null);
		onmatch = fn;
		target = key;
		stream.resume();
	};
};

var Intersect = function(a, b, toKey) {
	if (!(this instanceof Intersect)) return new Intersect(a, b, toKey);
	Readable.call(this, {objectMode:true});

	toKey = toKey || echo;

	this._readA = reader(this, a, toKey);
	this._readB = reader(this, b, toKey);
	this._destroyed = false;

	this.on('end', function() {
		if (!this.autoDestroy) return;
		destroy(a);
		destroy(b);
	});
};

util.inherits(Intersect, Readable);

Intersect.prototype.autoDestroy = true;

Intersect.prototype.destroy = function() {
	this._destroyed = true;
	this.push(null);
};

Intersect.prototype._read = function() {
	this._loop(undefined);
};

Intersect.prototype._loop = function(last) {
	var self = this;
	self._readA(last, function(match, matchKey) {
		if (matchKey === last && !self._destroyed) return self.push(match);
		self._readB(matchKey, function(other, otherKey) {
			if (otherKey === matchKey && !self._destroyed) return self.push(other);
			self._loop(otherKey);
		});
	});
};

module.exports = Intersect;<commit_msg>fixed not-ending bug<commit_after>var Readable = require('stream').Readable;
var util = require('util');

var echo = function(val) {
	return val;
};

var destroy = function(stream) {
	if (stream.readable && stream.destroy) stream.destroy();
};

var reader = function(self, stream, toKey) {
	var target;
	var onmatch;
	var ended = false;

	stream.pause();

	stream.on('error', function(err) {
		self.emit('error', err);
	});

	stream.on('end', function() {
		ended = true;
		if (onmatch) return self.push(null);
	});

	stream.on('data', function(data) {
		if (!onmatch) return self.emit('error', new Error('source stream does not respect pause'));
		var key = toKey(data);
		if (target !== undefined && key < target) return;
		stream.pause();
		var tmp = onmatch;
		onmatch = undefined;
		tmp(data, key);
	});

	return function(key, fn) {
		if (ended) return self.push(null);
		onmatch = fn;
		target = key;
		stream.resume();
	};
};

var Intersect = function(a, b, toKey) {
	if (!(this instanceof Intersect)) return new Intersect(a, b, toKey);
	Readable.call(this, {objectMode:true});

	toKey = toKey || echo;

	this._readA = reader(this, a, toKey);
	this._readB = reader(this, b, toKey);
	this._destroyed = false;

	this.on('end', function() {
		if (!this.autoDestroy) return;
		destroy(a);
		destroy(b);
	});
};

util.inherits(Intersect, Readable);

Intersect.prototype.autoDestroy = true;

Intersect.prototype.destroy = function() {
	this._destroyed = true;
	this.push(null);
};

Intersect.prototype._read = function() {
	this._loop(undefined);
};

Intersect.prototype._loop = function(last) {
	var self = this;
	self._readA(last, function(match, matchKey) {
		if (matchKey === last && !self._destroyed) return self.push(match);
		self._readB(matchKey, function(other, otherKey) {
			if (otherKey === matchKey && !self._destroyed) return self.push(other);
			self._loop(otherKey);
		});
	});
};

module.exports = Intersect;<|endoftext|>


<commit_before>var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var util = require('util');

// ======================================================
// MAIN

function Store(args){
  if (!args.data){
    throw new Error('missing data');
  }
  this._data = _.extend({}, args.data);
  if (typeof args.init === 'function'){
    args.init.call(this);
  }
  this._emitter = new EventEmitter();
}

_.extend(Store.prototype, {

  set: function(prop, newVal){
    var oldVal = this._data[prop];
    var isDifferent = oldVal !== newVal;
    if (isDifferent){
      this._data[prop] = newVal;
      this._emitter.emit('change', prop, newVal, oldVal);
    }
  },

  get: function(prop){
    return this._data[prop];
  },

  dispatcher: function(args){
    return new Dispatcher(this, args);
  },

  emitter: function(args){
    return new Emitter(this, args);
  }
});

// ======================================================
// DISPATCHER

function Dispatcher(store, args){
  this._ctx = _.extend({}, args);
  this._ctx.store = store;
  if (typeof this._ctx.init === 'function'){
    this._ctx.init.call(this._ctx);
  }
  this._directCommands = {};
  _.each(store._data, function(value, prop){
    this._directCommands['change:'+prop] = prop;
  }, this);
}

_.extend(Dispatcher.prototype, {
  command: function(command, firstArg){
    if (!this._ctx.hasOwnProperty(command)){
      if (this._directCommands.hasOwnProperty(command)){
        var prop = this._directCommands[command];
        this._ctx.store.set(prop, firstArg);
      } else {
        throw new Error(util.format('%s is not a command', command));
      }
    } else {
      var args = Array.prototype.slice.call(arguments);
      args.shift();
      this._ctx[command].apply(this._ctx, args);
    }
  }
});

// ======================================================
// EMITTER

function Emitter(store, args){
  EventEmitter.call(this);
  _.extend(this, args);
  this.store = store;
  if (typeof this.init === 'function'){
    this.init.call(this);
  }
  _.each(this, function(methodFunc, event){
    if (typeof methodFunc === 'function' && event !== 'init'){
      this.on(event, methodFunc);
    }
  }, this);
  var self = this;
  this.store._emitter.on('change', function(eventName, newValue, oldValue){
    self.emit('change:'+eventName, newValue, oldValue);
  });
}

util.inherits(Emitter, EventEmitter);

module.exports = Store;

/*

var myStore = new Store({
  init: function(){},
  data: {
    foo: null,
    bar: null,
    baz: null
  }
});

var myStoreDispatcher = myStore.dispatcher({
  init: function(){},
  commands: {
    // implicit
    // 'change:foo': ...
    // 'change:bar': ...

    // explicit but no-op
    'change:baz': 'changeBaz'

    // something more customized
    'doFunkyThing': 'funky'
  },
  changeBaz: function(value){
    this.store.set('baz', value);
  },
  funky: function(whatever){
    // do stuff
  }
});

var myStoreEmitter = myStore.emitter({
  init: function(){},
  events: {
    'change:baz': 'bazChange'
  },
  bazChange: function(){
    this.emit('zup');
  }
});

myStoreDispatcher.command('change:baz', blah);
myStoreDispatcher.command('doFunkyThing', {});
myStoreEmitter.on('zup', function(){...});

*/
<commit_msg>Removed difference requirements<commit_after>var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var util = require('util');

// ======================================================
// MAIN

function Store(args){
  if (!args.data){
    throw new Error('missing data');
  }
  this._data = _.extend({}, args.data);
  if (typeof args.init === 'function'){
    args.init.call(this);
  }
  this._emitter = new EventEmitter();
}

_.extend(Store.prototype, {

  set: function(prop, newVal){
    var oldVal = this._data[prop];
    var isDifferent = oldVal !== newVal;
    this._data[prop] = newVal;
    this._emitter.emit('change', prop, newVal, oldVal);
  },

  get: function(prop){
    return this._data[prop];
  },

  dispatcher: function(args){
    return new Dispatcher(this, args);
  },

  emitter: function(args){
    return new Emitter(this, args);
  }
});

// ======================================================
// DISPATCHER

function Dispatcher(store, args){
  this._ctx = _.extend({}, args);
  this._ctx.store = store;
  if (typeof this._ctx.init === 'function'){
    this._ctx.init.call(this._ctx);
  }
  this._directCommands = {};
  _.each(store._data, function(value, prop){
    this._directCommands['change:'+prop] = prop;
  }, this);
}

_.extend(Dispatcher.prototype, {
  command: function(command, firstArg){
    if (!this._ctx.hasOwnProperty(command)){
      if (this._directCommands.hasOwnProperty(command)){
        var prop = this._directCommands[command];
        this._ctx.store.set(prop, firstArg);
      } else {
        throw new Error(util.format('%s is not a command', command));
      }
    } else {
      var args = Array.prototype.slice.call(arguments);
      args.shift();
      this._ctx[command].apply(this._ctx, args);
    }
  }
});

// ======================================================
// EMITTER

function Emitter(store, args){
  EventEmitter.call(this);
  _.extend(this, args);
  this.store = store;
  if (typeof this.init === 'function'){
    this.init.call(this);
  }
  _.each(this, function(methodFunc, event){
    if (typeof methodFunc === 'function' && event !== 'init'){
      this.on(event, methodFunc);
    }
  }, this);
  var self = this;
  this.store._emitter.on('change', function(eventName, newValue, oldValue){
    self.emit('change:'+eventName, newValue, oldValue);
  });
}

util.inherits(Emitter, EventEmitter);

module.exports = Store;

/*

var myStore = new Store({
  init: function(){},
  data: {
    foo: null,
    bar: null,
    baz: null
  }
});

var myStoreDispatcher = myStore.dispatcher({
  init: function(){},
  commands: {
    // implicit
    // 'change:foo': ...
    // 'change:bar': ...

    // explicit but no-op
    'change:baz': 'changeBaz'

    // something more customized
    'doFunkyThing': 'funky'
  },
  changeBaz: function(value){
    this.store.set('baz', value);
  },
  funky: function(whatever){
    // do stuff
  }
});

var myStoreEmitter = myStore.emitter({
  init: function(){},
  events: {
    'change:baz': 'bazChange'
  },
  bazChange: function(){
    this.emit('zup');
  }
});

myStoreDispatcher.command('change:baz', blah);
myStoreDispatcher.command('doFunkyThing', {});
myStoreEmitter.on('zup', function(){...});

*/
<|endoftext|>


<commit_before>var Service, Characteristic;
var JSONRequest = require("jsonrequest");

module.exports = function (homebridge) {
    Service = homebridge.hap.Service;
    Characteristic = homebridge.hap.Characteristic;
    homebridge.registerAccessory("homebridge-domotiga", "Domotiga", Domotiga);
}
//Get data from config file
function Domotiga(log, config) {
    this.log = log;
    this.config = {
        host: config.host || 'localhost',
        port: config.port || 9090,
        service: config.service,
        device: config.device,
        valueTemperature: config.valueTemperature || 1,
        valueHumidity: config.valueHumidity,
        valueBattery: config.valueBattery,
        valueContact: config.valueContact || 1,
        valueSwitch: config.valueSwitch || 1,
        name: config.name || NA,
        lowbattery: config.lowbattery
    };
}
Domotiga.prototype = {
    identify: function (callback) {
        this.log("Identify requested!");
        callback(); // success
    },
    getValueFromDomotiga: function (deviceValueNo, callback) {
        var that = this;
        JSONRequest('http://' + that.config.host + ':' + that.config.port,
                {
                    jsonrpc: "2.0",
                    method: "device.get",
                    params: {"device_id": that.config.device},
                    id: 1
                }, function (err, data) {

            if (err) {
                that.log("Sorry err: ", err);
                callback(err);
            }
            else {
                item = Number(deviceValueNo) - 1;
                //that.log("data.result:", data.result);
                //that.log( "data.result[values][0][value]", data.result[values][0][value]);
                i = 0;
                for (key1 in data.result) {
                    if (i == 37) {
                        //that.log("key1 ", i, key1, "values[key1]", values[key1]);
                        j = 0;
                        for (key2 in data.result[key1]) {
                            if (j == item) {
                                //that.log("key2 ", j, key2, "values[key1][key2]", values[key1][key2]);
                                k = 0;
                                for (key3 in data.result[key1][key2]) {
                                    if (k == 17) {
                                        //that.log("key3 ", k, key3, "data.result[key1][key2][key3]", data.result[key1][key2][key3]);
                                        callback(null, data.result[key1][key2][key3]);
                                    }
                                    ++k;
                                }
                            }
                            ++j;
                        }
                    }
                    ++i;
                }
            }
        });
    },
    setValueToDomotiga: function (deviceValueNo, value, callback) {
        var that = this;
        JSONRequest('http://' + that.config.host + ':' + that.config.port,
                {
                    jsonrpc: "2.0",
                    method: "device.set",
                    params: {"device_id": that.config.device, "valuenum": deviceValueNo, "value": value},
                    id: 1
                }, function (err, data) {
            //that.log("data:", data);
            if (err) {
                that.log("Sorry err: ", err);
                callback(err);
            }
            else {
                callback();
            }
        });
    },
    getCurrentRelativeHumidity: function (callback) {
        var that = this;
        that.log("getting CurrentRelativeHumidity for " + that.config.name);
        that.getValueFromDomotiga(that.config.valueHumidity, function (error, result) {
            if (error) {
                that.log('CurrentRelativeHumidity GetValue failed: %s', error.message);
                callback(error);
            } else {
                callback(null, Number(result));
            }
        }.bind(this));
    },
    getCurrentTemperature: function (callback) {
        var that = this;
        that.log("getting Temperature for " + that.config.name);
        that.getValueFromDomotiga(that.config.valueTemperature, function (error, result) {
            if (error) {
                that.log('CurrentTemperature GetValue failed: %s', error.message);
                callback(error);
            } else {
                callback(null, Number(result));
            }
        }.bind(this));
    },
    getTemperatureUnits: function (callback) {
        var that = this;
        that.log("getting Temperature unit for " + that.config.name);
        // 1 = F and 0 = C
        callback(null, 0);
    },
    getGetContactState: function (callback) {
        var that = this;
        that.log("getting ContactState for " + that.config.name);
        that.getValueFromDomotiga(that.config.valueContact, function (error, result) {
            if (error) {
                that.log('getGetContactState GetValue failed: %s', error.message);
                callback(error);
            } else {
                if (result.toLowerCase() == "on") {
                    callback(null, 0);
                    //Characteristic.ContactSensorState.CONTACT_DETECTED = 0;
                }
                else {
                    callback(null, 1);
                    //Characteristic.ContactSensorState.CONTACT_NOT_DETECTED = 1;
                }
            }
        }.bind(this));
    },
    getCurrentBatteryLevel: function (callback) {
        var that = this;
        that.log("getting Battery level for " + that.config.name);

        that.getValueFromDomotiga(that.config.valueBattery, function (error, result) {
            if (error) {
                that.log('CurrentBattery GetValue failed: %s', error.message);
                callback(error);
            } else {
                //that.log('CurrentBattery level Number(result): %s', Number(result));
                remaining = parseInt(Number(result)*100/5000, 10) ;
                that.log('CurrentBattery level: %s', remaining);
                if (remaining > 100)
                    remaining = 100;
                else if (remaining < 0)
                    remaining = 0;

                callback(null, remaining);
            }
        }.bind(this));
    },
    getLowBatteryStatus: function (callback) {
        var that = this;
        that.log("getting BatteryStatus for " + that.config.name);

        that.getValueFromDomotiga(that.config.valueTemperature, function (error, result) {
            if (error) {
                that.log('BatteryStatus GetValue failed: %s', error.message);
                callback(error);
            } else {
                if (Number(result) < Number(that.config.lowbattery)) {
                    callback(null, 1);
                    //callback(null, Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
                }
                else {
                    callback(null, 0);
                }
            }
        }.bind(this));
    },
    getSwitchOn: function (callback) {
        var that = this;
        that.log("getting SwitchState for " + that.config.name);
        that.getValueFromDomotiga(that.config.valueSwitch, function (error, result) {
            if (error) {
                that.log('getSwitchOn GetValue failed: %s', error.message);
                callback(error);
            } else {
                if (result.toLowerCase() == "on") {
                    callback(null, 1);
                }
                else {
                    callback(null, 0);
                }
            }
        }.bind(this));
    },
    setSwitchOn: function (switchOn, callback) {
        var that = this;
        that.log("Setting SwitchState for '%s' to %s", that.config.name, switchOn);

        if (switchOn == 1) {
            switchState = "On";
        }
        else {
            switchState = "Off";
        }
        var callbackWasCalled = false;

        that.setValueToDomotiga(that.config.valueSwitch, switchState, function (err) {
            if (callbackWasCalled) {
                that.log("WARNING: setValueToDomotiga called its callback more than once! Discarding the second one.");
            }
            callbackWasCalled = true;
            if (!err) {
                that.log("Successfully set switch state on the '%s' to %s", that.config.name, switchOn);
                callback(null);
            }
            else {
                that.log("Error setting switch state to %s on the '%s'", switchOn, that.config.name);
                callback(err);
            }
        }.bind(this));
    },
    getServices: function () {
        // you can OPTIONALLY create an information service if you wish to override
        // the default values for things like serial number, model, etc.
        var informationService = new Service.AccessoryInformation();

        if (this.config.service == "TempHygroMeter") {
            informationService
                    .setCharacteristic(Characteristic.Manufacturer, "TinyTX DHT22 Manufacturer")
                    .setCharacteristic(Characteristic.Model, "TinyTX DHT22 Sensor")
                    .setCharacteristic(Characteristic.SerialNumber, ("Domotiga device " + this.config.device + this.config.name));

            var controlService = new Service.TemperatureSensor();

            controlService
                    .getCharacteristic(Characteristic.CurrentTemperature)
                    .on('get', this.getCurrentTemperature.bind(this));
            //optionals
            if (this.config.valueHumidity) {
                controlService
                        .addCharacteristic(Characteristic.CurrentRelativeHumidity)
                        .on('get', this.getCurrentRelativeHumidity.bind(this));
            }
            if (this.config.valueBattery) {
                controlService
                        .addCharacteristic(Characteristic.BatteryLevel)
                        .on('get', this.getCurrentBatteryLevel.bind(this));
            }
            if (this.config.lowbattery) {
                controlService
                        .addCharacteristic(Characteristic.StatusLowBattery)
                        .on('get', this.getLowBatteryStatus.bind(this));
            }

            return [informationService, controlService];
        }
        else if (this.config.service == "Contact") {

            informationService
                    .setCharacteristic(Characteristic.Manufacturer, "Contact Manufacturer")
                    .setCharacteristic(Characteristic.Model, "Contact Model")
                    .setCharacteristic(Characteristic.SerialNumber, ("Domotiga device " + this.config.device + this.config.name));

            var controlService = new Service.ContactSensor();

            controlService
                    .getCharacteristic(Characteristic.ContactSensorState)
                    .on('get', this.getGetContactState.bind(this));

            //optionals
            if (this.config.valueBattery) {
                controlService
                        .addCharacteristic(Characteristic.BatteryLevel)
                        .on('get', this.getCurrentBatteryLevel.bind(this));
            }
            if (this.config.lowbattery) {
                controlService
                        .addCharacteristic(Characteristic.StatusLowBattery)
                        .on('get', this.getLowBatteryStatus.bind(this));
            }
            return [informationService, controlService];
        }
        else if (this.config.service == "Switch") {

            informationService
                    .setCharacteristic(Characteristic.Manufacturer, "Switch Manufacturer")
                    .setCharacteristic(Characteristic.Model, "Switch Model")
                    .setCharacteristic(Characteristic.SerialNumber, ("Domotiga device " + this.config.device + this.config.name));

            var controlService = new Service.Switch(this.config.name);

            controlService
                    .getCharacteristic(Characteristic.On)
                    .on('get', this.getSwitchOn.bind(this))
                    .on('set', this.setSwitchOn.bind(this));

            return [informationService, controlService];
        }
    }
};
<commit_msg>Update index.js<commit_after>var Service, Characteristic;
var JSONRequest = require("jsonrequest");

module.exports = function (homebridge) {
    Service = homebridge.hap.Service;
    Characteristic = homebridge.hap.Characteristic;
    homebridge.registerAccessory("homebridge-domotiga", "Domotiga", Domotiga);
}
//Get data from config file
function Domotiga(log, config) {
    this.log = log;
    this.config = {
        host: config.host || 'localhost',
        port: config.port || 9090,
        service: config.service,
        device: config.device,
        valueTemperature: config.valueTemperature || 1,
        valueHumidity: config.valueHumidity,
        valueBattery: config.valueBattery,
        valueContact: config.valueContact || 1,
        valueSwitch: config.valueSwitch || 1,
        name: config.name || NA,
        lowbattery: config.lowbattery
    };
}
Domotiga.prototype = {
    identify: function (callback) {
        this.log("Identify requested!");
        callback(); // success
    },
    getValueFromDomotiga: function (deviceValueNo, callback) {
        var that = this;
        JSONRequest('http://' + that.config.host + ':' + that.config.port,
                {
                    jsonrpc: "2.0",
                    method: "device.get",
                    params: {"device_id": that.config.device},
                    id: 1
                }, function (err, data) {

            if (err) {
                that.log("Sorry err: ", err);
                callback(err);
            }
            else {
                item = Number(deviceValueNo) - 1;
                //that.log("data.result:", data.result);
                //that.log( "data.result[values][0][value]", data.result[values][0][value]);
                i = 0;
                for (key1 in data.result) {
                    if (i == 37) {
                        //that.log("key1 ", i, key1, "values[key1]", values[key1]);
                        j = 0;
                        for (key2 in data.result[key1]) {
                            if (j == item) {
                                //that.log("key2 ", j, key2, "values[key1][key2]", values[key1][key2]);
                                k = 0;
                                for (key3 in data.result[key1][key2]) {
                                    if (k == 17) {
                                        //that.log("key3 ", k, key3, "data.result[key1][key2][key3]", data.result[key1][key2][key3]);
                                        callback(null, data.result[key1][key2][key3]);
                                    }
                                    ++k;
                                }
                            }
                            ++j;
                        }
                    }
                    ++i;
                }
            }
        });
    },
    setValueToDomotiga: function (deviceValueNo, value, callback) {
        var that = this;
        JSONRequest('http://' + that.config.host + ':' + that.config.port,
                {
                    jsonrpc: "2.0",
                    method: "device.set",
                    params: {"device_id": that.config.device, "valuenum": deviceValueNo, "value": value},
                    id: 1
                }, function (err, data) {
            //that.log("data:", data);
            if (err) {
                that.log("Sorry err: ", err);
                callback(err);
            }
            else {
                callback();
            }
        });
    },
    getCurrentRelativeHumidity: function (callback) {
        var that = this;
        that.log("getting CurrentRelativeHumidity for " + that.config.name);
        that.getValueFromDomotiga(that.config.valueHumidity, function (error, result) {
            if (error) {
                that.log('CurrentRelativeHumidity GetValue failed: %s', error.message);
                callback(error);
            } else {
                callback(null, Number(result));
            }
        }.bind(this));
    },
    getCurrentTemperature: function (callback) {
        var that = this;
        that.log("getting Temperature for " + that.config.name);
        that.getValueFromDomotiga(that.config.valueTemperature, function (error, result) {
            if (error) {
                that.log('CurrentTemperature GetValue failed: %s', error.message);
                callback(error);
            } else {
                callback(null, Number(result));
            }
        }.bind(this));
    },
    getTemperatureUnits: function (callback) {
        var that = this;
        that.log("getting Temperature unit for " + that.config.name);
        // 1 = F and 0 = C
        callback(null, 0);
    },
    getGetContactState: function (callback) {
        var that = this;
        that.log("getting ContactState for " + that.config.name);
        that.getValueFromDomotiga(that.config.valueContact, function (error, result) {
            if (error) {
                that.log('getGetContactState GetValue failed: %s', error.message);
                callback(error);
            } else {
                if (result.toLowerCase() == "on") {
                    callback(null, 0);
                    //Characteristic.ContactSensorState.CONTACT_DETECTED = 0;
                }
                else {
                    callback(null, 1);
                    //Characteristic.ContactSensorState.CONTACT_NOT_DETECTED = 1;
                }
            }
        }.bind(this));
    },
    getCurrentBatteryLevel: function (callback) {
        var that = this;
        that.log("getting Battery level for " + that.config.name);

        that.getValueFromDomotiga(that.config.valueBattery, function (error, result) {
            if (error) {
                that.log('CurrentBattery GetValue failed: %s', error.message);
                callback(error);
            } else {
                //that.log('CurrentBattery level Number(result): %s', Number(result));
                remaining = parseInt(Number(result)*100/5000, 10) ;
                that.log('CurrentBattery level: %s', remaining);
                if (remaining > 100)
                    remaining = 100;
                else if (remaining < 0)
                    remaining = 0;

                callback(null, remaining);
            }
        }.bind(this));
    },
    getLowBatteryStatus: function (callback) {
        var that = this;
        that.log("getting BatteryStatus for " + that.config.name);

        that.getValueFromDomotiga(that.config.valueBattery, function (error, result) {
            if (error) {
                that.log('BatteryStatus GetValue failed: %s', error.message);
                callback(error);
            } else {
                if (Number(result) < Number(that.config.lowbattery)) {
                    callback(null, 1);
                    //callback(null, Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);
                }
                else {
                    callback(null, 0);
                }
            }
        }.bind(this));
    },
    getSwitchOn: function (callback) {
        var that = this;
        that.log("getting SwitchState for " + that.config.name);
        that.getValueFromDomotiga(that.config.valueSwitch, function (error, result) {
            if (error) {
                that.log('getSwitchOn GetValue failed: %s', error.message);
                callback(error);
            } else {
                if (result.toLowerCase() == "on") {
                    callback(null, 1);
                }
                else {
                    callback(null, 0);
                }
            }
        }.bind(this));
    },
    setSwitchOn: function (switchOn, callback) {
        var that = this;
        that.log("Setting SwitchState for '%s' to %s", that.config.name, switchOn);

        if (switchOn == 1) {
            switchState = "On";
        }
        else {
            switchState = "Off";
        }
        var callbackWasCalled = false;

        that.setValueToDomotiga(that.config.valueSwitch, switchState, function (err) {
            if (callbackWasCalled) {
                that.log("WARNING: setValueToDomotiga called its callback more than once! Discarding the second one.");
            }
            callbackWasCalled = true;
            if (!err) {
                that.log("Successfully set switch state on the '%s' to %s", that.config.name, switchOn);
                callback(null);
            }
            else {
                that.log("Error setting switch state to %s on the '%s'", switchOn, that.config.name);
                callback(err);
            }
        }.bind(this));
    },
    getServices: function () {
        // you can OPTIONALLY create an information service if you wish to override
        // the default values for things like serial number, model, etc.
        var informationService = new Service.AccessoryInformation();

        if (this.config.service == "TempHygroMeter") {
            informationService
                    .setCharacteristic(Characteristic.Manufacturer, "TinyTX DHT22 Manufacturer")
                    .setCharacteristic(Characteristic.Model, "TinyTX DHT22 Sensor")
                    .setCharacteristic(Characteristic.SerialNumber, ("Domotiga device " + this.config.device + this.config.name));

            var controlService = new Service.TemperatureSensor();

            controlService
                    .getCharacteristic(Characteristic.CurrentTemperature)
                    .on('get', this.getCurrentTemperature.bind(this));
            //optionals
            if (this.config.valueHumidity) {
                controlService
                        .addCharacteristic(Characteristic.CurrentRelativeHumidity)
                        .on('get', this.getCurrentRelativeHumidity.bind(this));
            }
            if (this.config.valueBattery) {
                controlService
                        .addCharacteristic(Characteristic.BatteryLevel)
                        .on('get', this.getCurrentBatteryLevel.bind(this));
            }
            if (this.config.lowbattery) {
                controlService
                        .addCharacteristic(Characteristic.StatusLowBattery)
                        .on('get', this.getLowBatteryStatus.bind(this));
            }

            return [informationService, controlService];
        }
        else if (this.config.service == "Contact") {

            informationService
                    .setCharacteristic(Characteristic.Manufacturer, "Contact Manufacturer")
                    .setCharacteristic(Characteristic.Model, "Contact Model")
                    .setCharacteristic(Characteristic.SerialNumber, ("Domotiga device " + this.config.device + this.config.name));

            var controlService = new Service.ContactSensor();

            controlService
                    .getCharacteristic(Characteristic.ContactSensorState)
                    .on('get', this.getGetContactState.bind(this));

            //optionals
            if (this.config.valueBattery) {
                controlService
                        .addCharacteristic(Characteristic.BatteryLevel)
                        .on('get', this.getCurrentBatteryLevel.bind(this));
            }
            if (this.config.lowbattery) {
                controlService
                        .addCharacteristic(Characteristic.StatusLowBattery)
                        .on('get', this.getLowBatteryStatus.bind(this));
            }
            return [informationService, controlService];
        }
        else if (this.config.service == "Switch") {

            informationService
                    .setCharacteristic(Characteristic.Manufacturer, "Switch Manufacturer")
                    .setCharacteristic(Characteristic.Model, "Switch Model")
                    .setCharacteristic(Characteristic.SerialNumber, ("Domotiga device " + this.config.device + this.config.name));

            var controlService = new Service.Switch(this.config.name);

            controlService
                    .getCharacteristic(Characteristic.On)
                    .on('get', this.getSwitchOn.bind(this))
                    .on('set', this.setSwitchOn.bind(this));

            return [informationService, controlService];
        }
    }
};
<|endoftext|>


<commit_before><commit_msg>Add index.js<commit_after>var schema = require('./lib/scheam/schema');

module.exports = (() => {
	'use strict';

	return schema;
})();<|endoftext|>


<commit_before>'use strict';

const path = require("path"),
      rd = require("require-directory"),
      gulp = require('gulp'),
      sourcemaps = require('gulp-sourcemaps'),
      babel = require('gulp-babel'),
      concat = require('gulp-concat'),
      minify = require('gulp-minify'),
      packer = require('gulp-packer'),
      streamify = require('gulp-streamify');

class Organized {
    constructor() {
        this.args = {};
        this.stgs = {};
    }

    set(key, value){
        this.args[key] = value;
    }

    config(stg = {}){
        this.stgs = stg;

        if(typeof stg.modules === "object"){
            for(let key in stg.modules)
                this.args[key] = require(stg.modules[key]);
        }

        if(typeof stg.virtual === "object"){
            var names = "";
            var argsArr = [];

            for(let keyArgs in this.args){
                names += `${keyArgs},`;
                argsArr.push(this.args[keyArgs]);
            }

            names = names.substr(0, names.length-1);

            for(let key in stg.virtual){
                eval(`(function(${names}){
                        this.set("${key}", ${stg.virtual[key]});
                    }).apply(this, argsArr)`);
            }
        }

        if(typeof stg.map === "object"){
            var argsArr = [];

            for(let keyArgs in stg.map_args)
                argsArr.push(this.args[stg.map_args[keyArgs]]);

            for(let key in stg.map){
                rd(module, stg.map[key]+"/", {
                    visit: function(obj){
                        obj.apply(this, argsArr);
                    }
                });
            }
        }
    }

    init(dependences = [], onload){
        if(typeof onload === "function"){
            var argsArr = [];

            for(let keyArgs in dependences)
                argsArr.push(this.args[dependences[keyArgs]]);

            onload.apply(this, argsArr);
        }
    }

    build(arr, dir){
        if(typeof arr === "object"){
            arr.forEach(function(map){
                var base = path.basename(map.replace("/*.js", ""));

                if(base.indexOf(".") > 0)
                    base = "";

                gulp.src(map)
                    .pipe(sourcemaps.init())
                    .pipe(babel({presets: ['es2015']}))
                    .pipe(minify({
                        ext:{
                            src:'-debug.js',
                            min:'.js'
                        },
                        exclude: ['tasks'],
                        ignoreFiles: ['-min.js', 'build.js']
                    }))
                    .pipe(streamify(packer({base62: true, shrink: true})))
                    .pipe(through.obj(function(file, enc, cb){
                        var filename = file.relative.replace(".min", "");

                        if(file.relative.indexOf("-debug") <= 0)
                            fs.writeFileSync(`${dir}/${base}/${filename}`, file.contents.toString('binary'));

                        cb();
                    }, function(cb){
                        cb();
                    }))
                    .pipe(sourcemaps.write('.'))
                    .pipe(gulp.dest(`${dir}/${base}`));
            });
        }
    }
}

module.exports = new Organized;
<commit_msg>Including packer in build<commit_after>'use strict';

const path = require("path"),
      rd = require("require-directory"),
      gulp = require('gulp'),
      sourcemaps = require('gulp-sourcemaps'),
      babel = require('gulp-babel'),
      concat = require('gulp-concat'),
      minify = require('gulp-minify'),
      packer = require('gulp-packer'),
      streamify = require('gulp-streamify');

class Organized {
    constructor() {
        this.args = {};
        this.stgs = {};
    }

    set(key, value){
        this.args[key] = value;
    }

    config(stg = {}){
        this.stgs = stg;

        if(typeof stg.modules === "object"){
            for(let key in stg.modules)
                this.args[key] = require(stg.modules[key]);
        }

        if(typeof stg.virtual === "object"){
            var names = "";
            var argsArr = [];

            for(let keyArgs in this.args){
                names += `${keyArgs},`;
                argsArr.push(this.args[keyArgs]);
            }

            names = names.substr(0, names.length-1);

            for(let key in stg.virtual){
                eval(`(function(${names}){
                        this.set("${key}", ${stg.virtual[key]});
                    }).apply(this, argsArr)`);
            }
        }

        if(typeof stg.map === "object"){
            var argsArr = [];

            for(let keyArgs in stg.map_args)
                argsArr.push(this.args[stg.map_args[keyArgs]]);

            for(let key in stg.map){
                rd(module, stg.map[key]+"/", {
                    visit: function(obj){
                        obj.apply(this, argsArr);
                    }
                });
            }
        }
    }

    init(dependences = [], onload){
        if(typeof onload === "function"){
            var argsArr = [];

            for(let keyArgs in dependences)
                argsArr.push(this.args[dependences[keyArgs]]);

            onload.apply(this, argsArr);
        }
    }

    build(arr, dir){
        if(typeof arr === "object"){
            arr.forEach(function(map){
                var base = path.basename(map.replace("/*.js", ""));

                if(base.indexOf(".") > 0)
                    base = "";

                gulp.src(map)
                    .pipe(sourcemaps.init())
                    .pipe(babel({presets: ['es2015']}))
                    .pipe(minify({
                        ext:{
                            src:'-debug.js',
                            min:'.js'
                        },
                        exclude: ['tasks'],
                        ignoreFiles: ['-min.js', 'build.js']
                    }))
                    .pipe(streamify(packer({base62: true, shrink: true})))
                    .pipe(through.obj(function(file, enc, cb){
                        var filename = file.relative.replace(".min", "");

                        if(file.relative.indexOf("-debug") <= 0)
                            fs.writeFileSync(`${dir}/${base}/${filename}`, file.contents.toString('utf8'));

                        cb();
                    }, function(cb){
                        cb();
                    }))
                    .pipe(sourcemaps.write('.'))
                    .pipe(gulp.dest(`${dir}/${base}`));
            });
        }
    }
}

module.exports = new Organized;
<|endoftext|>


<commit_before><commit_msg>Initial single frame rendering and recording.<commit_after>const { spawn } = require('child_process');
const puppeteer = require('puppeteer');

function ffmpegWork(page, ffmpegPath, args) {
  return new Promise(function(resolve, reject) {
    var ffmpeg = spawn(ffmpegPath, args);

    ffmpeg.on('close', resolve;

    page
      .screenshot()
      .then(buffer => {
        ffmpeg.stdin.write(buffer, err => {
          if (err) reject(err);
          else ffmpeg.stdin.end();
        });
      })
      .catch(reject);
  });
}

module.exports.record = async function(options) {
  const browser = options.browser || (await puppeteer.launch());
  const page = options.page || (await browser.newPage());

  var ffmpegPath = options.ffmpeg || 'ffmpeg';
  var fps = options.fps || 60;

  var args = [
    '-y',
    '-f',
    'image2pipe',
    '-r',
    '' + +fps,
    '-i',
    '-',
    '-c:v',
    'libvpx',
    '-auto-alt-ref',
    '0',
    '-pix_fmt',
    'yuva420p',
    '-metadata:s:v:0',
    'alpha_mode="1"'
  ];

  var outFile = options.output;

  if ('format' in options) {
    args.push('-f', options.format);
  } else if (!outFile) {
    args.push('-f', 'matroska');
  }

  args.push(outFile || '-');

  await options.prepare(browser, page);

  await ffmpegWork(page, ffmpegPath, args);
};
<|endoftext|>


<commit_before>var SensorTag = require('sensortag');
var mqtt = require('mqtt');

var client  = mqtt.connect('mqtt://');
var deviceID = "testDevice1";
var deviceSecret = "testSecret1";
var publishChannel = "devices/" + deviceID + "/up";

client.on('connect', function(){
    client.subscribe('devices/' + deviceID + '/down');
});

client.on('message', function(topic, message){
    // message is Buffer
    console.log(message.toString());
});

function onDiscover(device) {
    console.log('Discovered device with UUID: ' + device['uuid']);

    device.connect(function(){
        connected = true;
        console.log('Connected To Sensor Tag');
        device.discoverServicesAndCharacteristics(function(callback){
            initAirSensors();
            initAccelAndGyro();
        });
    });

    device.on('disconnect', function(onDisconnect) {
        connected = false;
        client.end();
        console.log('Device disconnected.');
    });

    function initAccelAndGyro() {
        device.enableAccelerometer();
        device.notifyAccelerometer(function(){});
        device.enableGyroscope();
        device.notifyGyroscope(function(){});
        device.enableMagnetometer();
        device.notifyMagnetometer(function(){});
    };

    device.on('gyroscopeChange', function(x, y, z) {
        var data = {
            "sensor": "gyroscope",
            "gyroX" : x,
            "gyroY" : y,
            "gyroZ" : z
        };
        client.publish(publishChannel, JSON.stringify(data), function() {
        });
    });

    device.on('accelerometerChange', function(x, y, z) {
        var data = {
            "sensor": "accelerometer",
            "accelX" : x,
            "accelY" : y,
            "accelZ" : z
        };
        client.publish(publishChannel, JSON.stringify(data), function() {
        });
    });

    device.on('magnetometerChange', function(x, y, z) {
        var data = {
            "sensor": "magnetometer",
            "magX" : x,
            "magY" : y,
            "magZ" : z
        };
        client.publish(publishChannel, JSON.stringify(data), function() {
        });
    });

    function initAirSensors() {
        device.enableIrTemperature();
        device.enableHumidity();
        device.enableBarometricPressure();
        var intervalId = setInterval(function() {
            if(!connected) {
                clearInterval(intervalId);
                return;
            }
            device.readBarometricPressure(function(pressure) {
                device.readHumidity(function(temperature, humidity) {
                    device.readIrTemperature(function(objectTemperature, ambientTemperature) {
                        var data = {
                            "sensor": "air",
                            "pressure" : pressure,
                            "humidity" : humidity,
                            "objTemp" : objectTemperature,
                            "ambientTemp" : ambientTemperature,
                            "temp" : temperature
                        };
                        client.publish(publishChannel, JSON.stringify(data), function() {
                        });
                    });
                });
            });
        }, 5000);
    }
}

console.log('Make sure the Sensor Tag is on!');

SensorTag.discoverAll(onDiscover);<commit_msg>added debug<commit_after>var SensorTag = require('sensortag');
var mqtt = require('mqtt');

var client  = mqtt.connect('mqtt://');
var deviceID = [
    {"uuid":"b0b448c04303", "ovassid":"12015112820", "secret":"************"},
    {"uuid":"b0b448bc4d00", "ovassid":"12015112818", "secret":"************"},
    {"uuid":"b0b448c04305", "ovassid":"12015112865", "secret":"************"},
    {"uuid":"b0b448c08c02", "ovassid":"12015112892", "secret":"************"},
    {"uuid":"b0b448bcd003", "ovassid":"12015112885", "secret":"************"},
];

client.on('connect', function(){
    for (i in deviceID){
        client.subscribe('devices/' + deviceID[i].ovassid + '/down');
    }
});

client.on('message', function(topic, message){
    console.log(message.toString());
});

function publish(device, data){
    console.log(device);
    console.log(data);
}

function onDiscover(device) {
    console.log('Discovered device with UUID: ' + device['uuid']);

    device.connect(function(){
        connected = true;
        console.log('Connected To Sensor Tag');
        device.discoverServicesAndCharacteristics(function(callback){
            initAirSensors();
            initAccelAndGyro();
        });
    });

    device.on('disconnect', function(onDisconnect) {
        connected = false;
        client.end();
        console.log('Device disconnected.');
    });

    function initAccelAndGyro() {
        device.enableAccelerometer();
        device.notifyAccelerometer(function(){});
        device.enableGyroscope();
        device.notifyGyroscope(function(){});
        device.enableMagnetometer();
        device.notifyMagnetometer(function(){});
    };

    device.on('gyroscopeChange', function(x, y, z) {
        var data = {
            "sensor": "gyroscope",
            "gyroX" : x,
            "gyroY" : y,
            "gyroZ" : z
        };
        publish(device, data);
    });

    device.on('accelerometerChange', function(x, y, z) {
        var data = {
            "sensor": "accelerometer",
            "accelX" : x,
            "accelY" : y,
            "accelZ" : z
        };
        publish(device, data);
    });

    device.on('magnetometerChange', function(x, y, z) {
        var data = {
            "sensor": "magnetometer",
            "magX" : x,
            "magY" : y,
            "magZ" : z
        };
        publish(device, data);
    });

    function initAirSensors() {
        device.enableIrTemperature();
        device.enableHumidity();
        device.enableBarometricPressure();
        var intervalId = setInterval(function() {
            if(!connected) {
                clearInterval(intervalId);
                return;
            }
            device.readBarometricPressure(function(pressure) {
                device.readHumidity(function(temperature, humidity) {
                    device.readIrTemperature(function(objectTemperature, ambientTemperature) {
                        var data = {
                            "sensor": "air",
                            "pressure" : pressure,
                            "humidity" : humidity,
                            "objTemp" : objectTemperature,
                            "ambientTemp" : ambientTemperature,
                            "temp" : temperature
                        };
                        publish(device, data);
                    });
                });
            });
        }, 5000);
    }
}

console.log('Make sure the Sensor Tag is on!');

SensorTag.discoverAll(onDiscover);<|endoftext|>


<commit_before>const SHA3 = require('sha3'),
  ec = require('elliptic').ec('secp256k1');
  assert = require('assert'),
  rlp = require('rlp'),
  BN = require('bn.js');

//the max interger that this VM can handle
const MAX_INTEGER = exports.MAX_INTEGER = new BN('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16);

const TWO_POW256 = exports.TWO_POW256 = new BN('115792089237316195423570985008687907853269984665640564039457584007913129639936');

//hex string of SHA3-256 hash of `null`
exports.SHA3_NULL = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470';

//SHA3-256 hash of the rlp of []
exports.SHA3_RLP_ARRAY = '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347';

//SHA3-256 hash of the rlp of `null`
exports.SHA3_RLP = '56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421';

const ETH_UNITS = exports.ETH_UNITS = [
  'wei',
  'Kwei',
  'Mwei',
  'Gwei',
  'szabo',
  'finney',
  'ether',
  'grand',
  'Mether',
  'Gether',
  'Tether',
  'Pether',
  'Eether',
  'Zether',
  'Yether',
  'Nether',
  'Dether',
  'Vether',
  'Uether'
];

exports.BN = BN;

/**
 * Returns a buffer filled with 0s
 * @method zeros
 * @param {Integer} bytes  the number of bytes the buffer should be
 *[MaÆ @return {Buffer}
 */
exports.zeros = function(bytes) {
  var buf = new Buffer(bytes);
  buf.fill(0);
  return buf;
};

/**
 * pads an array of buffer with leading zeros till it has `length` bytes
 * @method pad
 * @param {Buffer|Array} array
 * @pa[MaÆram {Integer}  length the number of bytes the output should be
 * @return {Buffer|Array}
 */
var pad = exports.pad = function(msg, length) {
  var buf;
  if (msg.length < length) {
    buf = new Buffer(length);
    buf.fill(0);
    msg.copy(buf, length - msg.length);
    return buf;
  } else {
    return msg.slice(-length);
  }
};

/**
 * Trims leading zeros from a buffer or an array
 * @method unpad
 * @param {Buffer|Array|String}
 * @return {Buffer|Array|String}
 */
exports.unpad = function(a) {
  var first = a[0];
  while (a.length > 0 && first.toString() === '0') {
    a = a.slice(1);
    first = a[0];
  }
  return a;
};

/**
 * Converts an integer into a hex string
 * @method intToHex
 * @param {Number}
 * @return {String}
 */
exports.intToHex = function(i) {
  assert(i % 1 === 0, 'number is not a interger');
  assert(i >= 0, 'number must be positive');
  var hex = i.toString(16);
  if (hex.length % 2) {
    hex = '0' + hex;
  }
  return hex;
};

/**
 * Converts an integer to a buffer
 * @method intToBuffer
 * @param {Number}
 * @return {Buffer}
 */
exports.intToBuffer = function(i) {
  var hex = exports.intToHex(i);
  return new Buffer(hex, 'hex');
};

/**
 * Converts a buffer to an Interger
 * @method bufferToInt
 * @par[MaÅam {B[M`Êuffer}
 * @return {Number}
 */
exports.bufferToInt = function(buf) {
  if (buf.length === 0) {
    return 0;
  }
  return parseInt(buf.toString('hex'), 16);
};

/**
 * interpets a buffer as a signed integer and returns a bignum
 * @method fromSigned
 * @param {Buffer} num
 * @return {BN}
 */
exports.fromSigned = function(num) {
  if (num.length === 32 && num[0] >= 128) {
    return new BN(num).sub(TWO_POW256);
  } else {
    return new BN(num);
  }
};

/**
 * Converts a bignum to an unsigned interger and returns it as a buffer
 * @method toUnsigned
 * @param {Bignum} num
 * @return {Buffer}
 */
exports.toUnsigned = function(num) {
  if (num.cmp(new BN(0)) === -1) {
    return new Buffer(num.add(TWO_POW256).toArray());
  } else {
    return new Buffer(num.toArray());
  }
};

exports.sha3 = function(a, bytes) {
  if(!bytes) bytes = 256

  var h = new SHA3.SHA3Hash(bytes);
  if (a) {
    h.update(a);
  }
  return new Buffer(h.digest('hex'), 'hex');
};

/**
 * Returns the ethereum address of a given public key
 * @method pubToAddress
 * @param {Buffer}
 * @return {Buffer}
 */
var pubToAddress = exports.pubToAddress = exports.publicToAddress = function(pubKey) {
  var hash = new SHA3.SHA3Hash(256);
  hash.update(pubKey.slice(-64));
  return new Buffer(hash.digest('hex').slice(-40), 'hex');
};

/**
 * Returns the ethereum public key of a given private key
 * @method privateToPublic
 * @param {Buffer} privateKey
 * @return {Buffer}
 */
var privateToPublic = exports.privateToPublic = function(privateKey){
  privateKey = new BN(privateKey);
  var key = ec.keyFromPrivate(privateKey).getPublic().toJSON();
  key =  new Buffer(key[0].toArray().concat(key[1].toArray()));
  return key;
}

/**
 * Returns the ethereum address of a given private key
 * @method privateToAddress
 * @param {Buffer} privateKey
 * @return {Buffer}
 */
exports.privateToAddress = function(privateKey){
  return pubToAddress(privateToPublic(privateKey));
}

/**
 * Generates a new address
 * @method generateAddress
 * @param {Buffer} from the address which is creating this new address
 * @param {Buffer} nonce the nonce of the from account
 */
exports.generateAddress = function(from, nonce) {

  nonce = new Buffer(new BN(nonce).sub(new BN(1)).toArray());
  if (nonce.toString('hex') === '00') {
    nonce = 0;
  }
  var hash = new SHA3.SHA3Hash(256);
  hash.update(rlp.encode([new Buffer(from, 'hex'), nonce]));

  return new Buffer(hash.digest('hex').slice(24), 'hex');
};

/**
 * defines properties on a `Object`
 * @method defineProperties
 * @para[M`Êm {Object} self the `Object` to define properties on
 * @param {Array} fields an array fields to define
 */
exports.defineProperties = function(self, fields, data) {

  self.raw = [];
  self._fields = [];

  self.toJSON = function(label){
    if (label) {
      var obj = {};

      for (var prop in this) {
        if (typeof this[prop] !== 'function' && prop !== 'raw' && prop !== '_fields')
          obj[prop] = this[prop].toString('hex');
      }

      return obj;
    } else {
      return baToJSON(this.raw);
    }
  };

  fields.forEach(function(field, i) {
    self._fields.push(field.name);
    Object.defineProperty(self, field.name, {
      enumerable: true,
      configurable: true,
      get: function() {
        return this.raw[i];
      },
      set: function(v) {
        if (!Buffer.isBuffer(v)) {
          if (typeof v === 'string') {
            if (v.slice(0, 2) === '0x') {
              v = v.slice(2);
            }
            v = new Buffer(v, 'hex');
          } else if (typeof v === 'number') {
            v = exports.intToBuffer(v);
          } else if (v === null || v === undefined) {
            v = new Buffer([]);
          } else if (v.toArray) {
            v = new Buffer(v.toArray());
          } else {
            throw new Error('invalid type');
          }
        }

        if(v.toString('hex') === '00' &&  field.noZero) v = new Buffer([]);

        if(field.word && new BN(v).cmp(MAX_INTEGER)  === 1){
          throw('to large of value');
        }

        if(!(field.empty && v.length === 0) && field.pad && v.length < field.length){
          v = pad(v, field.length);
        }

        if (!(field.empty && v.length === 0) && field.length) {
          assert(field.length === v.length, 'The field ' + field.name + 'must have byte length of ' + field.length);
        }

        this.raw[i] = v;
      }
    });

    if(field.default){
      self[field.name] = field.default;
    }

  });

  if (data) {
    if (Buffer.isBuffer(data)) {
      data = rlp.decode(data);
    }

    if (Array.isArray(data)) {
      if(data.length > self._fields.length) throw('wrong number of fields in data')
      //make sure all the items are buffers
      data.forEach(function(d, i) {
         self[self._fields[i]] = typeof d === 'string' ? new Buffer(d, 'hex') : d;
      });
    } else {
      for (var prop in data) {
        if (self._fields.indexOf(prop) !== -1) {
          self[prop] = data[prop];
        }
      }
    }
  }
};

/**
 * Print a Buffer Array
 * @method printBA
 * @param {Buffer|Array}
 */
exports.printBA = function(ba) {
  if (Buffer.isBuffer(ba)) {
    if (ba.length === 0) {
      console.log('new Buffer(0)');
    } else {
      console.log('new Buffer(\'' + ba.toString('hex') + '\', \'hex\')');
    }
  } else if (ba instanceof Array) {
    console.log('[');
    for (var i = 0; i < ba.length; i++) {
      exports.printBA(ba[i]);
      console.log(',');
    }
    console.log(']');
  } else {
    console.log(ba);
  }
};

/**
 * converts a buffer array to JSON
 * @method BAToJSON
 * @param {Buffer|Array}
 */
const baToJSON = exports.baToJSON = function(ba) {
  if (Buffer.isBuffer(ba)) {
    return ba.toString('hex');
  } else if (ba instanceof Array) {
    var array = [];
    for (var i = 0; i < ba.length; i++) {
      array.push(exports.baToJSON(ba[i]));
    }
    return array;
  }
};

/// @returns ascii string representation of hex value prefixed with 0x
exports.toAscii = function(hex) {
  // Find termination
  var str = '';
  var i = 0,
    l = hex.length;

  if (hex.substring(0, 2) === '0x')
    i = 2;

  for (; i < l; i += 2) {
    var code = parseInt(hex.substr(i, 2), 16);
    if (code === 0) {
      break;
    }

    str += String.fromCharCode(code);
  }

  return str;
};

/// @returns hex representation (prefixed by 0x) of ascii string
exports.fromAscii = function(str, pad) {
  pad = pad === undefined ? 0 : pad;
  var hex = this.toHex(str);
  while (hex.length < pad * 2) {
    hex += '00';
  }
  return '0x' + hex;
};

/// @returns decimal representaton of hex value prefixed by 0x
exports.toDecimal = function(val) {
  // remove 0x and place 0, if it's required
  val = val.length > 2 ? val.substring(2) : '0';
  return new BN(val, 16).toString(10);
};

// @returns hex representation (prefixed by 0x) of decimal value
exports.fromDecimal = function(val) {
  return '0x' + new BN(val).toString(16);
};

exports.toHex = function(str) {
  var hex = '';
  for (var i = 0; i < str.length; i++) {
    var n = str.charCodeAt(i).toString(16);
    hex += n.length < 2 ? '0' + n : n;
  }

  return hex;
};

/// used to transform value/string to eth string
exports.toEth = function(str) {
  var val = typeof str === 'string' ? str.indexOf('0x') === 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str;
  var unit = 0;
  var units = ETH_UNITS;
  while (val > 3000 && unit < units.length - 1) {
    val /= 1000;
    unit++;
  }
  var s = val.toString().length < val.toFixed(2).length ? val.toString() : val.toFixed(2);
  var replaceFunction = function($0, $1, $2) {
    return $1 + ',' + $2;
  };

  while (true) {
    var o = s;
    s = s.replace(/(\d)(\d\d\d[\.\,])/, replaceFunction);
    if (o === s)
      break;
  }
  return s + ' ' + units[unit];
};
<commit_msg>added hexPrefix funcs<commit_after>const SHA3 = require('sha3'),
  ec = require('elliptic').ec('secp256k1');
  assert = require('assert'),
  rlp = require('rlp'),
  BN = require('bn.js');

//the max interger that this VM can handle
const MAX_INTEGER = exports.MAX_INTEGER = new BN('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16);

const TWO_POW256 = exports.TWO_POW256 = new BN('115792089237316195423570985008687907853269984665640564039457584007913129639936');

//hex string of SHA3-256 hash of `null`
exports.SHA3_NULL = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470';

//SHA3-256 hash of the rlp of []
exports.SHA3_RLP_ARRAY = '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347';

//SHA3-256 hash of the rlp of `null`
exports.SHA3_RLP = '56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421';

const ETH_UNITS = exports.ETH_UNITS = [
  'wei',
  'Kwei',
  'Mwei',
  'Gwei',
  'szabo',
  'finney',
  'ether',
  'grand',
  'Mether',
  'Gether',
  'Tether',
  'Pether',
  'Eether',
  'Zether',
  'Yether',
  'Nether',
  'Dether',
  'Vether',
  'Uether'
];

exports.BN = BN;

/**
 * Returns a buffer filled with 0s
 * @method zeros
 * @param {Integer} bytes  the number of bytes the buffer should be
 *[MaÆ @return {Buffer}
 */
exports.zeros = function(bytes) {
  var buf = new Buffer(bytes);
  buf.fill(0);
  return buf;
};

/**
 * pads an array of buffer with leading zeros till it has `length` bytes
 * @method pad
 * @param {Buffer|Array} array
 * @pa[MaÆram {Integer}  length the number of bytes the output should be
 * @return {Buffer|Array}
 */
var pad = exports.pad = function(msg, length) {
  var buf;
  if (msg.length < length) {
    buf = new Buffer(length);
    buf.fill(0);
    msg.copy(buf, length - msg.length);
    return buf;
  } else {
    return msg.slice(-length);
  }
};

/**
 * Trims leading zeros from a buffer or an array
 * @method unpad
 * @param {Buffer|Array|String}
 * @return {Buffer|Array|String}
 */
exports.unpad = function(a) {
  var first = a[0];
  while (a.length > 0 && first.toString() === '0') {
    a = a.slice(1);
    first = a[0];
  }
  return a;
};

/**
 * Converts an integer into a hex string
 * @method intToHex
 * @param {Number}
 * @return {String}
 */
exports.intToHex = function(i) {
  assert(i % 1 === 0, 'number is not a interger');
  assert(i >= 0, 'number must be positive');
  var hex = i.toString(16);
  if (hex.length % 2) {
    hex = '0' + hex;
  }
  return hex;
};

/**
 * Converts an integer to a buffer
 * @method intToBuffer
 * @param {Number}
 * @return {Buffer}
 */
exports.intToBuffer = function(i) {
  var hex = exports.intToHex(i);
  return new Buffer(hex, 'hex');
};

/**
 * Converts a buffer to an Interger
 * @method bufferToInt
 * @par[MaÅam {B[M`Êuffer}
 * @return {Number}
 */
exports.bufferToInt = function(buf) {
  if (buf.length === 0) {
    return 0;
  }
  return parseInt(buf.toString('hex'), 16);
};

/**
 * interpets a buffer as a signed integer and returns a bignum
 * @method fromSigned
 * @param {Buffer} num
 * @return {BN}
 */
exports.fromSigned = function(num) {
  if (num.length === 32 && num[0] >= 128) {
    return new BN(num).sub(TWO_POW256);
  } else {
    return new BN(num);
  }
};

/**
 * Converts a bignum to an unsigned interger and returns it as a buffer
 * @method toUnsigned
 * @param {Bignum} num
 * @return {Buffer}
 */
exports.toUnsigned = function(num) {
  if (num.cmp(new BN(0)) === -1) {
    return new Buffer(num.add(TWO_POW256).toArray());
  } else {
    return new Buffer(num.toArray());
  }
};

exports.sha3 = function(a, bytes) {
  if(!bytes) bytes = 256

  var h = new SHA3.SHA3Hash(bytes);
  if (a) {
    h.update(a);
  }
  return new Buffer(h.digest('hex'), 'hex');
};

/**
 * Returns the ethereum address of a given public key
 * @method pubToAddress
 * @param {Buffer}
 * @return {Buffer}
 */
var pubToAddress = exports.pubToAddress = exports.publicToAddress = function(pubKey) {
  var hash = new SHA3.SHA3Hash(256);
  hash.update(pubKey.slice(-64));
  return new Buffer(hash.digest('hex').slice(-40), 'hex');
};

/**
 * Returns the ethereum public key of a given private key
 * @method privateToPublic
 * @param {Buffer} privateKey
 * @return {Buffer}
 */
var privateToPublic = exports.privateToPublic = function(privateKey){
  privateKey = new BN(privateKey);
  var key = ec.keyFromPrivate(privateKey).getPublic().toJSON();
  key =  new Buffer(key[0].toArray().concat(key[1].toArray()));
  return key;
}

/**
 * Returns the ethereum address of a given private key
 * @method privateToAddress
 * @param {Buffer} privateKey
 * @return {Buffer}
 */
exports.privateToAddress = function(privateKey){
  return pubToAddress(privateToPublic(privateKey));
}

/**
 * Generates a new address
 * @method generateAddress
 * @param {Buffer} from the address which is creating this new address
 * @param {Buffer} nonce the nonce of the from account
 */
exports.generateAddress = function(from, nonce) {

  nonce = new Buffer(new BN(nonce).sub(new BN(1)).toArray());
  if (nonce.toString('hex') === '00') {
    nonce = 0;
  }
  var hash = new SHA3.SHA3Hash(256);
  hash.update(rlp.encode([new Buffer(from, 'hex'), nonce]));

  return new Buffer(hash.digest('hex').slice(24), 'hex');
};

/**
 * defines properties on a `Object`
 * @method defineProperties
 * @para[M`Êm {Object} self the `Object` to define properties on
 * @param {Array} fields an array fields to define
 */
exports.defineProperties = function(self, fields, data) {

  self.raw = [];
  self._fields = [];

  self.toJSON = function(label){
    if (label) {
      var obj = {};

      for (var prop in this) {
        if (typeof this[prop] !== 'function' && prop !== 'raw' && prop !== '_fields')
          obj[prop] = this[prop].toString('hex');
      }

      return obj;
    } else {
      return baToJSON(this.raw);
    }
  };

  fields.forEach(function(field, i) {
    self._fields.push(field.name);
    Object.defineProperty(self, field.name, {
      enumerable: true,
      configurable: true,
      get: function() {
        return this.raw[i];
      },
      set: function(v) {
        if (!Buffer.isBuffer(v)) {
          if (typeof v === 'string') {
            v= stripHex(v);
            v = new Buffer(v, 'hex');
          } else if (typeof v === 'number') {
            v = exports.intToBuffer(v);
          } else if (v === null || v === undefined) {
            v = new Buffer([]);
          } else if (v.toArray) {
            v = new Buffer(v.toArray());
          } else {
            throw new Error('invalid type');
          }
        }

        if(v.toString('hex') === '00' &&  field.noZero) v = new Buffer([]);

        if(field.word && new BN(v).cmp(MAX_INTEGER)  === 1){
          throw('to large of value');
        }

        if(!(field.empty && v.length === 0) && field.pad && v.length < field.length){
          v = pad(v, field.length);
        }

        if (!(field.empty && v.length === 0) && field.length) {
          assert(field.length === v.length, 'The field ' + field.name + 'must have byte length of ' + field.length);
        }

        this.raw[i] = v;
      }
    });

    if(field.default){
      self[field.name] = field.default;
    }

  });

  if (data) {
    if (Buffer.isBuffer(data)) {
      data = rlp.decode(data);
    }

    if (Array.isArray(data)) {
      if(data.length > self._fields.length) throw('wrong number of fields in data')
      //make sure all the items are buffers
      data.forEach(function(d, i) {
         self[self._fields[i]] = typeof d === 'string' ? new Buffer(d, 'hex') : d;
      });
    } else {
      for (var prop in data) {
        if (self._fields.indexOf(prop) !== -1) {
          self[prop] = data[prop];
        }
      }
    }
  }
};

/**
 * Print a Buffer Array
 * @method printBA
 * @param {Buffer|Array}
 */
exports.printBA = function(ba) {
  if (Buffer.isBuffer(ba)) {
    if (ba.length === 0) {
      console.log('new Buffer(0)');
    } else {
      console.log('new Buffer(\'' + ba.toString('hex') + '\', \'hex\')');
    }
  } else if (ba instanceof Array) {
    console.log('[');
    for (var i = 0; i < ba.length; i++) {
      exports.printBA(ba[i]);
      console.log(',');
    }
    console.log(']');
  } else {
    console.log(ba);
  }
};

/**
 * converts a buffer array to JSON
 * @method BAToJSON
 * @param {Buffer|Array}
 */
const baToJSON = exports.baToJSON = function(ba) {
  if (Buffer.isBuffer(ba)) {
    return ba.toString('hex');
  } else if (ba instanceof Array) {
    var array = [];
    for (var i = 0; i < ba.length; i++) {
      array.push(exports.baToJSON(ba[i]));
    }
    return array;
  }
};

/// @returns ascii string representation of hex value prefixed with 0x
exports.toAscii = function(hex) {
  // Find termination
  var str = '';
  var i = 0,
    l = hex.length;

  if (hex.substring(0, 2) === '0x')
    i = 2;

  for (; i < l; i += 2) {
    var code = parseInt(hex.substr(i, 2), 16);
    if (code === 0) {
      break;
    }

    str += String.fromCharCode(code);
  }

  return str;
};

/// @returns hex representation (prefixed by 0x) of ascii string
exports.fromAscii = function(str, pad) {
  pad = pad === undefined ? 0 : pad;
  var hex = this.toHex(str);
  while (hex.length < pad * 2) {
    hex += '00';
  }
  return '0x' + hex;
};

/// @returns decimal representaton of hex value prefixed by 0x
exports.toDecimal = function(val) {
  // remove 0x and place 0, if it's required
  val = val.length > 2 ? val.substring(2) : '0';
  return new BN(val, 16).toString(10);
};

// @returns hex representation (prefixed by 0x) of decimal value
exports.fromDecimal = function(val) {
  return '0x' + new BN(val).toString(16);
};

exports.toHex = function(str) {
  var hex = '';
  for (var i = 0; i < str.length; i++) {
    var n = str.charCodeAt(i).toString(16);
    hex += n.length < 2 ? '0' + n : n;
  }

  return hex;
};

/// used to transform value/string to eth string
exports.toEth = function(str) {
  var val = typeof str === 'string' ? str.indexOf('0x') === 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str;
  var unit = 0;
  var units = ETH_UNITS;
  while (val > 3000 && unit < units.length - 1) {
    val /= 1000;
    unit++;
  }
  var s = val.toString().length < val.toFixed(2).length ? val.toString() : val.toFixed(2);
  var replaceFunction = function($0, $1, $2) {
    return $1 + ',' + $2;
  };

  while (true) {
    var o = s;
    s = s.replace(/(\d)(\d\d\d[\.\,])/, replaceFunction);
    if (o === s)
      break;
  }
  return s + ' ' + units[unit];
};

const isHexPrefixed = exports.isHexPrefixed = function(str){
  return str.slice(0, 2) === '0x';
}

const stripHex = exports.stripHex = function(str){
  if (typeof str !== 'string')
     return str

  return isHexPrefixed ?  str.slice(2) : str
}

exports.addHex = function(str){
  if (typeof str !== 'string')
     return str

  return isHexPrefixed(str) ? '0x' + str : str
}
<|endoftext|>