<commit_before>if (typeof require != 'undefined') {
	var DOMParser = require('xmldom').DOMParser;
	var XMLSerializer = require('xmldom').XMLSerializer;
	var text_encoding = require('text-encoding');
	var TextEncoder = text_encoding.TextEncoder;
	var TextDecoder = text_encoding.TextDecoder;

	var pako = require('./libs/pako.min.js');
	var minipdf = require('./minipdf.js');
	// var minipdf = require('./pdf_js_compat.js');
}

var pdfform = (function() {
'use strict';

var assert = minipdf.assert;

function BytesIO() {
	this.length = 0;
	this.entries = [];
}
BytesIO.prototype = {
	write_str: function(s) {
		this.length += s.length;
		assert(typeof s == 'string');
		this.entries.push(s);
	},
	write_buf: function(buf) {
		this.length += buf.length;
		assert(buf instanceof Uint8Array, 'Expected a Uint8Array, but got ' + JSON.stringify(buf));
		this.entries.push(buf);
	},
	get_uint8array: function() {
		var res = new Uint8Array(this.length);
		var pos = 0;
		this.entries.forEach(function(e) {
			if (typeof e == 'string') {
				for (var i = 0,slen = e.length;i < slen;i++,pos++) {
					res[pos] = e.charCodeAt(i);
				}
			} else {
				res.set(e, pos);
				pos += e.length;
			}
		});
		assert(pos == this.length);
		return res;
	},
	position: function() {
		return this.length;
	},
};

// Code from pdf.utils.js (ASL2) starts here
function pad(num, length) {
  var ret = num + '';
  while (ret.length < length) {
	ret = '0' + ret;
  }
  return ret;
}

function hasSpecialChar(str) {
  for (var i = 0, ii = str.length; i < ii; i++) {
	switch (str[i]) {
	case '(':
	case ')':
	case '\\':
	case '\n':
	case '\r':
	case '\t':
	case '\b':
	case '\f':
		return true;
	}
  }
  return false;
}

function serialize(node, uncompressed) {
	var i, ret;  // Wishing for let in modern browsers :(
	if (minipdf.isRef(node)) {
		return node.num + ' ' + node.gen + ' R';
	} else if (minipdf.isNum(node)) {
		return node;
	} else if (minipdf.isBool(node)) {
		return node;
	} else if (minipdf.isName(node)) {
		assert(node.name);
		return '/' + node.name;
	} else if (minipdf.isString(node)) {
		if (!hasSpecialChar(node)) {
			return '(' + node + ')';
		} else {
			ret = '<';
			for (i = 0; i < node.length; i++) {
				ret += pad(node.charCodeAt(i).toString(16), 2);
			}
			return ret + '>';
		}
	} else if (minipdf.isArray(node)) {
		ret = ['['];
		for (i = 0; i < node.length; i++) {
			ret.push(serialize(node[i], uncompressed));
		}
		ret.push(']');
		return ret.join(' ');
	} else if (minipdf.isDict(node)) {
		var map = node.map;
		ret = ['<<'];
		for (var key in map) {
			ret.push('/' + key + ' ' + serialize(map[key], uncompressed));
		}
		ret.push('>>');
		return ret.join('\n');
	} else if (minipdf.isStream(node)) {
		ret = '';
		delete node.dict.map.DecodeParms;
		delete node.dict.map.Filter;

		var content = node.getBytes();
		assert(content, 'expecting byte content from ' + JSON.stringify(node));
		var out;
		if (uncompressed) {
			out = minipdf.buf2str(content);
			node.dict.map.Length = out.length;
		} else {
			out = minipdf.buf2str(pako.deflate(content));
			node.dict.map.Length = out.length;
			node.dict.map.Filter = [new minipdf.Name('FlateDecode')];
		}

		assert(minipdf.isDict(node.dict));
		ret += serialize(node.dict, uncompressed);
		ret += '\nstream\n';
		ret += out;
		ret += '\nendstream\n';
		return ret;
	} else {
		throw new Error('Unknown node type ' + JSON.stringify(node));
	}
  }

// End of code from pdf.utils.js

function PDFObjects(doc) {
	this.entries = doc.get_xref_entries();
	assert(minipdf.isArray(this.entries), 'xref entries should be an Array');
}
PDFObjects.prototype = {
add: function(obj, gen) {
	var e = {
		obj: obj,
		gen: gen,
		num: this.entries.length,
		uncompressed: 'added',
	};
	this.entries.push(e);
	return e;
},
update: function(ref, obj) {
	assert(ref.num !== undefined);
	assert(ref.gen !== undefined);
	var e = {
		obj: obj,
		gen: ref.gen,
		num: ref.num,
		uncompressed: 'added',
	};
	this.entries[e.num] = e;
	return e;
},
write_object: function(out, e, uncompressed) {
	e.offset = out.position();
	assert(e.num !== undefined);
	var bs = serialize(e.obj, uncompressed);
	out.write_str(e.num + ' ' + e.gen + ' obj\n');
	out.write_str(bs);
	out.write_str('\nendobj\n');
},
write_xref_stream: function(out, prev, root_ref) {
	var map = {
		Type: new minipdf.Name('XRef'),
		Size: this.entries.length + 1, // + 1 for this object itself
		Length: 6 * (this.entries.length + 1),
		Root: root_ref,
		W: [1, 4, 1],
	};
	if (prev !== undefined) {
		map.Prev = prev;
	}

	var bio = new BytesIO();
	var entry = this.add('__xref_stream__', 0);
	entry.offset = out.position();
	this.entries.forEach(function(e) {
		assert(e.offset !== undefined, 'entry should have an offset');
		bio.write_buf(new Uint8Array([
			(e.uncompressed ? 1 : 2),
			(e.offset >> 24),
			(e.offset >> 16) & 0xff,
			(e.offset >> 8) & 0xff,
			e.offset & 0xff,
			e.gen,
		]));
	});
	var ui8ar = bio.get_uint8array();

	var stream = minipdf.newStream(map, ui8ar);
	entry.obj = stream;
	this.write_object(out, entry, true);
},
};

function visit_acroform_fields(doc, callback) {
	var to_visit = doc.acroForm.map.Fields.slice();
	while (to_visit.length > 0) {
		var n = to_visit.shift();
		if (minipdf.isRef(n)) {
			var ref = n;
			n = doc.fetch(n);
			n._pdfform_ref = ref;
		}

		if (n.map && n.map.Kids) {
			to_visit.push.apply(to_visit, n.map.Kids);
		} else if (n.map && n.map.Type && n.map.Type.name == 'Annot') {
			callback(n);
		}
	}
}

function pdf_decode_str(str) {
	if (! str.startsWith('\u00FE\u00FF')) {
		return str;
	}
    var res = '';
	for (var i = 2; i < str.length; i += 2) {
		res += String.fromCharCode(str.charCodeAt(i) << 8 | str.charCodeAt(i + 1));
	}
	return res;
}

function acroform_match_spec(n, fields) {
	var t = pdf_decode_str(n.map.T);
	if (t in fields) {
		return fields[t][0];
	} else {
		var m = /^(.*)\[([0-9]+)\]$/.exec(t);
		if (m && (m[1] in fields)) {
			return fields[m[1]][m[2]];
		}
	}
	return undefined;
}

function modify_xfa(doc, objects, out, index, callback) {
	var xfa = doc.acroForm.map.XFA;
	var section_idx = xfa.indexOf(index);
	assert(section_idx >= 0);
	var section_ref = xfa[section_idx + 1];
	var section_node = doc.fetch(section_ref);
	assert(minipdf.isStream(section_node), 'XFA section node should be a stream');
	var bs = section_node.getBytes();
	assert(bs);
	var str = (new TextDecoder('utf-8')).decode(bs);

	str = callback(str);

	var out_bs = (new TextEncoder('utf-8').encode(str));
	var out_node = minipdf.newStream(section_node.dict.map, out_bs);
	assert(minipdf.isStream(out_node));

	var e = objects.update(section_ref, out_node);
	objects.write_object(out, e);
}

function transform(data, fields) {
	var doc = minipdf.parse(new Uint8Array(data));
	var objects = new PDFObjects(doc);

	var out = new BytesIO();
	out.write_buf(data);

	// Change AcroForms
	visit_acroform_fields(doc, function(n) {
		var spec = acroform_match_spec(n, fields);
		if (spec === undefined) {
			return;
		}

		if (n.map.FT.name == 'Tx') {
			n.map.V = '' + spec;
		} else if (n.map.FT.name == 'Btn') {
			n.map.AS = n.map.V = n.map.DV = spec ? new minipdf.Name('Yes') : new minipdf.Name('Off');
		} else {
			throw new Error('Unsupported input type' + n.map.FT.name);
		}

		var ref = n._pdfform_ref;
		var e = objects.update(ref, n);
		objects.write_object(out, e);
	});
	// Set NeedAppearances in AcroForm dict
	var acroform_ref = doc.get_acroform_ref();
	doc.acroForm.map.NeedAppearances = true;
	var e = objects.update(acroform_ref, doc.acroForm);
	objects.write_object(out, e);

	// Change XFA
	modify_xfa(doc, objects, out, 'datasets', function(str) {
		// Fix up XML
		str = str.replace(/\n(\/?>)/g, '$1\n');

		var ds_doc = new DOMParser().parseFromString(str);
		for (var f in fields) {
			var els = ds_doc.getElementsByTagName(f);

			for (var i = 0;i < els.length;i++) {
				var val = fields[f][i];
				if (val === undefined) {
					continue;
				}
				var el = els[i];
				while (el.firstChild) {
					el.removeChild(el.firstChild);
				}

				if (typeof val == 'boolean') {
					val = val ? 1 : 0;
				}
				el.appendChild(ds_doc.createTextNode(val));
			}
		}

		str = new XMLSerializer().serializeToString(ds_doc);
		return str;
	});

	var startxref = out.position();
	var root_id = doc.get_root_id();
	var root_ref = new minipdf.Ref(root_id, 0);
	objects.write_xref_stream(out, doc.startXRef, root_ref);

	out.write_str('startxref\n');
	out.write_str(startxref + '\n');
	out.write_str('%%EOF');

	return out.get_uint8array();
}

return {
	transform: transform,
};
})();

if (typeof module != 'undefined') {
	module.exports = pdfform;
}<commit_msg>fix for browser usage<commit_after>if (typeof require != 'undefined') {
	var DOMParser = require('xmldom').DOMParser;
	var XMLSerializer = require('xmldom').XMLSerializer;
	var text_encoding = require('text-encoding');
	var TextEncoder = text_encoding.TextEncoder;
	var TextDecoder = text_encoding.TextDecoder;

	var pako = require('./libs/pako.min.js');
	var minipdf = require('./minipdf.js');
	// var minipdf = require('./pdf_js_compat.js');
}

