diff --git a/.gitignore b/.gitignore
index 6a8fac0c..23195f35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,4 +40,6 @@ Desktop.ini
.idea
npm-debug.log
/framework/build
-node_modules/
+node_modules/jshint
+node_modules/promise-matchers
+node_modules/jasmine-node
diff --git a/node_modules/.bin/jasmine-node b/node_modules/.bin/jasmine-node
new file mode 120000
index 00000000..a1c65325
--- /dev/null
+++ b/node_modules/.bin/jasmine-node
@@ -0,0 +1 @@
+../jasmine-node/bin/jasmine-node
\ No newline at end of file
diff --git a/node_modules/.bin/jshint b/node_modules/.bin/jshint
new file mode 120000
index 00000000..1b5b30ca
--- /dev/null
+++ b/node_modules/.bin/jshint
@@ -0,0 +1 @@
+../jshint/bin/jshint
\ No newline at end of file
diff --git a/node_modules/.bin/nopt b/node_modules/.bin/nopt
new file mode 120000
index 00000000..6b6566ea
--- /dev/null
+++ b/node_modules/.bin/nopt
@@ -0,0 +1 @@
+../nopt/bin/nopt.js
\ No newline at end of file
diff --git a/node_modules/.bin/shjs b/node_modules/.bin/shjs
new file mode 120000
index 00000000..a0449975
--- /dev/null
+++ b/node_modules/.bin/shjs
@@ -0,0 +1 @@
+../shelljs/bin/shjs
\ No newline at end of file
diff --git a/node_modules/cordova-common/node_modules/.bin/semver b/node_modules/cordova-common/node_modules/.bin/semver
new file mode 120000
index 00000000..317eb293
--- /dev/null
+++ b/node_modules/cordova-common/node_modules/.bin/semver
@@ -0,0 +1 @@
+../semver/bin/semver
\ No newline at end of file
diff --git a/node_modules/elementtree/tests/data/xml1.xml b/node_modules/elementtree/tests/data/xml1.xml
new file mode 100644
index 00000000..72c33aec
--- /dev/null
+++ b/node_modules/elementtree/tests/data/xml1.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
diff --git a/node_modules/elementtree/tests/data/xml2.xml b/node_modules/elementtree/tests/data/xml2.xml
new file mode 100644
index 00000000..5f94bbd9
--- /dev/null
+++ b/node_modules/elementtree/tests/data/xml2.xml
@@ -0,0 +1,14 @@
+
+
diff --git a/node_modules/elementtree/tests/test-simple.js b/node_modules/elementtree/tests/test-simple.js
new file mode 100644
index 00000000..1fc04b81
--- /dev/null
+++ b/node_modules/elementtree/tests/test-simple.js
@@ -0,0 +1,339 @@
+/**
+ * Copyright 2011 Rackspace
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+var fs = require('fs');
+var path = require('path');
+
+var sprintf = require('./../lib/sprintf').sprintf;
+var et = require('elementtree');
+var XML = et.XML;
+var ElementTree = et.ElementTree;
+var Element = et.Element;
+var SubElement = et.SubElement;
+var SyntaxError = require('./../lib/errors').SyntaxError;
+
+function readFile(name) {
+ return fs.readFileSync(path.join(__dirname, '/data/', name), 'utf8');
+}
+
+exports['test_simplest'] = function(test, assert) {
+ /* Ported from */
+ var Element = et.Element;
+ var root = Element('root');
+ root.append(Element('one'));
+ root.append(Element('two'));
+ root.append(Element('three'));
+ assert.equal(3, root.len());
+ assert.equal('one', root.getItem(0).tag);
+ assert.equal('two', root.getItem(1).tag);
+ assert.equal('three', root.getItem(2).tag);
+ test.finish();
+};
+
+
+exports['test_attribute_values'] = function(test, assert) {
+ var XML = et.XML;
+ var root = XML('');
+ assert.equal('Alpha', root.attrib['alpha']);
+ assert.equal('Beta', root.attrib['beta']);
+ assert.equal('Gamma', root.attrib['gamma']);
+ test.finish();
+};
+
+
+exports['test_findall'] = function(test, assert) {
+ var XML = et.XML;
+ var root = XML('');
+
+ assert.equal(root.findall("c").length, 1);
+ assert.equal(root.findall(".//c").length, 2);
+ assert.equal(root.findall(".//b").length, 3);
+ assert.equal(root.findall(".//b")[0]._children.length, 1);
+ assert.equal(root.findall(".//b")[1]._children.length, 0);
+ assert.equal(root.findall(".//b")[2]._children.length, 0);
+ assert.deepEqual(root.findall('.//b')[0], root.getchildren()[0]);
+
+ test.finish();
+};
+
+exports['test_find'] = function(test, assert) {
+ var a = Element('a');
+ var b = SubElement(a, 'b');
+ var c = SubElement(a, 'c');
+
+ assert.deepEqual(a.find('./b/..'), a);
+ test.finish();
+};
+
+exports['test_elementtree_find_qname'] = function(test, assert) {
+ var tree = new et.ElementTree(XML(''));
+ assert.deepEqual(tree.find(new et.QName('c')), tree.getroot()._children[2]);
+ test.finish();
+};
+
+exports['test_attrib_ns_clear'] = function(test, assert) {
+ var attribNS = '{http://foo/bar}x';
+
+ var par = Element('par');
+ par.set(attribNS, 'a');
+ var child = SubElement(par, 'child');
+ child.set(attribNS, 'b');
+
+ assert.equal('a', par.get(attribNS));
+ assert.equal('b', child.get(attribNS));
+
+ par.clear();
+ assert.equal(null, par.get(attribNS));
+ assert.equal('b', child.get(attribNS));
+ test.finish();
+};
+
+exports['test_create_tree_and_parse_simple'] = function(test, assert) {
+ var i = 0;
+ var e = new Element('bar', {});
+ var expected = "\n" +
+ 'ponies';
+
+ SubElement(e, "blah", {a: 11});
+ SubElement(e, "blah", {a: 12});
+ var se = et.SubElement(e, "gag", {a: '13', b: 'abc'});
+ se.text = 'ponies';
+
+ se.itertext(function(text) {
+ assert.equal(text, 'ponies');
+ i++;
+ });
+
+ assert.equal(i, 1);
+ var etree = new ElementTree(e);
+ var xml = etree.write();
+ assert.equal(xml, expected);
+ test.finish();
+};
+
+exports['test_write_with_options'] = function(test, assert) {
+ var i = 0;
+ var e = new Element('bar', {});
+ var expected1 = "\n" +
+ '\n' +
+ ' \n' +
+ ' test\n' +
+ ' \n' +
+ ' \n' +
+ ' ponies\n' +
+ '\n';
+ var expected2 = "\n" +
+ '\n' +
+ ' \n' +
+ ' test\n' +
+ ' \n' +
+ ' \n' +
+ ' ponies\n' +
+ '\n';
+
+ var expected3 = "\n" +
+ '\n' +
+ ' \n' +
+ ' Hello World\n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ ' Test & Test & Test\n' +
+ ' \n' +
+ '\n';
+
+ var se1 = SubElement(e, "blah", {a: 11});
+ var se2 = SubElement(se1, "baz", {d: 11});
+ se2.text = 'test';
+ SubElement(e, "blah", {a: 12});
+ var se = et.SubElement(e, "gag", {a: '13', b: 'abc'});
+ se.text = 'ponies';
+
+ se.itertext(function(text) {
+ assert.equal(text, 'ponies');
+ i++;
+ });
+
+ assert.equal(i, 1);
+ var etree = new ElementTree(e);
+ var xml1 = etree.write({'indent': 4});
+ var xml2 = etree.write({'indent': 2});
+ assert.equal(xml1, expected1);
+ assert.equal(xml2, expected2);
+
+ var file = readFile('xml2.xml');
+ var etree2 = et.parse(file);
+ var xml3 = etree2.write({'indent': 4});
+ assert.equal(xml3, expected3);
+ test.finish();
+};
+
+exports['test_parse_and_find_2'] = function(test, assert) {
+ var data = readFile('xml1.xml');
+ var etree = et.parse(data);
+
+ assert.equal(etree.findall('./object').length, 2);
+ assert.equal(etree.findall('[@name]').length, 1);
+ assert.equal(etree.findall('[@name="test_container_1"]').length, 1);
+ assert.equal(etree.findall('[@name=\'test_container_1\']').length, 1);
+ assert.equal(etree.findall('./object')[0].findtext('name'), 'test_object_1');
+ assert.equal(etree.findtext('./object/name'), 'test_object_1');
+ assert.equal(etree.findall('.//bytes').length, 2);
+ assert.equal(etree.findall('*/bytes').length, 2);
+ assert.equal(etree.findall('*/foobar').length, 0);
+
+ test.finish();
+};
+
+exports['test_namespaced_attribute'] = function(test, assert) {
+ var data = readFile('xml1.xml');
+ var etree = et.parse(data);
+
+ assert.equal(etree.findall('*/bytes[@android:type="cool"]').length, 1);
+
+ test.finish();
+}
+
+exports['test_syntax_errors'] = function(test, assert) {
+ var expressions = [ './/@bar', '[@bar', '[@foo=bar]', '[@', '/bar' ];
+ var errCount = 0;
+ var data = readFile('xml1.xml');
+ var etree = et.parse(data);
+
+ expressions.forEach(function(expression) {
+ try {
+ etree.findall(expression);
+ }
+ catch (err) {
+ errCount++;
+ }
+ });
+
+ assert.equal(errCount, expressions.length);
+ test.finish();
+};
+
+exports['test_register_namespace'] = function(test, assert){
+ var prefix = 'TESTPREFIX';
+ var namespace = 'http://seriously.unknown/namespace/URI';
+ var errCount = 0;
+
+ var etree = Element(sprintf('{%s}test', namespace));
+ assert.equal(et.tostring(etree, { 'xml_declaration': false}),
+ sprintf('', namespace));
+
+ et.register_namespace(prefix, namespace);
+ var etree = Element(sprintf('{%s}test', namespace));
+ assert.equal(et.tostring(etree, { 'xml_declaration': false}),
+ sprintf('<%s:test xmlns:%s="%s" />', prefix, prefix, namespace));
+
+ try {
+ et.register_namespace('ns25', namespace);
+ }
+ catch (err) {
+ errCount++;
+ }
+
+ assert.equal(errCount, 1, 'Reserved prefix used, but exception was not thrown');
+ test.finish();
+};
+
+exports['test_tostring'] = function(test, assert) {
+ var a = Element('a');
+ var b = SubElement(a, 'b');
+ var c = SubElement(a, 'c');
+ c.text = 543;
+
+ assert.equal(et.tostring(a, { 'xml_declaration': false }), '543');
+ assert.equal(et.tostring(c, { 'xml_declaration': false }), '543');
+ test.finish();
+};
+
+exports['test_escape'] = function(test, assert) {
+ var a = Element('a');
+ var b = SubElement(a, 'b');
+ b.text = '&&&&<>"\n\r';
+
+ assert.equal(et.tostring(a, { 'xml_declaration': false }), '&&&&<>\"\n\r');
+ test.finish();
+};
+
+exports['test_find_null'] = function(test, assert) {
+ var root = Element('root');
+ var node = SubElement(root, 'node');
+ var leaf = SubElement(node, 'leaf');
+ leaf.text = 'ipsum';
+
+ assert.equal(root.find('node/leaf'), leaf);
+ assert.equal(root.find('no-such-node/leaf'), null);
+ test.finish();
+};
+
+exports['test_findtext_null'] = function(test, assert) {
+ var root = Element('root');
+ var node = SubElement(root, 'node');
+ var leaf = SubElement(node, 'leaf');
+ leaf.text = 'ipsum';
+
+ assert.equal(root.findtext('node/leaf'), 'ipsum');
+ assert.equal(root.findtext('no-such-node/leaf'), null);
+ test.finish();
+};
+
+exports['test_remove'] = function(test, assert) {
+ var root = Element('root');
+ var node1 = SubElement(root, 'node1');
+ var node2 = SubElement(root, 'node2');
+ var node3 = SubElement(root, 'node3');
+
+ assert.equal(root.len(), 3);
+
+ root.remove(node2);
+
+ assert.equal(root.len(), 2);
+ assert.equal(root.getItem(0).tag, 'node1')
+ assert.equal(root.getItem(1).tag, 'node3')
+
+ test.finish();
+};
+
+exports['test_cdata_write'] = function(test, assert) {
+ var root, etree, xml, values, value, i;
+
+ values = [
+ 'if(0>1) then true;',
+ 'ponies hello',
+ ''
+ ];
+
+ for (i = 0; i < values.length; i++) {
+ value = values[i];
+
+ root = Element('root');
+ root.append(et.CData(value));
+ etree = new ElementTree(root);
+ xml = etree.write({'xml_declaration': false});
+
+ assert.equal(xml, sprintf('', value));
+ }
+
+ test.finish();
+};
diff --git a/node_modules/nopt/examples/my-program.js b/node_modules/nopt/examples/my-program.js
new file mode 100755
index 00000000..142447e1
--- /dev/null
+++ b/node_modules/nopt/examples/my-program.js
@@ -0,0 +1,30 @@
+#!/usr/bin/env node
+
+//process.env.DEBUG_NOPT = 1
+
+// my-program.js
+var nopt = require("../lib/nopt")
+ , Stream = require("stream").Stream
+ , path = require("path")
+ , knownOpts = { "foo" : [String, null]
+ , "bar" : [Stream, Number]
+ , "baz" : path
+ , "bloo" : [ "big", "medium", "small" ]
+ , "flag" : Boolean
+ , "pick" : Boolean
+ }
+ , shortHands = { "foofoo" : ["--foo", "Mr. Foo"]
+ , "b7" : ["--bar", "7"]
+ , "m" : ["--bloo", "medium"]
+ , "p" : ["--pick"]
+ , "f" : ["--flag", "true"]
+ , "g" : ["--flag"]
+ , "s" : "--flag"
+ }
+ // everything is optional.
+ // knownOpts and shorthands default to {}
+ // arg list defaults to process.argv
+ // slice defaults to 2
+ , parsed = nopt(knownOpts, shortHands, process.argv, 2)
+
+console.log("parsed =\n"+ require("util").inspect(parsed))
diff --git a/node_modules/nopt/test/basic.js b/node_modules/nopt/test/basic.js
new file mode 100644
index 00000000..d399de92
--- /dev/null
+++ b/node_modules/nopt/test/basic.js
@@ -0,0 +1,273 @@
+var nopt = require("../")
+ , test = require('tap').test
+
+
+test("passing a string results in a string", function (t) {
+ var parsed = nopt({ key: String }, {}, ["--key", "myvalue"], 0)
+ t.same(parsed.key, "myvalue")
+ t.end()
+})
+
+// https://github.com/npm/nopt/issues/31
+test("Empty String results in empty string, not true", function (t) {
+ var parsed = nopt({ empty: String }, {}, ["--empty"], 0)
+ t.same(parsed.empty, "")
+ t.end()
+})
+
+test("~ path is resolved to $HOME", function (t) {
+ var path = require("path")
+ if (!process.env.HOME) process.env.HOME = "/tmp"
+ var parsed = nopt({key: path}, {}, ["--key=~/val"], 0)
+ t.same(parsed.key, path.resolve(process.env.HOME, "val"))
+ t.end()
+})
+
+// https://github.com/npm/nopt/issues/24
+test("Unknown options are not parsed as numbers", function (t) {
+ var parsed = nopt({"parse-me": Number}, null, ['--leave-as-is=1.20', '--parse-me=1.20'], 0)
+ t.equal(parsed['leave-as-is'], '1.20')
+ t.equal(parsed['parse-me'], 1.2)
+ t.end()
+});
+
+// https://github.com/npm/nopt/issues/48
+test("Check types based on name of type", function (t) {
+ var parsed = nopt({"parse-me": {name: "Number"}}, null, ['--parse-me=1.20'], 0)
+ t.equal(parsed['parse-me'], 1.2)
+ t.end()
+})
+
+
+test("Missing types are not parsed", function (t) {
+ var parsed = nopt({"parse-me": {}}, null, ['--parse-me=1.20'], 0)
+ //should only contain argv
+ t.equal(Object.keys(parsed).length, 1)
+ t.end()
+})
+
+test("Types passed without a name are not parsed", function (t) {
+ var parsed = nopt({"parse-me": {}}, {}, ['--parse-me=1.20'], 0)
+ //should only contain argv
+ t.equal(Object.keys(parsed).length, 1)
+ t.end()
+})
+
+test("other tests", function (t) {
+
+ var util = require("util")
+ , Stream = require("stream")
+ , path = require("path")
+ , url = require("url")
+
+ , shorthands =
+ { s : ["--loglevel", "silent"]
+ , d : ["--loglevel", "info"]
+ , dd : ["--loglevel", "verbose"]
+ , ddd : ["--loglevel", "silly"]
+ , noreg : ["--no-registry"]
+ , reg : ["--registry"]
+ , "no-reg" : ["--no-registry"]
+ , silent : ["--loglevel", "silent"]
+ , verbose : ["--loglevel", "verbose"]
+ , h : ["--usage"]
+ , H : ["--usage"]
+ , "?" : ["--usage"]
+ , help : ["--usage"]
+ , v : ["--version"]
+ , f : ["--force"]
+ , desc : ["--description"]
+ , "no-desc" : ["--no-description"]
+ , "local" : ["--no-global"]
+ , l : ["--long"]
+ , p : ["--parseable"]
+ , porcelain : ["--parseable"]
+ , g : ["--global"]
+ }
+
+ , types =
+ { aoa: Array
+ , nullstream: [null, Stream]
+ , date: Date
+ , str: String
+ , browser : String
+ , cache : path
+ , color : ["always", Boolean]
+ , depth : Number
+ , description : Boolean
+ , dev : Boolean
+ , editor : path
+ , force : Boolean
+ , global : Boolean
+ , globalconfig : path
+ , group : [String, Number]
+ , gzipbin : String
+ , logfd : [Number, Stream]
+ , loglevel : ["silent","win","error","warn","info","verbose","silly"]
+ , long : Boolean
+ , "node-version" : [false, String]
+ , npaturl : url
+ , npat : Boolean
+ , "onload-script" : [false, String]
+ , outfd : [Number, Stream]
+ , parseable : Boolean
+ , pre: Boolean
+ , prefix: path
+ , proxy : url
+ , "rebuild-bundle" : Boolean
+ , registry : url
+ , searchopts : String
+ , searchexclude: [null, String]
+ , shell : path
+ , t: [Array, String]
+ , tag : String
+ , tar : String
+ , tmp : path
+ , "unsafe-perm" : Boolean
+ , usage : Boolean
+ , user : String
+ , username : String
+ , userconfig : path
+ , version : Boolean
+ , viewer: path
+ , _exit : Boolean
+ , path: path
+ }
+
+ ; [["-v", {version:true}, []]
+ ,["---v", {version:true}, []]
+ ,["ls -s --no-reg connect -d",
+ {loglevel:"info",registry:null},["ls","connect"]]
+ ,["ls ---s foo",{loglevel:"silent"},["ls","foo"]]
+ ,["ls --registry blargle", {}, ["ls"]]
+ ,["--no-registry", {registry:null}, []]
+ ,["--no-color true", {color:false}, []]
+ ,["--no-color false", {color:true}, []]
+ ,["--no-color", {color:false}, []]
+ ,["--color false", {color:false}, []]
+ ,["--color --logfd 7", {logfd:7,color:true}, []]
+ ,["--color=true", {color:true}, []]
+ ,["--logfd=10", {logfd:10}, []]
+ ,["--tmp=/tmp -tar=gtar",{tmp:"/tmp",tar:"gtar"},[]]
+ ,["--tmp=tmp -tar=gtar",
+ {tmp:path.resolve(process.cwd(), "tmp"),tar:"gtar"},[]]
+ ,["--logfd x", {}, []]
+ ,["a -true -- -no-false", {true:true},["a","-no-false"]]
+ ,["a -no-false", {false:false},["a"]]
+ ,["a -no-no-true", {true:true}, ["a"]]
+ ,["a -no-no-no-false", {false:false}, ["a"]]
+ ,["---NO-no-No-no-no-no-nO-no-no"+
+ "-No-no-no-no-no-no-no-no-no"+
+ "-no-no-no-no-NO-NO-no-no-no-no-no-no"+
+ "-no-body-can-do-the-boogaloo-like-I-do"
+ ,{"body-can-do-the-boogaloo-like-I-do":false}, []]
+ ,["we are -no-strangers-to-love "+
+ "--you-know=the-rules --and=so-do-i "+
+ "---im-thinking-of=a-full-commitment "+
+ "--no-you-would-get-this-from-any-other-guy "+
+ "--no-gonna-give-you-up "+
+ "-no-gonna-let-you-down=true "+
+ "--no-no-gonna-run-around false "+
+ "--desert-you=false "+
+ "--make-you-cry false "+
+ "--no-tell-a-lie "+
+ "--no-no-and-hurt-you false"
+ ,{"strangers-to-love":false
+ ,"you-know":"the-rules"
+ ,"and":"so-do-i"
+ ,"you-would-get-this-from-any-other-guy":false
+ ,"gonna-give-you-up":false
+ ,"gonna-let-you-down":false
+ ,"gonna-run-around":false
+ ,"desert-you":false
+ ,"make-you-cry":false
+ ,"tell-a-lie":false
+ ,"and-hurt-you":false
+ },["we", "are"]]
+ ,["-t one -t two -t three"
+ ,{t: ["one", "two", "three"]}
+ ,[]]
+ ,["-t one -t null -t three four five null"
+ ,{t: ["one", "null", "three"]}
+ ,["four", "five", "null"]]
+ ,["-t foo"
+ ,{t:["foo"]}
+ ,[]]
+ ,["--no-t"
+ ,{t:["false"]}
+ ,[]]
+ ,["-no-no-t"
+ ,{t:["true"]}
+ ,[]]
+ ,["-aoa one -aoa null -aoa 100"
+ ,{aoa:["one", null, '100']}
+ ,[]]
+ ,["-str 100"
+ ,{str:"100"}
+ ,[]]
+ ,["--color always"
+ ,{color:"always"}
+ ,[]]
+ ,["--no-nullstream"
+ ,{nullstream:null}
+ ,[]]
+ ,["--nullstream false"
+ ,{nullstream:null}
+ ,[]]
+ ,["--notadate=2011-01-25"
+ ,{notadate: "2011-01-25"}
+ ,[]]
+ ,["--date 2011-01-25"
+ ,{date: new Date("2011-01-25")}
+ ,[]]
+ ,["-cl 1"
+ ,{config: true, length: 1}
+ ,[]
+ ,{config: Boolean, length: Number, clear: Boolean}
+ ,{c: "--config", l: "--length"}]
+ ,["--acount bla"
+ ,{"acount":true}
+ ,["bla"]
+ ,{account: Boolean, credentials: Boolean, options: String}
+ ,{a:"--account", c:"--credentials",o:"--options"}]
+ ,["--clear"
+ ,{clear:true}
+ ,[]
+ ,{clear:Boolean,con:Boolean,len:Boolean,exp:Boolean,add:Boolean,rep:Boolean}
+ ,{c:"--con",l:"--len",e:"--exp",a:"--add",r:"--rep"}]
+ ,["--file -"
+ ,{"file":"-"}
+ ,[]
+ ,{file:String}
+ ,{}]
+ ,["--file -"
+ ,{"file":true}
+ ,["-"]
+ ,{file:Boolean}
+ ,{}]
+ ,["--path"
+ ,{"path":null}
+ ,[]]
+ ,["--path ."
+ ,{"path":process.cwd()}
+ ,[]]
+ ].forEach(function (test) {
+ var argv = test[0].split(/\s+/)
+ , opts = test[1]
+ , rem = test[2]
+ , actual = nopt(test[3] || types, test[4] || shorthands, argv, 0)
+ , parsed = actual.argv
+ delete actual.argv
+ for (var i in opts) {
+ var e = JSON.stringify(opts[i])
+ , a = JSON.stringify(actual[i] === undefined ? null : actual[i])
+ if (e && typeof e === "object") {
+ t.deepEqual(e, a)
+ } else {
+ t.equal(e, a)
+ }
+ }
+ t.deepEqual(rem, parsed.remain)
+ })
+ t.end()
+})