var pdfform = (function() {
'use strict';

var assert = minipdf.assert;

function BytesIO() {
	this.length = 0;
	this.entries = [];
}
BytesIO.prototype = {
	write_str: function(s) {
		this.length += s.length;
		assert(typeof s == 'string');
		this.entries.push(s);
	},
	write_buf: function(buf) {
		this.length += buf.length;
		assert(buf instanceof Uint8Array, 'Expected a Uint8Array, but got ' + JSON.stringify(buf));
		this.entries.push(buf);
	},
	get_uint8array: function() {
		var res = new Uint8Array(this.length);
		var pos = 0;
		this.entries.forEach(function(e) {
			if (typeof e == 'string') {
				for (var i = 0,slen = e.length;i < slen;i++,pos++) {
					res[pos] = e.charCodeAt(i);
				}
			} else {
				res.set(e, pos);
				pos += e.length;
			}
		});
		assert(pos == this.length);
		return res;
	},
	position: function() {
		return this.length;
	},
};

// Code from pdf.utils.js (ASL2) starts here
function pad(num, length) {
  var ret = num + '';
  while (ret.length < length) {
	ret = '0' + ret;
  }
  return ret;
}

function hasSpecialChar(str) {
  for (var i = 0, ii = str.length; i < ii; i++) {
	switch (str[i]) {
	case '(':
	case ')':
	case '\\':
	case '\n':
	case '\r':
	case '\t':
	case '\b':
	case '\f':
		return true;
	}
  }
  return false;
}

function serialize(node, uncompressed) {
	var i, ret;  // Wishing for let in modern browsers :(
	if (minipdf.isRef(node)) {
		return node.num + ' ' + node.gen + ' R';
	} else if (minipdf.isNum(node)) {
		return node;
	} else if (minipdf.isBool(node)) {
		return node;
	} else if (minipdf.isName(node)) {
		assert(node.name);
		return '/' + node.name;
	} else if (minipdf.isString(node)) {
		if (!hasSpecialChar(node)) {
			return '(' + node + ')';
		} else {
			ret = '<';
			for (i = 0; i < node.length; i++) {
				ret += pad(node.charCodeAt(i).toString(16), 2);
			}
			return ret + '>';
		}
	} else if (minipdf.isArray(node)) {
		ret = ['['];
		for (i = 0; i < node.length; i++) {
			ret.push(serialize(node[i], uncompressed));
		}
		ret.push(']');
		return ret.join(' ');
	} else if (minipdf.isDict(node)) {
		var map = node.map;
		ret = ['<<'];
		for (var key in map) {
			ret.push('/' + key + ' ' + serialize(map[key], uncompressed));
		}
		ret.push('>>');
		return ret.join('\n');
	} else if (minipdf.isStream(node)) {
		ret = '';
		delete node.dict.map.DecodeParms;
		delete node.dict.map.Filter;

		var content = node.getBytes();
		assert(content, 'expecting byte content from ' + JSON.stringify(node));
		var out;
		if (uncompressed) {
			out = minipdf.buf2str(content);
			node.dict.map.Length = out.length;
		} else {
			out = minipdf.buf2str(pako.deflate(content));
			node.dict.map.Length = out.length;
			node.dict.map.Filter = [new minipdf.Name('FlateDecode')];
		}

		assert(minipdf.isDict(node.dict));
		ret += serialize(node.dict, uncompressed);
		ret += '\nstream\n';
		ret += out;
		ret += '\nendstream\n';
		return ret;
	} else {
		throw new Error('Unknown node type ' + JSON.stringify(node));
	}
  }

// End of code from pdf.utils.js

function PDFObjects(doc) {
	this.entries = doc.get_xref_entries();
	assert(minipdf.isArray(this.entries), 'xref entries should be an Array');
}
PDFObjects.prototype = {
add: function(obj, gen) {
	var e = {
		obj: obj,
		gen: gen,
		num: this.entries.length,
		uncompressed: 'added',
	};
	this.entries.push(e);
	return e;
},
update: function(ref, obj) {
	assert(ref.num !== undefined);
	assert(ref.gen !== undefined);
	var e = {
		obj: obj,
		gen: ref.gen,
		num: ref.num,
		uncompressed: 'added',
	};
	this.entries[e.num] = e;
	return e;
},
write_object: function(out, e, uncompressed) {
	e.offset = out.position();
	assert(e.num !== undefined);
	var bs = serialize(e.obj, uncompressed);
	out.write_str(e.num + ' ' + e.gen + ' obj\n');
	out.write_str(bs);
	out.write_str('\nendobj\n');
},
write_xref_stream: function(out, prev, root_ref) {
	var map = {
		Type: new minipdf.Name('XRef'),
		Size: this.entries.length + 1, // + 1 for this object itself
		Length: 6 * (this.entries.length + 1),
		Root: root_ref,
		W: [1, 4, 1],
	};
	if (prev !== undefined) {
		map.Prev = prev;
	}

	var bio = new BytesIO();
	var entry = this.add('__xref_stream__', 0);
	entry.offset = out.position();
	this.entries.forEach(function(e) {
		assert(e.offset !== undefined, 'entry should have an offset');
		bio.write_buf(new Uint8Array([
			(e.uncompressed ? 1 : 2),
			(e.offset >> 24),
			(e.offset >> 16) & 0xff,
			(e.offset >> 8) & 0xff,
			e.offset & 0xff,
			e.gen,
		]));
	});
	var ui8ar = bio.get_uint8array();

	var stream = minipdf.newStream(map, ui8ar);
	entry.obj = stream;
	this.write_object(out, entry, true);
},
};

function visit_acroform_fields(doc, callback) {
	var to_visit = doc.acroForm.map.Fields.slice();
	while (to_visit.length > 0) {
		var n = to_visit.shift();
		if (minipdf.isRef(n)) {
			var ref = n;
			n = doc.fetch(n);
			n._pdfform_ref = ref;
		}

		if (n.map && n.map.Kids) {
			to_visit.push.apply(to_visit, n.map.Kids);
		} else if (n.map && n.map.Type && n.map.Type.name == 'Annot') {
			callback(n);
		}
	}
}

function pdf_decode_str(str) {
	if (! str.startsWith('\u00FE\u00FF')) {
		return str;
	}
    var res = '';
	for (var i = 2; i < str.length; i += 2) {
		res += String.fromCharCode(str.charCodeAt(i) << 8 | str.charCodeAt(i + 1));
	}
	return res;
}

function acroform_match_spec(n, fields) {
	var t = pdf_decode_str(n.map.T);
	if (t in fields) {
		return fields[t][0];
	} else {
		var m = /^(.*)\[([0-9]+)\]$/.exec(t);
		if (m && (m[1] in fields)) {
			return fields[m[1]][m[2]];
		}
	}
	return undefined;
}

function modify_xfa(doc, objects, out, index, callback) {
	var xfa = doc.acroForm.map.XFA;
	var section_idx = xfa.indexOf(index);
	assert(section_idx >= 0);
	var section_ref = xfa[section_idx + 1];
	var section_node = doc.fetch(section_ref);
	assert(minipdf.isStream(section_node), 'XFA section node should be a stream');
	var bs = section_node.getBytes();
	assert(bs);
	var str = (new TextDecoder('utf-8')).decode(bs);

	str = callback(str);

	var out_bs = (new TextEncoder('utf-8').encode(str));
	var out_node = minipdf.newStream(section_node.dict.map, out_bs);
	assert(minipdf.isStream(out_node));

	var e = objects.update(section_ref, out_node);
	objects.write_object(out, e);
}

function transform(data, fields) {
	var doc = minipdf.parse(new Uint8Array(data));
	var objects = new PDFObjects(doc);

	var out = new BytesIO();
	out.write_buf(data);

	// Change AcroForms
	visit_acroform_fields(doc, function(n) {
		var spec = acroform_match_spec(n, fields);
		if (spec === undefined) {
			return;
		}

		if (n.map.FT.name == 'Tx') {
			n.map.V = '' + spec;
		} else if (n.map.FT.name == 'Btn') {
			n.map.AS = n.map.V = n.map.DV = spec ? new minipdf.Name('Yes') : new minipdf.Name('Off');
		} else {
			throw new Error('Unsupported input type' + n.map.FT.name);
		}

		var ref = n._pdfform_ref;
		var e = objects.update(ref, n);
		objects.write_object(out, e);
	});
	// Set NeedAppearances in AcroForm dict
	var acroform_ref = doc.get_acroform_ref();
	doc.acroForm.map.NeedAppearances = true;
	var e = objects.update(acroform_ref, doc.acroForm);
	objects.write_object(out, e);

	// Change XFA
	modify_xfa(doc, objects, out, 'datasets', function(str) {
		// Fix up XML
		str = str.replace(/\n(\/?>)/g, '$1\n');

		var ds_doc = new DOMParser().parseFromString(str, "application/xml");
		for (var f in fields) {
			var els = ds_doc.getElementsByTagName(f);

			for (var i = 0;i < els.length;i++) {
				var val = fields[f][i];
				if (val === undefined) {
					continue;
				}
				var el = els[i];
				while (el.firstChild) {
					el.removeChild(el.firstChild);
				}

				if (typeof val == 'boolean') {
					val = val ? 1 : 0;
				}
				el.appendChild(ds_doc.createTextNode(val));
			}
		}

		str = new XMLSerializer().serializeToString(ds_doc);
		return str;
	});

	var startxref = out.position();
	var root_id = doc.get_root_id();
	var root_ref = new minipdf.Ref(root_id, 0);
	objects.write_xref_stream(out, doc.startXRef, root_ref);

	out.write_str('startxref\n');
	out.write_str(startxref + '\n');
	out.write_str('%%EOF');

	return out.get_uint8array();
}

return {
	transform: transform,
};
})();

if (typeof module != 'undefined') {
	module.exports = pdfform;
}<|endoftext|>


<commit_before>#!/usr/bin/env node

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Populate the database with accounts, session tokens and devices,
// so that each new account is linked to either one, two or three
// sessions and devices.
//
// Usage:
//
//     node scripts/populate-session-tokens n
//
// Where *n* is the number of accounts to create.

var log = { trace: console.log, error: console.error, stat: console.log, info: console.log } //eslint-disable-line no-console
var DB = require('../lib/db/mysql')(log, require('../fxa-auth-db-server').errors)
var config = require('../config')
var crypto = require('crypto')

var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex')
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex')

var count = parseInt(process.argv[2])

if (count > 0) {
  DB.connect(config).then(function (db) {
    iterate(0)

    function iterate (index) {
      if (index === count) {
        db.close()
        return log.info('Done: ' + index)
      }

      createRecords(index).then(iterate.bind(null, index + 1))
    }

    function createRecords (index) {
      var uid = crypto.randomBytes(16)
      return createAccount(uid)
        .then(function () {
          if (index % 6 === 0) {
            // One sixth of accounts will have three session tokens
            // and three devices. Two of the devices are attached to
            // a session token, the other one isn't.
            return createSessionTokenAndDevice(uid, 'mobile')
              .then(createSessionToken.bind(null, uid, null))
              .then(createSessionTokenAndDevice.bind(null, uid, 'mobile'))
              .then(createDevice.bind(null, uid, null, 'mobile'))
          } else if (index % 3 === 0) {
            // One sixth of accounts will have two session tokens
            // and two devices. One of the devices is attached to
            // a session token, the other one isn't.
            return createSessionToken(uid, null)
              .then(createSessionTokenAndDevice.bind(null, uid, 'mobile'))
              .then(createDevice.bind(null, uid, null, null))
          } else {
            // Two thirds of accounts will have one session token
            // and one device, connected to the session token.
            return createSessionTokenAndDevice(uid, null)
          }
        })
        .catch(function (error) {
          log.error(error)
        })
    }

    function createAccount (uid) {
      var time = Date.now()
      var email = (Math.random() + '').substr(2) + '@dummy.org'
      return db.createAccount(uid, {
        email: email,
        normalizedEmail: email.toLowerCase(),
        emailCode: zeroBuffer16,
        emailVerified: true,
        verifierVersion: 1,
        verifyHash: zeroBuffer32,
        authSalt: zeroBuffer32,
        kA: zeroBuffer32,
        wrapWrapKb: zeroBuffer32,
        verifierSetAt: time,
        createdAt: time,
        locale: 'en_US'
      })
    }

    function createSessionTokenAndDevice (uid, uaDeviceType) {
      return createSessionToken(uid, uaDeviceType).then(function (sessionTokenId) {
        return createDevice(uid, sessionTokenId, uaDeviceType)
      })
    }

    function createSessionToken (uid, uaDeviceType) {
      var sessionTokenId = hex(32)
      return db.createSessionToken(sessionTokenId, {
        data: hex(32),
        uid: uid,
        createdAt: Date.now(),
        uaBrowser: 'foo',
        uaBrowserVersion: 'bar',
        uaOS: 'baz',
        uaOSVersion: 'qux',
        uaDeviceType: uaDeviceType
      }).then(function () {
        return sessionTokenId
      })
    }

    function hex (length) {
      return crypto.randomBytes(length)
    }

    function createDevice (uid, sessionTokenId, uaDeviceType) {
      return db.createDevice(uid, hex(16), {
        sessionTokenId: sessionTokenId,
        name: 'fake device name',
        type: uaDeviceType,
        createdAt: Date.now()
      })
    }
  }).catch(function (err) {
    log.error(err.stack || err.message || err)
  })
} else {
  throw new Error('Invalid argument')
}

<commit_msg>fix(scripts): add process.exit to populate script<commit_after>#!/usr/bin/env node

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Populate the database with accounts, session tokens and devices,
// so that each new account is linked to either one, two or three
// sessions and devices.
//
// Usage:
//
//     node scripts/populate-session-tokens n
//
// Where *n* is the number of accounts to create.

var log = { trace: console.log, error: console.error, stat: console.log, info: console.log } //eslint-disable-line no-console
var DB = require('../lib/db/mysql')(log, require('../fxa-auth-db-server').errors)
var config = require('../config')
var crypto = require('crypto')

var zeroBuffer16 = Buffer('00000000000000000000000000000000', 'hex')
var zeroBuffer32 = Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex')

var count = parseInt(process.argv[2])

if (count > 0) {
  DB.connect(config).then(function (db) {
    iterate(0)

    function iterate (index) {
      if (index === count) {
        db.close()
        return log.info('Done: ' + index)
      }

      createRecords(index).then(iterate.bind(null, index + 1))
    }

    function createRecords (index) {
      var uid = crypto.randomBytes(16)
      return createAccount(uid)
        .then(function () {
          if (index % 6 === 0) {
            // One sixth of accounts will have three session tokens
            // and three devices. Two of the devices are attached to
            // a session token, the other one isn't.
            return createSessionTokenAndDevice(uid, 'mobile')
              .then(createSessionToken.bind(null, uid, null))
              .then(createSessionTokenAndDevice.bind(null, uid, 'mobile'))
              .then(createDevice.bind(null, uid, null, 'mobile'))
          } else if (index % 3 === 0) {
            // One sixth of accounts will have two session tokens
            // and two devices. One of the devices is attached to
            // a session token, the other one isn't.
            return createSessionToken(uid, null)
              .then(createSessionTokenAndDevice.bind(null, uid, 'mobile'))
              .then(createDevice.bind(null, uid, null, null))
          } else {
            // Two thirds of accounts will have one session token
            // and one device, connected to the session token.
            return createSessionTokenAndDevice(uid, null)
          }
        })
        .catch(function (error) {
          log.error(error)
        })
    }

    function createAccount (uid) {
      var time = Date.now()
      var email = (Math.random() + '').substr(2) + '@dummy.org'
      return db.createAccount(uid, {
        email: email,
        normalizedEmail: email.toLowerCase(),
        emailCode: zeroBuffer16,
        emailVerified: true,
        verifierVersion: 1,
        verifyHash: zeroBuffer32,
        authSalt: zeroBuffer32,
        kA: zeroBuffer32,
        wrapWrapKb: zeroBuffer32,
        verifierSetAt: time,
        createdAt: time,
        locale: 'en_US'
      })
    }

    function createSessionTokenAndDevice (uid, uaDeviceType) {
      return createSessionToken(uid, uaDeviceType).then(function (sessionTokenId) {
        return createDevice(uid, sessionTokenId, uaDeviceType)
      })
    }

    function createSessionToken (uid, uaDeviceType) {
      var sessionTokenId = hex(32)
      return db.createSessionToken(sessionTokenId, {
        data: hex(32),
        uid: uid,
        createdAt: Date.now(),
        uaBrowser: 'foo',
        uaBrowserVersion: 'bar',
        uaOS: 'baz',
        uaOSVersion: 'qux',
        uaDeviceType: uaDeviceType
      }).then(function () {
        return sessionTokenId
      })
    }

    function hex (length) {
      return crypto.randomBytes(length)
    }

    function createDevice (uid, sessionTokenId, uaDeviceType) {
      return db.createDevice(uid, hex(16), {
        sessionTokenId: sessionTokenId,
        name: 'fake device name',
        type: uaDeviceType,
        createdAt: Date.now()
      })
    }
  }).catch(function (err) {
    log.error(err.stack || err.message || err)
    process.exit()
  })
} else {
  throw new Error('Invalid argument')
}

<|endoftext|>


<commit_before>var ClientSocket = require('./client_socket');
var ServerSocket = require('./server_socket');

function Socket_firefox(cap, dispatchEvent, socketId) {
  var incomingConnections = Socket_firefox.incomingConnections;
  this.dispatchEvent = dispatchEvent;
  this.socketId = socketId;
  if (socketId in incomingConnections) {
    this.clientSocket = incomingConnections[socketId];
    delete incomingConnections[socketId];
    this.clientSocket.setOnDataListener(this._onData.bind(this));
  }
}

Socket_firefox.incomingConnections = {};
Socket_firefox.socketNumber = 1;

Socket_firefox.prototype.getInfo = function(continuation) {
  if(this.clientSocket) {
    continuation(this.clientSocket.getInfo());
  } else if (this.serverSocket) {
    continuation(this.serverSocket.getInfo());
  }
};

Socket_firefox.prototype.close = function(continuation) {
  if (!this.clientSocket && !this.serverSocket) {
    continuation(undefined, {
    "errcode": "SOCKET_CLOSED",
    "message": "Cannot close non-connected socket"
    });
  } else if(this.clientSocket) {
    this.clientSocket.close();
  } else if (this.serverSocket) {
    this.serverSocket.disconnect();
  } else {
    continuation(undefined, {
      'errcode': 'SOCKET_CLOSED',
      'message': 'Socket Already Closed, or was never opened'
    });
    return;
  }
  continuation();
};

// TODO: handle failures.
Socket_firefox.prototype.connect = function(hostname, port, continuation) {
  this.clientSocket = new ClientSocket();
  this.clientSocket.onDisconnect = function(err) {
    this.dispatchEvent("onDisconnect", err);
  }.bind(this);
  this.clientSocket.setOnDataListener(this._onData.bind(this));
  this.clientSocket.connect(hostname, port, false, continuation);
  this.hostname = hostname;
  this.port = port;
};

Socket_firefox.prototype.prepareSecure = function(continuation) {
  continuation();
};

// TODO: handle failures.
Socket_firefox.prototype.secure = function(continuation) {
  if (!this.hostname || !this.port || !this.clientSocket) {
    continuation(undefined, {
      "errcode": "NOT_CONNECTED",
      "message": "Cannot secure non-connected Socket"
    });
    return;
  }
  // Create a new ClientSocket (nsISocketTransport) object for the existing
  // hostname and port, using type 'starttls'.  This will upgrade the existing
  // connection to TLS, rather than create a new connection.
  // TODO: check to make sure this doesn't result in weird race conditions if
  // we have 2 pieces of code both trying to connect to the same hostname/port
  // and do a starttls flow (e.g. if there are 2 instances of a GTalk social
  // provider that are both trying to connect to GTalk simultaneously with
  // different logins).
  this.clientSocket.onDisconnect = undefined;  // avoid undesired dispatching
  this.clientSocket = new ClientSocket();
  // TODO: DRY this code up (see 'connect' above)
  this.clientSocket.onDisconnect = function(err) {
    this.dispatchEvent("onDisconnect", err);
  }.bind(this);
  this.clientSocket.setOnDataListener(this._onData.bind(this));
  this.clientSocket.connect(this.hostname, this.port, true);
  continuation();
};

Socket_firefox.prototype.write = function(buffer, continuation) {
  if (!this.clientSocket) {
    continuation(undefined, {
      "errcode": "NOT_CONNECTED",
      "message": "Cannot write non-connected socket"
    });
  } else {
    this.clientSocket.write(buffer);
    continuation();
  }
};

Socket_firefox.prototype.pause = function(continuation) {
  if (!this.clientSocket) {
    continuation(undefined, {
      "errcode": "NOT_CONNECTED",
      "message": "Can only pause a connected client socket"
    });
  } else {
    this.clientSocket.pause();
    continuation();
  }
};

Socket_firefox.prototype.resume = function(continuation) {
  if (!this.clientSocket) {
    continuation(undefined, {
      "errcode": "NOT_CONNECTED",
      "message": "Can only resume a connected client socket"
    });
  } else {
    this.clientSocket.resume();
    continuation();
  }
};

Socket_firefox.prototype.listen = function(host, port, continuation) {
  if (typeof this.serverSocket !== 'undefined') {
    continuation(undefined, {
      "errcode": "ALREADY_CONNECTED",
      "message": "Cannot listen on existing socket."
    });
  } else {
    try {
      this.serverSocket = new ServerSocket(host, port);
      this.host = host;
      this.port = port;
      this.serverSocket.onConnect = this._onConnect.bind(this);
      this.serverSocket.onDisconnect = function(err) {
        this.dispatchEvent("onDisconnect", err);
      }.bind(this);
      this.serverSocket.listen();
      continuation();
    } catch (e) {
      continuation(undefined, {
        "errcode": "UNKNOWN",
        "message": e.message
      });
    }
  }
};

Socket_firefox.prototype._onData = function(buffer) {
  this.dispatchEvent("onData",
                     {data: buffer.buffer});
};

Socket_firefox.prototype._onConnect = function(clientSocket) {
  var socketNumber = Socket_firefox.socketNumber++;
  Socket_firefox.incomingConnections[socketNumber] = clientSocket;
  this.dispatchEvent("onConnection", { socket: socketNumber,
                                       host: this.host,
                                       port: this.port
                                     });

};

/** REGISTER PROVIDER **/
exports.provider = Socket_firefox;
exports.name = "core.tcpsocket";
<commit_msg>pass socket reusing id of closed socket is also closed<commit_after>var ClientSocket = require('./client_socket');
var ServerSocket = require('./server_socket');

function Socket_firefox(cap, dispatchEvent, socketId) {
  var incomingConnections = Socket_firefox.incomingConnections;
  this.dispatchEvent = dispatchEvent;
  this.socketId = socketId;
  if (socketId in incomingConnections) {
    this.clientSocket = incomingConnections[socketId];
    delete incomingConnections[socketId];
    this.clientSocket.setOnDataListener(this._onData.bind(this));
    delete this.clientSocket.transport;  // new socket shouldn't be connected
  }
}

Socket_firefox.incomingConnections = {};
Socket_firefox.socketNumber = 1;

Socket_firefox.prototype.getInfo = function(continuation) {
  if(this.clientSocket) {
    continuation(this.clientSocket.getInfo());
  } else if (this.serverSocket) {
    continuation(this.serverSocket.getInfo());
  }
};

Socket_firefox.prototype.close = function(continuation) {
  if (!this.clientSocket && !this.serverSocket) {
    continuation(undefined, {
    "errcode": "SOCKET_CLOSED",
    "message": "Cannot close non-connected socket"
    });
  } else if(this.clientSocket) {
    this.clientSocket.close();
  } else if (this.serverSocket) {
    this.serverSocket.disconnect();
  } else {
    continuation(undefined, {
      'errcode': 'SOCKET_CLOSED',
      'message': 'Socket Already Closed, or was never opened'
    });
    return;
  }
  continuation();
};

// TODO: handle failures.
Socket_firefox.prototype.connect = function(hostname, port, continuation) {
  this.clientSocket = new ClientSocket();
  this.clientSocket.onDisconnect = function(err) {
    this.dispatchEvent("onDisconnect", err);
  }.bind(this);
  this.clientSocket.setOnDataListener(this._onData.bind(this));
  this.clientSocket.connect(hostname, port, false, continuation);
  this.hostname = hostname;
  this.port = port;
};

Socket_firefox.prototype.prepareSecure = function(continuation) {
  continuation();
};

// TODO: handle failures.
Socket_firefox.prototype.secure = function(continuation) {
  if (!this.hostname || !this.port || !this.clientSocket) {
    continuation(undefined, {
      "errcode": "NOT_CONNECTED",
      "message": "Cannot secure non-connected Socket"
    });
    return;
  }
  // Create a new ClientSocket (nsISocketTransport) object for the existing
  // hostname and port, using type 'starttls'.  This will upgrade the existing
  // connection to TLS, rather than create a new connection.
  // TODO: check to make sure this doesn't result in weird race conditions if
  // we have 2 pieces of code both trying to connect to the same hostname/port
  // and do a starttls flow (e.g. if there are 2 instances of a GTalk social
  // provider that are both trying to connect to GTalk simultaneously with
  // different logins).
  this.clientSocket.onDisconnect = undefined;  // avoid undesired dispatching
  this.clientSocket = new ClientSocket();
  // TODO: DRY this code up (see 'connect' above)
  this.clientSocket.onDisconnect = function(err) {
    this.dispatchEvent("onDisconnect", err);
  }.bind(this);
  this.clientSocket.setOnDataListener(this._onData.bind(this));
  this.clientSocket.connect(this.hostname, this.port, true);
  continuation();
};

Socket_firefox.prototype.write = function(buffer, continuation) {
  if (!this.clientSocket) {
    continuation(undefined, {
      "errcode": "NOT_CONNECTED",
      "message": "Cannot write non-connected socket"
    });
  } else {
    this.clientSocket.write(buffer);
    continuation();
  }
};

Socket_firefox.prototype.pause = function(continuation) {
  if (!this.clientSocket) {
    continuation(undefined, {
      "errcode": "NOT_CONNECTED",
      "message": "Can only pause a connected client socket"
    });
  } else {
    this.clientSocket.pause();
    continuation();
  }
};

Socket_firefox.prototype.resume = function(continuation) {
  if (!this.clientSocket) {
    continuation(undefined, {
      "errcode": "NOT_CONNECTED",
      "message": "Can only resume a connected client socket"
    });
  } else {
    this.clientSocket.resume();
    continuation();
  }
};

Socket_firefox.prototype.listen = function(host, port, continuation) {
  if (typeof this.serverSocket !== 'undefined') {
    continuation(undefined, {
      "errcode": "ALREADY_CONNECTED",
      "message": "Cannot listen on existing socket."
    });
  } else {
    try {
      this.serverSocket = new ServerSocket(host, port);
      this.host = host;
      this.port = port;
      this.serverSocket.onConnect = this._onConnect.bind(this);
      this.serverSocket.onDisconnect = function(err) {
        this.dispatchEvent("onDisconnect", err);
      }.bind(this);
      this.serverSocket.listen();
      continuation();
    } catch (e) {
      continuation(undefined, {
        "errcode": "UNKNOWN",
        "message": e.message
      });
    }
  }
};

Socket_firefox.prototype._onData = function(buffer) {
  this.dispatchEvent("onData",
                     {data: buffer.buffer});
};

Socket_firefox.prototype._onConnect = function(clientSocket) {
  var socketNumber = Socket_firefox.socketNumber++;
  Socket_firefox.incomingConnections[socketNumber] = clientSocket;
  this.dispatchEvent("onConnection", { socket: socketNumber,
                                       host: this.host,
                                       port: this.port
                                     });

};

/** REGISTER PROVIDER **/
exports.provider = Socket_firefox;
exports.name = "core.tcpsocket";
<|endoftext|>


<commit_before>var Backbone = require('backbone');
var CategoriesListView = require('../../../../../../../../../../javascripts/cartodb3/components/form-components/editors/fill/input-color/input-categories/input-color-categories-list-view/input-color-categories-list-view');

describe('components/form-components/editors/fill/input-color/input-categories/input-color-categories-list-view/input-color-categories-list-view', function () {
  var view;
  var model;

  describe('when the attribute is boolean', function () {
    beforeEach(function () {
      model = new Backbone.Model({
        type: 'color',
        attribute: 'fake_boolean_attribute',
        attribute_type: 'boolean',
        images: ['', ''],
        range: ['#5F4690', '#1D6996'],
        domain: [true, false],
        selected: true
      });

      view = new CategoriesListView({
        maxValues: 10,
        model: model,
        imageEnabled: false
      });

      view.render();
    });

    describe('.render', function () {
      it('should have a back button', function () {
        expect(view.$('.js-back')).toBeDefined();
      });

      it('should back button should have the "Color schemes" label', function () {
        expect(view.$('.label').text().trim()).toEqual('Color Schemes');
      });

      it('should be properly rendered', function () {
        pending('IMPLEMENT ME');
      });

      it('should be properly rendered when there are null values', function () {
        pending('IMPLEMENT ME');
      });
    });

    afterEach(function () {
      view.remove();
    });
  });

  describe('when the attribute is numeric', function () {
    it('.render', function () {
      pending('IMPLEMENT ME');
    });
  });

  describe('when the attribute is string', function () {
    it('.render', function () {
      pending('IMPLEMENT ME');
    });
  });

  describe('when the attribute is a date', function () {
    it('.render', function () {
      pending('IMPLEMENT ME');
    });
  });

  // TODO: Add test for edge cases: (ie: more than 11 values un attribute domain)
});
<commit_msg>Fix conflicts<commit_after>var Backbone = require('backbone');
var CategoriesListView = require('../../../../../../../../../../javascripts/cartodb3/components/form-components/editors/fill/input-color/input-categories/input-color-categories-list-view/input-color-categories-list-view');

describe('components/form-components/editors/fill/input-color/input-categories/input-color-categories-list-view/input-color-categories-list-view', function () {
  var view;
  var model;

  describe('when the attribute is boolean', function () {
    beforeEach(function () {
      model = new Backbone.Model({
        type: 'color',
        attribute: 'fake_boolean_attribute',
        attribute_type: 'boolean',
        images: ['', ''],
        range: ['#000000', '#1D6996'],
        domain: [true, false],
        selected: true
      });

      view = new CategoriesListView({
        maxValues: 10,
        model: model,
        imageEnabled: false
      });

      view.render();
    });

    describe('.render', function () {
      it('should have a back button', function () {
        expect(view.$('.js-back')).toBeDefined();
      });

      it('should back button should have the "Color schemes" label', function () {
        expect(view.$('.label').text().trim()).toEqual('Color Schemes');
      });

      it('should be properly rendered', function () {
        expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(model.get('range')[0]);
        expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(model.get('range')[1]);
        expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(undefined);
      });

      it('should be properly rendered when there are null values', function () {
        var model = new Backbone.Model({
          type: 'color',
          attribute: 'fake_boolean_attribute',
          attribute_type: 'boolean',
          images: ['', ''],
          range: ['#5F4690', '#1D6996', '#FFFFFF'],
          domain: [true, false, null],
          selected: true
        });

        var view = new CategoriesListView({
          maxValues: 10,
          model: model,
          imageEnabled: false
        });

        view.render();
        expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(model.get('range')[0]);
        expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(model.get('range')[1]);
        expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(model.get('range')[2]);
        view.remove();
      });
    });

    afterEach(function () {
      view.remove();
    });
  });

  describe('when the attribute is numeric', function () {
    it('.render', function () {
      pending('IMPLEMENT ME');
    });
  });

  describe('when the attribute is string', function () {
    it('.render', function () {
      pending('IMPLEMENT ME');
    });
  });

  describe('when the attribute is a date', function () {
    it('.render', function () {
      pending('IMPLEMENT ME');
    });
  });

  // TODO: Add test for edge cases: (ie: more than 11 values un attribute domain)
});
<|endoftext|>


<commit_before>//var XMLHttpRequest = require('freedom-xhr').corexhr;
// Included directly in freedom module. node-forge not browserify-friendly
//var forge = require('node-forge')({ disableNativeCode: true });

var STATUS_CODES = {
  "START": "Starting provisioner",
  "OAUTH_INIT": "Initializing oauth flow",
  "OAUTH_ERROR": "Error getting oauth token",
  "OAUTH_COMPLETE": "Got oauth token",
  "SSHKEY_RETRIEVED": "Retrieved SSH keys from storage",
  "SSHKEY_GENERATED": "Generated new SSH keys",
  "CLOUD_FAILED": "Failed to complete cloud operation",
  "CLOUD_INIT_ADDKEY": "Starting to add SSH key to cloud account",
  "CLOUD_DONE_ADDKEY": "Done adding SSH key to cloud account",
  "CLOUD_INIT_GETVM": "Starting to get all VMs",
  "CLOUD_DONE_GETVM": "Done getting all VMs",

};

var REDIRECT_URIS = [
  "https://kmnjcbmibpajfljogomikcdlmhgpnolg.chromiumapp.org"
  //  "http://localhost:10101"
];

var Provisioner = function(dispatchEvent) {
  this.dispatch = dispatchEvent;
  this.state = {};
};

Provisioner.prototype._sendStatus = function(code) {
  this.dispatch("status", {
    "code": code,
    "message": STATUS_CODES[code]
  });
};

/*
 * Generates an RSA keypair using forge
 */
Provisioner.prototype._generateKeyPair = function() {
  "use strict";
  var pair = forge.pki.rsa.generateKeyPair({bits: 1024, e: 0x10001});  // TODO: use async
  var publicKey = forge.ssh.publicKeyToOpenSSH(pair.publicKey, 'info@uproxy.org');
  var privateKey = forge.ssh.privateKeyToOpenSSH(pair.privateKey, '');
  return { public: publicKey, private: privateKey };
}

Provisioner.prototype._doOAuth = function() {
  return new Promise(function(resolve, reject) {
    var oauth = freedom["core.oauth"]();

    this._sendStatus("OAUTH_INIT");
    oauth.initiateOAuth(REDIRECT_URIS).then(function(obj) {
      var url = "https://cloud.digitalocean.com/v1/oauth/authorize?" +
                "client_id=c16837b5448cd6cf2582d2c2f767cfb7d11844ec395a91b43f26ca72513416c8&" +
                "response_type=token&" +
                "redirect_uri=" + encodeURIComponent(obj.redirect) + "&" +
                "state=" + encodeURIComponent(obj.state) + "&" +
                "scope=read%20write";
      return oauth.launchAuthFlow(url, obj);
    }).then(function(responseUrl) {
      var query = responseUrl.substr(responseUrl.indexOf('#') + 1),
        param,
        params = {},
        keys = query.split('&'),
        i = 0;

      for (i = 0; i < keys.length; i += 1) {
        param = keys[i].substr(0, keys[i].indexOf('='));
        params[param] = keys[i].substr(keys[i].indexOf('=') + 1);
      }

      this._sendStatus("OAUTH_COMPLETE");
      resolve(params);
    }.bind(this)).catch(function(err) {
      console.error("oauth error: " + JSON.stringify(err));
      reject(err)
    }.bind(this));
  }.bind(this));
};

Provisioner.prototype._getSshKey = function(name) {
  var storage = freedom["core.storage"]();
  return new Promise(function(resolve, reject) {
    var result = {};

    Promise.all([
      storage.get("DigitalOcean-" + name + "-PublicKey"),
      storage.get("DigitalOcean-" + name + "-PrivateKey")
    ]).then(function(val) {
      if (val[0] === null ||
         val[1] === null) {
        result = this._generateKeyPair();
        storage.set("DigitalOcean-" + name + "-PublicKey", result.public);
        storage.set("DigitalOcean-" + name + "-PrivateKey", result.private);
        this._sendStatus("SSHKEY_GENERATED");
      } else {
        result.public = val[0];
        result.private = val[1];
        this._sendStatus("SSHKEY_RETRIEVED");
      }
      resolve(result);
    }.bind(this)).catch(function(err) {
      console.error("storage error: " + JSON.stringify(err));
      reject(err);
    });
  }.bind(this));
};

Provisioner.prototype._doRequest = function(method, actionPath, body) {
  return new Promise(function(resolve, reject) {
    var url = 'https://api.digitalocean.com/v2/' + actionPath;
    var xhr = freedom["core.xhr"]()
    xhr.on("onload", function(resolve, reject, xhr, e) {
      xhr.getResponseText().then(function(resolve, reject, resp){
        try {
          var json = JSON.parse(resp);
          resolve(json);
        } catch(e) {
          reject(e);
        }
      }.bind(this, resolve, reject));
    }.bind(this, resolve, reject, xhr));
    xhr.on("onerror", reject);
    xhr.on("ontimeout", reject);
    xhr.open(method, url, true);
    xhr.setRequestHeader("Authorization", "Bearer " + this.state.oauth.access_token);
    xhr.setRequestHeader("Content-Type", "application/json");
    if (body !== null && typeof body !== "undefined") {
      xhr.send({ string: body })
    } else {
      xhr.send(null);
    }
  }.bind(this));
};

Provisioner.prototype._setupDigitalOcean = function(name) {
  return new Promise(function(resolve, reject) {

    /**
    this._sendStatus("CLOUD_INIT_GETVM");
    this._doRequest("GET", "droplets").then(function(response) {
      this._sendStatus("CLOUD_DONE_GETVM");
      console.log(response);

      resolve(response);
    }.bind(this))**/
   /**
    .then(function(response) {
      console.log(response);
    }.bind(this))
    **/
    this._doRequest("GET", "account/keys").then(function(cloudSshKeys) {
      console.log(cloudSshKeys);
      for (var i = 0; i < cloudSshKeys.ssh_keys.length; i++) {
        if (cloudSshKeys.ssh_keys[i].public_key === this.state.ssh.public) {
          return Promise.resolve({
            message: "SSH Key is already in use on your account",
            ssh_key: cloudSshKeys.ssh_keys[i]
          });
        }
      }
      return this._doRequest("POST", "account/keys", JSON.stringify({
        name: name,
        public_key: this.state.ssh.public
      }));
    }.bind(this)).then(function(sshKey) {
      console.log(sshKey);
      resolve();
    }.bind(this)).catch(function(err) {
      console.error("Error w/DigitalOcean: " + err);
      this._sendStatus("CLOUD_FAILED");
      reject({
        errcode: "",
        message: JSON.stringify(err)
      });
    }.bind(this));
  }.bind(this));
}

Provisioner.prototype.start = function(name) {
  this._sendStatus("START");
  return this._doOAuth().then(function(oauthObj) {
    this.state.oauth = oauthObj;
    return this._getSshKey(name);
  }.bind(this)).then(function(keys) {
    this.state.ssh = keys;
    return this._setupDigitalOcean(name);
  }.bind(this)).then(function() {
    console.log(this.state);
    return this.state;
  }.bind(this));
}

freedom().providePromises(Provisioner);
<commit_msg>creating droplets<commit_after>//var XMLHttpRequest = require('freedom-xhr').corexhr;
// Included directly in freedom module. node-forge not browserify-friendly
//var forge = require('node-forge')({ disableNativeCode: true });

var STATUS_CODES = {
  "START": "Starting provisioner",
  "OAUTH_INIT": "Initializing oauth flow",
  "OAUTH_ERROR": "Error getting oauth token",
  "OAUTH_COMPLETE": "Got oauth token",
  "SSHKEY_RETRIEVED": "Retrieved SSH keys from storage",
  "SSHKEY_GENERATED": "Generated new SSH keys",
  "CLOUD_FAILED": "Failed to complete cloud operation",
  "CLOUD_INIT_ADDKEY": "Starting to add SSH key to cloud account",
  "CLOUD_DONE_ADDKEY": "Done adding SSH key to cloud account",
  "CLOUD_INIT_GETVM": "Starting to get all VMs",
  "CLOUD_DONE_GETVM": "Done getting all VMs",

};

var REDIRECT_URIS = [
  "https://kmnjcbmibpajfljogomikcdlmhgpnolg.chromiumapp.org"
  //  "http://localhost:10101"
];

var Provisioner = function(dispatchEvent) {
  this.dispatch = dispatchEvent;
  this.state = {};
};

Provisioner.prototype._sendStatus = function(code) {
  this.dispatch("status", {
    "code": code,
    "message": STATUS_CODES[code]
  });
};

/*
 * Generates an RSA keypair using forge
 */
Provisioner.prototype._generateKeyPair = function() {
  "use strict";
  var pair = forge.pki.rsa.generateKeyPair({bits: 1024, e: 0x10001});  // TODO: use async
  var publicKey = forge.ssh.publicKeyToOpenSSH(pair.publicKey, 'info@uproxy.org');
  var privateKey = forge.ssh.privateKeyToOpenSSH(pair.privateKey, '');
  return { public: publicKey, private: privateKey };
}

Provisioner.prototype._doOAuth = function() {
  return new Promise(function(resolve, reject) {
    var oauth = freedom["core.oauth"]();

    this._sendStatus("OAUTH_INIT");
    oauth.initiateOAuth(REDIRECT_URIS).then(function(obj) {
      var url = "https://cloud.digitalocean.com/v1/oauth/authorize?" +
                "client_id=c16837b5448cd6cf2582d2c2f767cfb7d11844ec395a91b43f26ca72513416c8&" +
                "response_type=token&" +
                "redirect_uri=" + encodeURIComponent(obj.redirect) + "&" +
                "state=" + encodeURIComponent(obj.state) + "&" +
                "scope=read%20write";
      return oauth.launchAuthFlow(url, obj);
    }).then(function(responseUrl) {
      var query = responseUrl.substr(responseUrl.indexOf('#') + 1),
        param,
        params = {},
        keys = query.split('&'),
        i = 0;

      for (i = 0; i < keys.length; i += 1) {
        param = keys[i].substr(0, keys[i].indexOf('='));
        params[param] = keys[i].substr(keys[i].indexOf('=') + 1);
      }

      this._sendStatus("OAUTH_COMPLETE");
      resolve(params);
    }.bind(this)).catch(function(err) {
      console.error("oauth error: " + JSON.stringify(err));
      reject(err)
    }.bind(this));
  }.bind(this));
};

Provisioner.prototype._getSshKey = function(name) {
  var storage = freedom["core.storage"]();
  return new Promise(function(resolve, reject) {
    var result = {};

    Promise.all([
      storage.get("DigitalOcean-" + name + "-PublicKey"),
      storage.get("DigitalOcean-" + name + "-PrivateKey")
    ]).then(function(val) {
      if (val[0] === null ||
         val[1] === null) {
        result = this._generateKeyPair();
        storage.set("DigitalOcean-" + name + "-PublicKey", result.public);
        storage.set("DigitalOcean-" + name + "-PrivateKey", result.private);
        this._sendStatus("SSHKEY_GENERATED");
      } else {
        result.public = val[0];
        result.private = val[1];
        this._sendStatus("SSHKEY_RETRIEVED");
      }
      resolve(result);
    }.bind(this)).catch(function(err) {
      console.error("storage error: " + JSON.stringify(err));
      reject(err);
    });
  }.bind(this));
};

Provisioner.prototype._doRequest = function(method, actionPath, body) {
  return new Promise(function(resolve, reject) {
    var url = 'https://api.digitalocean.com/v2/' + actionPath;
    var xhr = freedom["core.xhr"]()
    xhr.on("onload", function(resolve, reject, xhr, e) {
      xhr.getResponseText().then(function(resolve, reject, resp){
        try {
          var json = JSON.parse(resp);
          resolve(json);
        } catch(e) {
          reject(e);
        }
      }.bind(this, resolve, reject));
    }.bind(this, resolve, reject, xhr));
    xhr.on("onerror", reject);
    xhr.on("ontimeout", reject);
    xhr.open(method, url, true);
    xhr.setRequestHeader("Authorization", "Bearer " + this.state.oauth.access_token);
    xhr.setRequestHeader("Content-Type", "application/json");
    if (body !== null && typeof body !== "undefined") {
      xhr.send({ string: body })
    } else {
      xhr.send(null);
    }
  }.bind(this));
};

Provisioner.prototype._setupDigitalOcean = function(name) {
  return new Promise(function(resolve, reject) {

    this._doRequest("GET", "account/keys").then(function(resp) {
      console.log(resp);
      for (var i = 0; i < resp.ssh_keys.length; i++) {
        if (resp.ssh_keys[i].public_key === this.state.ssh.public) {
          return Promise.resolve({
            message: "SSH Key is already in use on your account",
            ssh_key: resp.ssh_keys[i]
          });
        }
      }
      return this._doRequest("POST", "account/keys", JSON.stringify({
        name: name,
        public_key: this.state.ssh.public
      }));
    }.bind(this)).then(function(resp) {
      console.log(resp);
      return this._doRequest("GET", "droplets");
    }.bind(this)).then(function(resp) {
      console.log(resp);
      for (var i = 0; i < resp.droplets.length; i++) {
        if (resp.droplets[i].name === name) {
          return Promise.resolve({
            message: "Droplet already created with name=" + name,
            droplet: resp.droplets[i]
          });
        }
      }

      return this._doRequest("POST", "droplets", JSON.stringify({
        name: name,
        region: "nyc3",
        size: "512mb",
        image: "ubuntu-14-04-x64",
        ssh_keys: [ sshKeyId ]
      }));
    }.bind(this)).then(function(resp) {
      console.log(resp);
      resolve();
    }.bind(this)).catch(function(err) {
      console.error("Error w/DigitalOcean: " + err);
      this._sendStatus("CLOUD_FAILED");
      reject({
        errcode: "",
        message: JSON.stringify(err)
      });
    }.bind(this));
  }.bind(this));
}

Provisioner.prototype.start = function(name) {
  this._sendStatus("START");
  return this._doOAuth().then(function(oauthObj) {
    this.state.oauth = oauthObj;
    return this._getSshKey(name);
  }.bind(this)).then(function(keys) {
    this.state.ssh = keys;
    return this._setupDigitalOcean(name);
  }.bind(this)).then(function() {
    console.log(this.state);
    return this.state;
  }.bind(this));
}

freedom().providePromises(Provisioner);
<|endoftext|>


<commit_before>/* eslint-env node, mocha */
'use strict';

const assert = require('chai').assert
    , send = require('./send')
    , zlib = require('zlib')
    , etag = require('etag')

    , compressTimeout = 10;

let fakeRes
    , fakeOut
    , fakeHeaders
    , obj
    , buf;

describe('Send Tests', () => {
    beforeEach(() => {
        fakeHeaders = {};

        fakeRes = {
            setHeader: (key, value) => {
                fakeHeaders[key] = value;
            }
            , end: (data) => {
                fakeOut = data;
            }
            , statusCode: 200
        };

        fakeRes.send = send({
            headers: {
                'accept-encoding': 'none'
                , 'if-none-match': ''
            }
        }, { compression: false });

        fakeRes.sendDeflate = send({
            headers: {
                'accept-encoding': 'deflate'
                , 'if-none-match': ''
            }
        }, { compression: 'deflate' });

        fakeRes.sendGzip = send({
            headers: {
                'accept-encoding': 'gzip'
                , 'if-none-match': ''
            }
        }, { compression: 'gzip' });

        fakeOut = '';

        obj = {
            title: 'Tom Sawyer'
            , Author: 'Samuel Langhorne Clemens'
        };

        buf = new Buffer('this is a buffer', 'utf8');

        fakeRes.sendEtag = send({
            headers: {
                'accept-encoding': 'none'
                , 'if-none-match': etag(JSON.stringify(obj))
            }
        }, { compression: false });
    });

    it('should be defined as a function', () => {
        assert.isFunction(send);
    });

    it('should return a function', () => {
        assert.isFunction(send({}, {}));
    });

    it('should handle an empty data object', () => {
        fakeRes.send();
        assert.strictEqual(fakeOut, '');
    });

    it('should handle a string', () => {
        fakeRes.send('The Walrus is Paul');
        assert.strictEqual(fakeOut, 'The Walrus is Paul');
    });

    it('should handle an object', () => {
        fakeRes.send(obj);
        assert.strictEqual(fakeOut, JSON.stringify(obj));
    });

    it('should handle a buffer', () => {
        fakeRes.send(buf);
        assert.strictEqual(fakeOut, 'this is a buffer');
    });

    it('should handle an array', () => {
        fakeRes.send([ 'one', 'two' ]);
        assert.strictEqual(fakeOut, JSON.stringify([ 'one', 'two' ]));
    });

    it('should handle a number and other weird data', () => {
        fakeRes.send(1);
        assert.strictEqual(fakeOut, '1');
    });

    it('should handle a bool', () => {
        fakeRes.send(true);
        assert.strictEqual(fakeOut, JSON.stringify(true));
    });

    it('should return deflate compressed results if deflate header is sent', (done) => {
        let outString
            , compareString;

        fakeRes.sendDeflate(obj);

        setTimeout(() => {
            outString = JSON.stringify(fakeOut);
            compareString = JSON.stringify(zlib.deflateSync(JSON.stringify(obj)));

            assert.strictEqual(outString, compareString);
            assert.strictEqual(fakeHeaders['Content-Encoding'], 'deflate');
            done();
        }, compressTimeout);
    });

    it('should return gzip compressed results if gzip header is sent', (done) => {
        let outString
            , compareString;

        fakeRes.sendGzip(obj);

        setTimeout(() => {
            outString = JSON.stringify(fakeOut);
            compareString = JSON.stringify(zlib.gzipSync(JSON.stringify(obj)));

            assert.strictEqual(outString, compareString);
            assert.strictEqual(fakeHeaders['Content-Encoding'], 'gzip');
            done();
        }, compressTimeout);
    });

    it('should return a 304 if the content has not changed', () => {
        const notModifiedStatus = 304;

        fakeRes.sendEtag(obj);
        assert.strictEqual(fakeRes.statusCode, notModifiedStatus);
    });
});
<commit_msg>Starts getting the tests updated and working<commit_after>/* eslint-env node, mocha */
'use strict';

const assert = require('chai').assert
    , send = require('./send')
    , zlib = require('zlib')
    , brotli = require('iltorb')
    , etag = require('etag')

    , compressTimeout = 10;

let fakeRes
    , fakeOut
    , fakeHeaders
    , obj
    , buf;

describe('Send Tests', () => {
    beforeEach(() => {
        fakeHeaders = {};

        fakeRes = {
            setHeader: (key, value) => {
                fakeHeaders[key] = value;
            }
            , end: (data) => {
                fakeOut = data;
            }
            , statusCode: 200
        };

        fakeRes.send = send({
            headers: {
                'accept-encoding': 'none'
                , 'if-none-match': ''
            }
        }, { compression: false });

        fakeRes.sendDeflate = send({
            headers: {
                'accept-encoding': 'deflate'
                , 'if-none-match': ''
            }
        }, { compression: 'deflate' });

        fakeRes.sendGzip = send({
            headers: {
                'accept-encoding': 'gzip'
                , 'if-none-match': ''
            }
        }, { compression: 'gzip' });

        fakeRes.sendBrotli = send({
            headers: {
                'accept-encoding': 'br'
                , 'if-none-match': ''
            }
        }, { compression: 'br' });

        fakeOut = '';

        obj = {
            title: 'Tom Sawyer'
            , Author: 'Samuel Langhorne Clemens'
        };

        buf = new Buffer('this is a buffer', 'utf8');

        fakeRes.sendEtag = send({
            headers: {
                'accept-encoding': 'none'
                , 'if-none-match': etag(JSON.stringify(obj))
            }
        }, { compression: false });
    });

    it('should be defined as a function', () => {
        assert.isFunction(send);
    });

    it('should return a function', () => {
        assert.isFunction(send({}, {}));
    });

    it('should handle an empty data object', () => {
        fakeRes.send();
        assert.strictEqual(fakeOut, '');
    });

    it('should handle a string', () => {
        fakeRes.send('The Walrus is Paul');
        assert.strictEqual(fakeOut, 'The Walrus is Paul');
    });

    it('should handle an object', () => {
        fakeRes.send(obj);
        assert.strictEqual(fakeOut, JSON.stringify(obj));
    });

    it('should handle a buffer', () => {
        fakeRes.send(buf);
        assert.strictEqual(fakeOut, 'this is a buffer');
    });

    it('should handle an array', () => {
        fakeRes.send([ 'one', 'two' ]);
        assert.strictEqual(fakeOut, JSON.stringify([ 'one', 'two' ]));
    });

    it('should handle a number and other weird data', () => {
        fakeRes.send(1);
        assert.strictEqual(fakeOut, '1');
    });

    it('should handle a bool', () => {
        fakeRes.send(true);
        assert.strictEqual(fakeOut, JSON.stringify(true));
    });

    it('should return deflate compressed results if deflate header is sent', (done) => {
        fakeRes.sendDeflate(obj);

        setTimeout(() => {
            const outString = JSON.stringify(fakeOut)
                , compareString = JSON.stringify(zlib.deflateSync(JSON.stringify(obj)));

            assert.strictEqual(outString, compareString);
            assert.strictEqual(fakeHeaders['Content-Encoding'], 'deflate');
            done();
        }, compressTimeout);
    });

    it('should return gzip compressed results if gzip header is sent', (done) => {
        fakeRes.sendGzip(obj);

        setTimeout(() => {
            const outString = JSON.stringify(fakeOut)
                , compareString = JSON.stringify(zlib.gzipSync(JSON.stringify(obj)));

            assert.strictEqual(outString, compareString);
            assert.strictEqual(fakeHeaders['Content-Encoding'], 'gzip');
            done();
        }, compressTimeout);
    });

    it('should return brotli compressed results if brotli header is sent', (done) => {
        fakeRes.sendBrotli(obj);

        setTimeout(() => {
            const outString = JSON.stringify(fakeOut);

            brotli.compress(JSON.stringify(obj), (err, compareString) => {
                assert.strictEqual(outString, JSON.stringify(compareString));
                assert.strictEqual(fakeHeaders['Content-Encoding'], 'br');
                done();
            });
        }, compressTimeout);
    });

    it('should return a 304 if the content has not changed', () => {
        const notModifiedStatus = 304;

        fakeRes.sendEtag(obj);
        assert.strictEqual(fakeRes.statusCode, notModifiedStatus);
    });
});
<|endoftext|>


<commit_before>var Physics = function() {
    PIXELS_PER_METER = 16;
    return function(context, gameWidth, gameHeight, endGameCallback) {
        var that = this;
        function newDebugDraw() {
            var debugDraw = new b2DebugDraw();
            debugDraw.SetSprite(document.getElementById("sup").getContext("2d"));
            debugDraw.SetDrawScale(PIXELS_PER_METER*that.debugScale);
            debugDraw.SetFillAlpha(0.5);
            debugDraw.SetLineThickness(1.0);
            debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
            return debugDraw;
        }

        var b2Vec2 = Box2D.Common.Math.b2Vec2;
        var b2BodyDef = Box2D.Dynamics.b2BodyDef;
        var b2Body = Box2D.Dynamics.b2Body;
        var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
        var b2Fixture = Box2D.Dynamics.b2Fixture;
        var b2World = Box2D.Dynamics.b2World;
        var b2MassData = Box2D.Collision.Shapes.b2MassData;
        var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
        var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
        var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
        var b2Settings = Box2D.Common.b2Settings;
        this.toRemove = [];
        this.boxesRemoved = 0;

        b2Settings.b2_maxTranslation = 10000.0;
        b2Settings.b2_maxTranslationSquared = 10000.0*10000.0;
        b2Settings.b2MixRestitution = function(r1, r2) {
            if (r1 === undefined)
                r1 = 0;
            if (r2 === undefined)
                r2 = 0;
            return Math.min(r1, r2);
        };

        var turnRate = Constants.k('world_rotation_rate');
        var targetRotation = 0;
        var rotation = 0;
        var gravity = 0.00001;

        this.world = new b2World(newGravity(), false);
        this.world.UserData = this;

        var debugDraw = newDebugDraw();

        if (Constants.k('debug_physics')) {
            that.world.SetDebugDraw(debugDraw);
        } else {
            that.world.SetDebugDraw(null);
            debugDraw.m_sprite.graphics.clear();
        }

        gravity = Constants.k('world_gravity');
        that.world.SetGravity(newGravity());

        var setPhysicalProperties = function(cls, fix, massless) {
            if (massless === undefined) {
                massless = false;
            }
            fix.SetFriction(Constants.k(cls + '_friction'));
            fix.SetRestitution(Constants.k(cls + '_restitution'));
            if (!massless) {
                fix.SetDensity(Constants.k(cls + '_density'));
            }
        };

        newWorld(endGameCallback);

        this.newBlock = function(cls, stage) {
            var fd                 = new b2FixtureDef;
            fd.shape               = new b2PolygonShape();
            fd.density = 1.0;
            fd.friction = 0.3;
            fd.restitution = 0.1;

            badBlockChance = Constants.k('block_bad_prob');
            var killsYou = Math.random() < badBlockChance;
            if (cls == "block" && killsYou) {
                cls = "block_bad";
            }

            value = Constants.k(cls + '_image');
            scale = Constants.k(cls + '_scale');
            flags = Constants.k(cls + '_flags');
            size = Constants.k('game_size');
            dist = Constants.k('mousehole_spawn_distance');
            randomness = Constants.k('spawn_randomness');
            var bodyDef                  = new b2BodyDef();
            bodyDef.type                 = b2Body.b2_dynamicBody;
            if (/c/.exec(flags)) {
                fd.shape.SetAsBox(1, 2.5);
            } else {
                fd.shape.SetAsBox(1, 1);
            }
            var radius = dist;
            var gravVec = newGravity()
            gravVec.NegativeSelf();
            gravVec.Normalize();
            gravVec.Multiply(radius);

            var x = size/2+gravVec.x+Math.random()*randomness-randomness/2;
            var y = size/2+gravVec.y+Math.random()*randomness-randomness/2;

            bodyDef.position.x           = x/PIXELS_PER_METER;
            bodyDef.position.y           = y/PIXELS_PER_METER;
            bodyDef.allowSleep           = false;
            if (/f/.exec(flags)) {
                bodyDef.fixedRotation = true;
            }
            var body = that.world.CreateBody(bodyDef);
            var fix = body.CreateFixture(fd);
            setPhysicalProperties(cls, fix);

            var e = new BaseEntity();

            // pick a source
            value = value.split(' ');
            value = value[Math.floor(Math.random() * value.length)];
            var beeTexture = PIXI.Texture.fromImage(value, true);
            var beeSprite = new PIXI.Sprite(beeTexture);

            if (/c/.exec(flags)) {
                beeSprite.anchor.x = 0.42;
            } else {
                beeSprite.anchor.x = 0.5;
            }
            beeSprite.anchor.y = 0.5;

            beeSprite.scale.x = scale;
            beeSprite.scale.y = scale;

            e = new PhysicsEntityAdapter(body, e)
            e = new SpriteAdapter(stage, beeSprite, e);
            if (/f/.exec(flags)) {
                e = new RotateWithWorldAdapter(e);
            }
            if (/d/.exec(flags)) {
                e = new PoisonAdapter(endGameCallback, 'player', e);
            }
            if (/g/.exec(flags)) {
                e = new TagAdapter(['grabbable'], e);
                e = new ScoreAdapter(e);
            }
            if (/t/.exec(flags)) {
                e = new TagAdapter(['block'], e);
                e = new LimitedLifespanAdapter(10, function() {
                    var total = 0;
                    World.all(function(x) {
                        if (e.hasTag('block')) {
                            total += 1;
                        }
                    });
                    return total > 20;
                }, e);
            }
            if (/c/.exec(flags)) {
                e = new TagAdapter(['player'], e);
                e = new LateralMovementAdapter(e);
                e = new GrabAdapter(e);
                e = new JumpAdapter(e);
                e = new DebugLateralMovementAdapter(e);
                e = new JumpSpacingAdapter(e);
                e = new ControlAdapter(e);
                body.SetUserData({tag: "PLAYER", entity:e});
            } else {
                body.SetUserData({tag: "BLOCK", entity:e, "spawnTime":unixTime()});
            }
            World.add(e);
        };

        this.draw = function(scaleFactor) {
            that.debugScale = scaleFactor;
            that.world.SetDebugDraw(newDebugDraw());
            that.world.DrawDebugData();
        };

        var doneRotating = true
        this.update = function(callback) {
            if (Math.abs(targetRotation - rotation) > turnRate) {
                doneRotating = false;
                function sign(x) { return x ? x < 0 ? -1 : 1 : 0; }
                direction = sign(targetRotation - rotation);
                rotation += direction * turnRate;
                that.world.SetGravity(newGravity());
            } else {
                if (!doneRotating) {
                    rotation = targetRotation;
                    callback();
                    doneRotating = true;
                }
            }

            that.toRemove = [];
            that.world.Step(1/60, Constants.k('physics_velocityIterations'), Constants.k('physics_positionIterations'));
            for (var i = 0; i < that.toRemove.length; i++) {
                var body = that.toRemove[i];
                that.world.DestroyBody(body);
                World.del(body.GetUserData().entity);
                that.boxesRemoved += 1;
            }
            that.world.ClearForces();
        };

        this.getRotation = function() {
            return rotation;
        };

        this.setTargetRotation = function(rotation) {
            targetRotation = rotation;
        };

        function newGravity() {
            var vector = rotate([0, gravity*PIXELS_PER_METER]);
            return new b2Vec2(vector[0], vector[1]);
        }

        function rotate(vec) {
            var sine   = Math.sin(rotation * (Math.PI/180));
            var cosine = Math.cos(rotation * (Math.PI/180));
            return [vec[0] * cosine + vec[1] * sine,
                   vec[0] * -sine + vec[1] * cosine];
        }

        function newPlatform(x, y, width, height, orientation) {
            var orientationRadians  = orientation * (Math.PI/180);
            var platformDef         = new b2FixtureDef;
            platformDef.shape       = new b2PolygonShape();
            platformDef.friction    = 0.2;
            platformDef.restitution = 0.7;
            platformDef.shape.SetAsOrientedBox(width/2, height/2, new b2Vec2(0, 0), orientationRadians);

            var platformBodyDef    = new b2BodyDef();
            platformBodyDef.type   = b2Body.b2_staticBody;
            platformBodyDef.position.x = x/PIXELS_PER_METER;
            platformBodyDef.position.y = y/PIXELS_PER_METER;
            var body = that.world.CreateBody(platformBodyDef);
            body.SetAngle(orientationRadians);

            body.SetUserData({'tag': 'WALL'});

            var fix = body.CreateFixture(platformDef);
            setPhysicalProperties('platform', fix, true);

        }

        function addWall(x, y, width, height, rotation, offset1, offset2) {
            //floor
            var floorDef                 = new b2FixtureDef;
            floorDef.shape               = new b2PolygonShape();
            floorDef.friction            = 0.2;
            floorDef.restitution         = 0.7;
            floorDef.shape.SetAsOrientedBox(width/2, height/2, new b2Vec2(offset1, offset2), rotation * Math.PI/180);

            var floorBodyDef                  = new b2BodyDef();
            floorBodyDef.type                 = b2Body.b2_staticBody;
            floorBodyDef.position.x           = x/PIXELS_PER_METER;
            floorBodyDef.position.y           = y/PIXELS_PER_METER;
            var body = that.world.CreateBody(floorBodyDef)
            body.SetUserData({'tag': 'WALL'});
            var fix = body.CreateFixture(floorDef);
            setPhysicalProperties('wall', fix, true);
        }

        function newWorld(endGameCallback) {
            addWall(gameWidth/2, 0, 10000, 3, 0, 0, 0);
            addWall(gameWidth/2, gameHeight, 10000, 3, 0, 0, 0);
            addWall(0, gameHeight/2, 3, 100000, 0, 0, 0);
            addWall(gameWidth, gameHeight/2, 3, 100000, 0, 0, 0);
            //addWall(gameWidth, gameHeight/2, 100000, 3, 45, 3, 3);
            addWall(gameWidth+gameWidth*0.25, gameHeight/2, 100000, 3, 45, 0, 0);
            addWall(-gameWidth*0.25, gameHeight/2, 100000, 3, 45, 0, 0);
            addWall(gameWidth/2, -gameHeight*0.25, 10000, 3, -45, 0, 0);
            addWall(gameWidth/2, gameHeight+gameHeight*0.25, 10000, 3, -45, 0, 0);
            var platThickness = 0.7;
            var platLength = 5;
            newPlatform((1/2)*gameWidth, (2/7)*gameHeight, platLength, platThickness, 90);
            newPlatform((1/2)*gameWidth, (5/7)*gameHeight, platLength, platThickness, 270);
            newPlatform((2/7)*gameWidth, (1/2)*gameHeight, platThickness, platLength, 0);
            newPlatform((5/7)*gameWidth, (1/2)*gameHeight, platThickness, platLength, 180);
            var myContactListener = {
                "BeginContact" : function(contact) {
                    var data1 = contact.GetFixtureA().GetBody().GetUserData();
                    var data2 = contact.GetFixtureB().GetBody().GetUserData();
                    if (data1 && data2) {
                        if (data1.entity !== undefined && data2.entity !== undefined) {
                            data1.entity.collideInto(data2.entity);
                            data2.entity.collideInto(data1.entity);
                        }
                        if (data1.tag == "GOAL" && data2.entity != null) {
                            data2.entity.doHitGoal()
                            if (unixTime() - data2.spawnTime > 5) {
                                that.toRemove.push(contact.GetFixtureB().GetBody());
                            }
                        }
                        if (data2.tag == "GOAL" && data1.entity != null) {
                            data1.entity.doHitGoal()
                            if (unixTime() - data1.spawnTime > 5) {
                                that.toRemove.push(contact.GetFixtureA().GetBody());
                            }
                        }
                        if (data1.tag == "WALL" && data2.entity != null) {
                            data2.entity.doHitWall();
                        }
                        if (data2.tag == "WALL" && data1.entity != null) {
                            data1.entity.doHitWall();
                        }
                    }
                },
                "EndContact" : function() {
                },
                "PreSolve" : function() {
                },
                "PostSolve" : function() {
                }
            };
            that.world.SetContactListener(myContactListener);
        }

        this.newGoal = function(gameSize, stage) {
            width = Constants.k('goal_width');
            height = Constants.k('goal_height');
            image = Constants.k('goal_image');
            scale = Constants.k('goal_scale');
            //floor
            var floorDef                 = new b2FixtureDef;
            floorDef.shape               = new b2PolygonShape();
            floorDef.isSensor            = true;
            //floorDef.friction            = 0.2;
            //floorDef.restitution         = 0.7;
            floorDef.shape.SetAsBox(width/2, height/2);

            var floorBodyDef                  = new b2BodyDef();
            floorBodyDef.type                 = b2Body.b2_staticBody;
            floorBodyDef.position.x           = gameSize*0.5/PIXELS_PER_METER;
            floorBodyDef.position.y           = gameSize*0.5/PIXELS_PER_METER;
            var body = that.world.CreateBody(floorBodyDef);

            body.SetUserData({tag: "GOAL"});
            var fix = body.CreateFixture(floorDef);

            var e = new BaseEntity();

            var beeTexture = PIXI.Texture.fromImage(image, true);
            var beeSprite = new PIXI.Sprite(beeTexture);

            beeSprite.anchor.x = 0.5;
            beeSprite.anchor.y = 0.5;

            beeSprite.scale.x = scale;
            beeSprite.scale.y = scale;
            e = new FixedLocationAdapter(gameSize*0.5 / PIXELS_PER_METER,
                                         gameSize*0.5 / PIXELS_PER_METER,
                                         0, e)
            e = new SpriteAdapter(stage, beeSprite, e);
            World.add(e);
        }

        this.rotate = rotate;
    };
}();
<commit_msg>Remove the special case handling<commit_after>var Physics = function() {
    PIXELS_PER_METER = 16;
    return function(context, gameWidth, gameHeight, endGameCallback) {
        var that = this;
        function newDebugDraw() {
            var debugDraw = new b2DebugDraw();
            debugDraw.SetSprite(document.getElementById("sup").getContext("2d"));
            debugDraw.SetDrawScale(PIXELS_PER_METER*that.debugScale);
            debugDraw.SetFillAlpha(0.5);
            debugDraw.SetLineThickness(1.0);
            debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
            return debugDraw;
        }

        var b2Vec2 = Box2D.Common.Math.b2Vec2;
        var b2BodyDef = Box2D.Dynamics.b2BodyDef;
        var b2Body = Box2D.Dynamics.b2Body;
        var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
        var b2Fixture = Box2D.Dynamics.b2Fixture;
        var b2World = Box2D.Dynamics.b2World;
        var b2MassData = Box2D.Collision.Shapes.b2MassData;
        var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
        var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
        var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
        var b2Settings = Box2D.Common.b2Settings;
        this.toRemove = [];
        this.boxesRemoved = 0;

        b2Settings.b2_maxTranslation = 10000.0;
        b2Settings.b2_maxTranslationSquared = 10000.0*10000.0;
        b2Settings.b2MixRestitution = function(r1, r2) {
            if (r1 === undefined)
                r1 = 0;
            if (r2 === undefined)
                r2 = 0;
            return Math.min(r1, r2);
        };

        var turnRate = Constants.k('world_rotation_rate');
        var targetRotation = 0;
        var rotation = 0;
        var gravity = 0.00001;

        this.world = new b2World(newGravity(), false);
        this.world.UserData = this;

        var debugDraw = newDebugDraw();

        if (Constants.k('debug_physics')) {
            that.world.SetDebugDraw(debugDraw);
        } else {
            that.world.SetDebugDraw(null);
            debugDraw.m_sprite.graphics.clear();
        }

        gravity = Constants.k('world_gravity');
        that.world.SetGravity(newGravity());

        var setPhysicalProperties = function(cls, fix, massless) {
            if (massless === undefined) {
                massless = false;
            }
            fix.SetFriction(Constants.k(cls + '_friction'));
            fix.SetRestitution(Constants.k(cls + '_restitution'));
            if (!massless) {
                fix.SetDensity(Constants.k(cls + '_density'));
            }
        };

        newWorld(endGameCallback);

        this.newBlock = function(cls, stage) {
            var fd                 = new b2FixtureDef;
            fd.shape               = new b2PolygonShape();
            fd.density = 1.0;
            fd.friction = 0.3;
            fd.restitution = 0.1;

            badBlockChance = Constants.k('block_bad_prob');
            var killsYou = Math.random() < badBlockChance;
            if (cls == "block" && killsYou) {
                cls = "block_bad";
            }

            value = Constants.k(cls + '_image');
            scale = Constants.k(cls + '_scale');
            flags = Constants.k(cls + '_flags');
            size = Constants.k('game_size');
            dist = Constants.k('mousehole_spawn_distance');
            randomness = Constants.k('spawn_randomness');
            var bodyDef                  = new b2BodyDef();
            bodyDef.type                 = b2Body.b2_dynamicBody;
            if (/c/.exec(flags)) {
                fd.shape.SetAsBox(1, 2.5);
            } else {
                fd.shape.SetAsBox(1, 1);
            }
            var radius = dist;
            var gravVec = newGravity()
            gravVec.NegativeSelf();
            gravVec.Normalize();
            gravVec.Multiply(radius);

            var x = size/2+gravVec.x+Math.random()*randomness-randomness/2;
            var y = size/2+gravVec.y+Math.random()*randomness-randomness/2;

            bodyDef.position.x           = x/PIXELS_PER_METER;
            bodyDef.position.y           = y/PIXELS_PER_METER;
            bodyDef.allowSleep           = false;
            if (/f/.exec(flags)) {
                bodyDef.fixedRotation = true;
            }
            var body = that.world.CreateBody(bodyDef);
            var fix = body.CreateFixture(fd);
            setPhysicalProperties(cls, fix);

            var e = new BaseEntity();

            // pick a source
            value = value.split(' ');
            value = value[Math.floor(Math.random() * value.length)];
            var beeTexture = PIXI.Texture.fromImage(value, true);
            var beeSprite = new PIXI.Sprite(beeTexture);

            if (/c/.exec(flags)) {
                beeSprite.anchor.x = 0.42;
            } else {
                beeSprite.anchor.x = 0.5;
            }
            beeSprite.anchor.y = 0.5;

            beeSprite.scale.x = scale;
            beeSprite.scale.y = scale;

            e = new PhysicsEntityAdapter(body, e)
            e = new SpriteAdapter(stage, beeSprite, e);
            if (/f/.exec(flags)) {
                e = new RotateWithWorldAdapter(e);
            }
            if (/d/.exec(flags)) {
                e = new PoisonAdapter(endGameCallback, 'player', e);
            }
            if (/g/.exec(flags)) {
                e = new TagAdapter(['worthPoints', 'grabbable'], e);
                e = new ScoreAdapter(e);
            }
            if (/t/.exec(flags)) {
                e = new TagAdapter(['block'], e);
                e = new LimitedLifespanAdapter(10, function() {
                    var total = 0;
                    World.all(function(x) {
                        if (e.hasTag('block')) {
                            total += 1;
                        }
                    });
                    return total > 20;
                }, e);
            }
            if (/c/.exec(flags)) {
                e = new TagAdapter(['player'], e);
                e = new LateralMovementAdapter(e);
                e = new GrabAdapter(e);
                e = new JumpAdapter(e);
                e = new DebugLateralMovementAdapter(e);
                e = new JumpSpacingAdapter(e);
                e = new ControlAdapter(e);
                body.SetUserData({tag: "PLAYER", entity:e});
            } else {
                body.SetUserData({tag: "BLOCK", entity:e, "spawnTime":unixTime()});
            }
            World.add(e);
        };

        this.draw = function(scaleFactor) {
            that.debugScale = scaleFactor;
            that.world.SetDebugDraw(newDebugDraw());
            that.world.DrawDebugData();
        };

        var doneRotating = true
        this.update = function(callback) {
            if (Math.abs(targetRotation - rotation) > turnRate) {
                doneRotating = false;
                function sign(x) { return x ? x < 0 ? -1 : 1 : 0; }
                direction = sign(targetRotation - rotation);
                rotation += direction * turnRate;
                that.world.SetGravity(newGravity());
            } else {
                if (!doneRotating) {
                    rotation = targetRotation;
                    callback();
                    doneRotating = true;
                }
            }

            that.toRemove = [];
            that.world.Step(1/60, Constants.k('physics_velocityIterations'), Constants.k('physics_positionIterations'));
            for (var i = 0; i < that.toRemove.length; i++) {
                var body = that.toRemove[i];
                that.world.DestroyBody(body);
                World.del(body.GetUserData().entity);
                that.boxesRemoved += 1;
            }
            that.world.ClearForces();
        };

        this.getRotation = function() {
            return rotation;
        };

        this.setTargetRotation = function(rotation) {
            targetRotation = rotation;
        };

        function newGravity() {
            var vector = rotate([0, gravity*PIXELS_PER_METER]);
            return new b2Vec2(vector[0], vector[1]);
        }

        function rotate(vec) {
            var sine   = Math.sin(rotation * (Math.PI/180));
            var cosine = Math.cos(rotation * (Math.PI/180));
            return [vec[0] * cosine + vec[1] * sine,
                   vec[0] * -sine + vec[1] * cosine];
        }

        function newPlatform(x, y, width, height, orientation) {
            var orientationRadians  = orientation * (Math.PI/180);
            var platformDef         = new b2FixtureDef;
            platformDef.shape       = new b2PolygonShape();
            platformDef.friction    = 0.2;
            platformDef.restitution = 0.7;
            platformDef.shape.SetAsOrientedBox(width/2, height/2, new b2Vec2(0, 0), orientationRadians);

            var platformBodyDef    = new b2BodyDef();
            platformBodyDef.type   = b2Body.b2_staticBody;
            platformBodyDef.position.x = x/PIXELS_PER_METER;
            platformBodyDef.position.y = y/PIXELS_PER_METER;
            var body = that.world.CreateBody(platformBodyDef);
            body.SetAngle(orientationRadians);

            body.SetUserData({'tag': 'WALL'});

            var fix = body.CreateFixture(platformDef);
            setPhysicalProperties('platform', fix, true);

        }

        function addWall(x, y, width, height, rotation, offset1, offset2) {
            //floor
            var floorDef                 = new b2FixtureDef;
            floorDef.shape               = new b2PolygonShape();
            floorDef.friction            = 0.2;
            floorDef.restitution         = 0.7;
            floorDef.shape.SetAsOrientedBox(width/2, height/2, new b2Vec2(offset1, offset2), rotation * Math.PI/180);

            var floorBodyDef                  = new b2BodyDef();
            floorBodyDef.type                 = b2Body.b2_staticBody;
            floorBodyDef.position.x           = x/PIXELS_PER_METER;
            floorBodyDef.position.y           = y/PIXELS_PER_METER;
            var body = that.world.CreateBody(floorBodyDef)
            body.SetUserData({'tag': 'WALL'});
            var fix = body.CreateFixture(floorDef);
            setPhysicalProperties('wall', fix, true);
        }

        function newWorld(endGameCallback) {
            addWall(gameWidth/2, 0, 10000, 3, 0, 0, 0);
            addWall(gameWidth/2, gameHeight, 10000, 3, 0, 0, 0);
            addWall(0, gameHeight/2, 3, 100000, 0, 0, 0);
            addWall(gameWidth, gameHeight/2, 3, 100000, 0, 0, 0);
            //addWall(gameWidth, gameHeight/2, 100000, 3, 45, 3, 3);
            addWall(gameWidth+gameWidth*0.25, gameHeight/2, 100000, 3, 45, 0, 0);
            addWall(-gameWidth*0.25, gameHeight/2, 100000, 3, 45, 0, 0);
            addWall(gameWidth/2, -gameHeight*0.25, 10000, 3, -45, 0, 0);
            addWall(gameWidth/2, gameHeight+gameHeight*0.25, 10000, 3, -45, 0, 0);
            var platThickness = 0.7;
            var platLength = 5;
            newPlatform((1/2)*gameWidth, (2/7)*gameHeight, platLength, platThickness, 90);
            newPlatform((1/2)*gameWidth, (5/7)*gameHeight, platLength, platThickness, 270);
            newPlatform((2/7)*gameWidth, (1/2)*gameHeight, platThickness, platLength, 0);
            newPlatform((5/7)*gameWidth, (1/2)*gameHeight, platThickness, platLength, 180);
            var myContactListener = {
                "BeginContact" : function(contact) {
                    var data1 = contact.GetFixtureA().GetBody().GetUserData();
                    var data2 = contact.GetFixtureB().GetBody().GetUserData();
                    if (data1 && data2) {
                        if (data1.entity !== undefined && data2.entity !== undefined) {
                            data1.entity.collideInto(data2.entity);
                            data2.entity.collideInto(data1.entity);
                        }
                        if (data1.tag == "WALL" && data2.entity != null) {
                            data2.entity.doHitWall();
                        }
                        if (data2.tag == "WALL" && data1.entity != null) {
                            data1.entity.doHitWall();
                        }
                    }
                },
                "EndContact" : function() {
                },
                "PreSolve" : function() {
                },
                "PostSolve" : function() {
                }
            };
            that.world.SetContactListener(myContactListener);
        }

        this.newGoal = function(gameSize, stage) {
            width = Constants.k('goal_width');
            height = Constants.k('goal_height');
            image = Constants.k('goal_image');
            scale = Constants.k('goal_scale');
            //floor
            var floorDef                 = new b2FixtureDef;
            floorDef.shape               = new b2PolygonShape();
            floorDef.isSensor            = true;
            //floorDef.friction            = 0.2;
            //floorDef.restitution         = 0.7;
            floorDef.shape.SetAsBox(width/2, height/2);

            var floorBodyDef                  = new b2BodyDef();
            floorBodyDef.type                 = b2Body.b2_staticBody;
            floorBodyDef.position.x           = gameSize*0.5/PIXELS_PER_METER;
            floorBodyDef.position.y           = gameSize*0.5/PIXELS_PER_METER;
            var body = that.world.CreateBody(floorBodyDef);

            body.SetUserData({tag: "GOAL"});
            var fix = body.CreateFixture(floorDef);

            var e = new BaseEntity();

            var beeTexture = PIXI.Texture.fromImage(image, true);
            var beeSprite = new PIXI.Sprite(beeTexture);

            beeSprite.anchor.x = 0.5;
            beeSprite.anchor.y = 0.5;

            beeSprite.scale.x = scale;
            beeSprite.scale.y = scale;
            e = new PhysicsEntityAdapter(body, e);
            e = new SpriteAdapter(stage, beeSprite, e);
            e = new PoisonAdapter(function(x) {
                x.doHitGoal();
            }, 'worthPoints', e);
            World.add(e);
        }

        this.rotate = rotate;
    };
}();
<|endoftext|>


<commit_before>var isArray = require('./isArray')

module.exports = function pickOne(items, fn) {
	if (!items) { return null }
	var result
	if (isArray(items)) {
		for (var i=0; i<items.length; i++) {
			result = fn(items[i], i)
			if (result != null && result != false) { return result }
		}
	} else {
		for (var key in items) {
			result = fn(items[key], key)
			if (result != null && result != false) { return result }
		}
	}
	return null
}
<commit_msg>let 0 be a valid find<commit_after>var isArray = require('./isArray')

module.exports = function pickOne(items, fn) {
	if (!items) { return null }
	var result
	if (isArray(items)) {
		for (var i=0; i<items.length; i++) {
			result = fn(items[i], i)
			if (result != null && result !== false) { return result }
		}
	} else {
		for (var key in items) {
			result = fn(items[key], key)
			if (result != null && result !== false) { return result }
		}
	}
	return null
}
<|endoftext|>