From 2387e8ad33180b6fd96b70c52c95ef094810ccc6 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Sun, 16 Sep 2018 08:09:20 -0500
Subject: [PATCH 01/14] minor syntax fix

---
 main.js        | 4 ++--
 test/server.js | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/main.js b/main.js
index e760e1a..9e3377e 100755
--- a/main.js
+++ b/main.js
@@ -29,9 +29,9 @@ function collect(val, memo) {
 const defaultCacheModule = config.get("Cache.defaultModule");
 
 const processorOptions = config.get("Cache.options.processor");
-if(Array.isArray(processorOptions.putWhitelist) && processorOptions.putWhitelist.length){
+if(Array.isArray(processorOptions.putWhitelist) && processorOptions.putWhitelist.length) {
     helpers.log(consts.LOG_INFO, `PUT whitelist: ${processorOptions.putWhitelist}`);
-};
+}
 
 program.description("Unity Cache Server")
     .version(VERSION)
diff --git a/test/server.js b/test/server.js
index f2e7672..d792c4f 100644
--- a/test/server.js
+++ b/test/server.js
@@ -72,8 +72,8 @@ describe("Server common", function() {
         const ipv6Server = new CacheServer(cache, {port: 0, allowIpv6: true});
 
         before(function () {  
-            var interfaces = os.networkInterfaces();
-            var ipv6Available = false;
+            const interfaces = os.networkInterfaces();
+            let ipv6Available = false;
             Object.keys(interfaces).forEach(function (interfaceName){
                 interfaces[interfaceName].forEach(function (address){
                     if(address.family === "IPv6"){
@@ -95,7 +95,7 @@ describe("Server common", function() {
         });
     
         it("should bind to ipv6 when allowed", function(done) {
-            var serverAddress = ipv6Server._server.address();
+            const serverAddress = ipv6Server._server.address();
             assert.strictEqual(serverAddress.family, "IPv6");
             done();
         });
@@ -113,7 +113,7 @@ describe("Server common", function() {
         });
 
         it("should bind to ipv4 when ipv6 not allowed", function(done) {
-            var serverAddress = ipv4Server._server.address();
+            const serverAddress = ipv4Server._server.address();
             assert.strictEqual(serverAddress.family, "IPv4");
             done();
         });

From 247c77a7ba22248bb00dad7d5ea2dfcbe6b556a3 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Sun, 16 Sep 2018 08:15:50 -0500
Subject: [PATCH 02/14] Updated .gitignore rules

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 3010568..68baad0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ node_modules/
 coverage/
 local-production.yml
 .cache*/
+Dockerfile*
+.dockerignore
\ No newline at end of file

From 50887a926fe531dc886a2d684bf90b10205a20e7 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Sun, 16 Sep 2018 08:10:20 -0500
Subject: [PATCH 03/14] Skip DNS resolution if addresses are already in IP
 format

---
 lib/helpers.js | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/helpers.js b/lib/helpers.js
index ceb06d9..d660a15 100644
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -3,6 +3,7 @@ const consts = require("./constants");
 const dns = require('dns');
 const path = require('path');
 const fs = require('fs-extra');
+const ip = require('ip');
 
 let logLevel = consts.LOG_TEST;
 
@@ -94,10 +95,14 @@ exports.isBuffer = function(obj) {
 exports.parseAndValidateAddressString = function(address, defaultPort) {
     // eslint-disable-next-line prefer-const
     let [host, port] = address.split(':');
+    port = port || defaultPort;
 
     port = parseInt(port);
     if(!port) port = defaultPort;
 
+    if(ip.isV4Format(address) || ip.isV6Format(address))
+        return Promise.resolve({ host: address, port: port });
+
     return new Promise((resolve, reject) => {
         dns.lookup(host, {family: 4, hints: dns.ADDRCONFIG}, (err, address) => {
             if(err) return reject(err);

From 554ef626df26aee6a8b3e4f837e72cf4d3c86468 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Sun, 16 Sep 2018 08:13:21 -0500
Subject: [PATCH 04/14] Fix variable naming and incorrect variable references

---
 lib/helpers.js                   | 8 ++++----
 lib/server/transaction_mirror.js | 5 +++--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/lib/helpers.js b/lib/helpers.js
index d660a15..5b7b762 100644
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -100,13 +100,13 @@ exports.parseAndValidateAddressString = function(address, defaultPort) {
     port = parseInt(port);
     if(!port) port = defaultPort;
 
-    if(ip.isV4Format(address) || ip.isV6Format(address))
-        return Promise.resolve({ host: address, port: port });
+    if(ip.isV4Format(host) || ip.isV6Format(host))
+        return Promise.resolve({ host: host, port: port });
 
     return new Promise((resolve, reject) => {
-        dns.lookup(host, {family: 4, hints: dns.ADDRCONFIG}, (err, address) => {
+        dns.lookup(host, {family: 4, hints: dns.ADDRCONFIG}, (err, ip) => {
             if(err) return reject(err);
-            resolve({ host: address, port: port });
+            resolve({ host: ip, port: port });
         });
     });
 };
diff --git a/lib/server/transaction_mirror.js b/lib/server/transaction_mirror.js
index 7fa10b0..2fd4c0b 100644
--- a/lib/server/transaction_mirror.js
+++ b/lib/server/transaction_mirror.js
@@ -23,10 +23,10 @@ class TransactionMirror {
         this._processing = false;
         this._queueProcessDelay = TransactionMirror.options.queueProcessDelay || PROCESS_DELAY_MS;
 
-        const address = connectOptions.address;
+        const host = connectOptions.host;
         const port = connectOptions.port;
         const idleTimeout = TransactionMirror.options.idleTimeout || CONNECT_IDLE_TIMEOUT_MS;
-        this._client = new Client(address, port, {idleTimeout: idleTimeout});
+        this._client = new Client(host, port, {idleTimeout: idleTimeout});
     }
 
     static get options() {
@@ -38,6 +38,7 @@ class TransactionMirror {
     }
 
     _connect() {
+        helpers.log(consts.LOG_INFO, `[TransactionMirror] Connecting to ${this._connectOptions.host}:${this._connectOptions.port}`);
         return this._client.connect();
     }
 

From 266c934bb64026ab95ca3cdedc2175bf5d6ecefe Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Sun, 16 Sep 2018 08:14:28 -0500
Subject: [PATCH 05/14] Skip mirroring if mirror IP matches source transaction
 IP

---
 lib/server/server.js | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/server/server.js b/lib/server/server.js
index 4d2628f..5d6a00d 100644
--- a/lib/server/server.js
+++ b/lib/server/server.js
@@ -61,12 +61,13 @@ class CacheServer {
 
             const cmdProc = new CommandProcessor(self.cache);
 
-            // TODO: Prune mirror list to exclude the incoming socket address, to prevent looping transactions
             const mirrors = self._mirrors;
-
             if(mirrors.length > 0) {
                 cmdProc.on('onTransactionEnd', (trx) => {
-                    mirrors.forEach(m => m.queueTransaction(trx));
+                    mirrors.forEach(m => {
+                        if(m.address !== socket.remoteAddress)
+                            m.queueTransaction(trx);
+                    });
                 });
             }
 

From 441938819c2f8bb1598b2e1e85e8b3f8258c1dbf Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Sun, 16 Sep 2018 10:20:48 -0500
Subject: [PATCH 06/14] Print startup log message for configured transaction
 mirrors

---
 lib/server/transaction_mirror.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/server/transaction_mirror.js b/lib/server/transaction_mirror.js
index 2fd4c0b..4f3ab58 100644
--- a/lib/server/transaction_mirror.js
+++ b/lib/server/transaction_mirror.js
@@ -27,6 +27,7 @@ class TransactionMirror {
         const port = connectOptions.port;
         const idleTimeout = TransactionMirror.options.idleTimeout || CONNECT_IDLE_TIMEOUT_MS;
         this._client = new Client(host, port, {idleTimeout: idleTimeout});
+        helpers.log(consts.LOG_INFO, `[TransactionMirror] Mirroring transactions to ${host}:${port}`);
     }
 
     static get options() {

From 0e8d48768dcc7cafd481208ff1672891b6a60e74 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Sun, 16 Sep 2018 15:55:56 -0500
Subject: [PATCH 07/14] Updated node to latest LTS release; updated package
 dependencies; bumped version to 6.1.2-beta.0

---
 .nvmrc            |    2 +-
 package-lock.json | 1218 ++++++++++++++++++++++-----------------------
 package.json      |    4 +-
 3 files changed, 612 insertions(+), 612 deletions(-)

diff --git a/.nvmrc b/.nvmrc
index 41c4217..368fe85 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v8.11.3
+v8.12.0
diff --git a/package-lock.json b/package-lock.json
index 0527420..840a102 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "unity-cache-server",
-  "version": "6.1.1",
+  "version": "6.1.2-beta.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -19,10 +19,10 @@
       "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
       "dev": true,
       "requires": {
-        "co": "4.6.0",
-        "fast-deep-equal": "1.1.0",
-        "fast-json-stable-stringify": "2.0.0",
-        "json-schema-traverse": "0.3.1"
+        "co": "^4.6.0",
+        "fast-deep-equal": "^1.0.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.3.0"
       }
     },
     "ansi-styles": {
@@ -30,7 +30,7 @@
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
       "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
       "requires": {
-        "color-convert": "1.9.1"
+        "color-convert": "^1.9.0"
       }
     },
     "argparse": {
@@ -38,7 +38,7 @@
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
       "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
       "requires": {
-        "sprintf-js": "1.0.3"
+        "sprintf-js": "~1.0.2"
       }
     },
     "asn1": {
@@ -84,7 +84,7 @@
       "dev": true,
       "optional": true,
       "requires": {
-        "tweetnacl": "0.14.5"
+        "tweetnacl": "^0.14.3"
       }
     },
     "bluebird": {
@@ -99,7 +99,7 @@
       "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
       "dev": true,
       "requires": {
-        "hoek": "4.2.1"
+        "hoek": "4.x.x"
       }
     },
     "brace-expansion": {
@@ -108,7 +108,7 @@
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
       "dev": true,
       "requires": {
-        "balanced-match": "1.0.0",
+        "balanced-match": "^1.0.0",
         "concat-map": "0.0.1"
       }
     },
@@ -129,9 +129,9 @@
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
       "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
       "requires": {
-        "ansi-styles": "3.2.1",
-        "escape-string-regexp": "1.0.5",
-        "supports-color": "5.4.0"
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
       }
     },
     "cli-cursor": {
@@ -139,7 +139,7 @@
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
       "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
       "requires": {
-        "restore-cursor": "2.0.0"
+        "restore-cursor": "^2.0.0"
       }
     },
     "cli-spinners": {
@@ -158,7 +158,7 @@
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
       "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
       "requires": {
-        "color-name": "1.1.3"
+        "color-name": "^1.1.1"
       }
     },
     "color-name": {
@@ -172,7 +172,7 @@
       "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
       "dev": true,
       "requires": {
-        "delayed-stream": "1.0.0"
+        "delayed-stream": "~1.0.0"
       }
     },
     "commander": {
@@ -191,7 +191,7 @@
       "resolved": "https://registry.npmjs.org/config/-/config-1.31.0.tgz",
       "integrity": "sha512-Ep/l9Rd1J9IPueztJfpbOqVzuKHQh4ZODMNt9xqTYdBBNRXbV4oTu34kCkkfdRVcDq0ohtpaeXGgb+c0LQxFRA==",
       "requires": {
-        "json5": "1.0.1"
+        "json5": "^1.0.1"
       },
       "dependencies": {
         "json5": {
@@ -199,7 +199,7 @@
           "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
           "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
           "requires": {
-            "minimist": "1.2.0"
+            "minimist": "^1.2.0"
           }
         }
       }
@@ -216,12 +216,12 @@
       "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==",
       "dev": true,
       "requires": {
-        "growl": "1.10.3",
-        "js-yaml": "3.12.0",
-        "lcov-parse": "0.0.10",
-        "log-driver": "1.2.7",
-        "minimist": "1.2.0",
-        "request": "2.85.0"
+        "growl": "~> 1.10.0",
+        "js-yaml": "^3.11.0",
+        "lcov-parse": "^0.0.10",
+        "log-driver": "^1.2.7",
+        "minimist": "^1.2.0",
+        "request": "^2.85.0"
       }
     },
     "cryptiles": {
@@ -230,7 +230,7 @@
       "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
       "dev": true,
       "requires": {
-        "boom": "5.2.0"
+        "boom": "5.x.x"
       },
       "dependencies": {
         "boom": {
@@ -239,7 +239,7 @@
           "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
           "dev": true,
           "requires": {
-            "hoek": "4.2.1"
+            "hoek": "4.x.x"
           }
         }
       }
@@ -250,7 +250,7 @@
       "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
       "dev": true,
       "requires": {
-        "assert-plus": "1.0.0"
+        "assert-plus": "^1.0.0"
       }
     },
     "debug": {
@@ -281,7 +281,7 @@
       "dev": true,
       "optional": true,
       "requires": {
-        "jsbn": "0.1.1"
+        "jsbn": "~0.1.0"
       }
     },
     "escape-string-regexp": {
@@ -335,9 +335,9 @@
       "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
       "dev": true,
       "requires": {
-        "asynckit": "0.4.0",
+        "asynckit": "^0.4.0",
         "combined-stream": "1.0.6",
-        "mime-types": "2.1.18"
+        "mime-types": "^2.1.12"
       }
     },
     "fs-extra": {
@@ -345,9 +345,9 @@
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
       "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
       "requires": {
-        "graceful-fs": "4.1.11",
-        "jsonfile": "4.0.0",
-        "universalify": "0.1.1"
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
       }
     },
     "fs.realpath": {
@@ -362,7 +362,7 @@
       "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
       "dev": true,
       "requires": {
-        "assert-plus": "1.0.0"
+        "assert-plus": "^1.0.0"
       }
     },
     "glob": {
@@ -371,12 +371,12 @@
       "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
       "dev": true,
       "requires": {
-        "fs.realpath": "1.0.0",
-        "inflight": "1.0.6",
-        "inherits": "2.0.3",
-        "minimatch": "3.0.4",
-        "once": "1.4.0",
-        "path-is-absolute": "1.0.1"
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
       }
     },
     "graceful-fs": {
@@ -402,8 +402,8 @@
       "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
       "dev": true,
       "requires": {
-        "ajv": "5.5.2",
-        "har-schema": "2.0.0"
+        "ajv": "^5.1.0",
+        "har-schema": "^2.0.0"
       }
     },
     "has-flag": {
@@ -417,10 +417,10 @@
       "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
       "dev": true,
       "requires": {
-        "boom": "4.3.1",
-        "cryptiles": "3.1.2",
-        "hoek": "4.2.1",
-        "sntp": "2.1.0"
+        "boom": "4.x.x",
+        "cryptiles": "3.x.x",
+        "hoek": "4.x.x",
+        "sntp": "2.x.x"
       }
     },
     "he": {
@@ -441,9 +441,9 @@
       "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
       "dev": true,
       "requires": {
-        "assert-plus": "1.0.0",
-        "jsprim": "1.4.1",
-        "sshpk": "1.14.1"
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
       }
     },
     "inflight": {
@@ -452,8 +452,8 @@
       "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
       "dev": true,
       "requires": {
-        "once": "1.4.0",
-        "wrappy": "1.0.2"
+        "once": "^1.3.0",
+        "wrappy": "1"
       }
     },
     "inherits": {
@@ -490,8 +490,8 @@
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
       "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
       "requires": {
-        "argparse": "1.0.10",
-        "esprima": "4.0.0"
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
       }
     },
     "jsbn": {
@@ -524,7 +524,7 @@
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
       "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
       "requires": {
-        "graceful-fs": "4.1.11"
+        "graceful-fs": "^4.1.6"
       }
     },
     "jsprim": {
@@ -573,7 +573,7 @@
       "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
       "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
       "requires": {
-        "chalk": "2.4.1"
+        "chalk": "^2.0.1"
       }
     },
     "lokijs": {
@@ -599,7 +599,7 @@
       "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
       "dev": true,
       "requires": {
-        "mime-db": "1.33.0"
+        "mime-db": "~1.33.0"
       }
     },
     "mimic-fn": {
@@ -613,7 +613,7 @@
       "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
       "dev": true,
       "requires": {
-        "brace-expansion": "1.1.11"
+        "brace-expansion": "^1.1.7"
       }
     },
     "minimist": {
@@ -659,7 +659,7 @@
       "dependencies": {
         "commander": {
           "version": "2.15.1",
-          "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
           "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
           "dev": true
         },
@@ -700,11 +700,11 @@
       "integrity": "sha512-v1J/FLUB9PfGqZLGDBhQqODkbLotP0WtLo9R4EJY2PPu5f5Xg4o0rA8FDlmrjFSv9vBBKcfnOSpfYYuu5RTHqg==",
       "dev": true,
       "requires": {
-        "@sinonjs/formatio": "2.0.0",
-        "just-extend": "1.1.27",
-        "lolex": "2.4.1",
-        "path-to-regexp": "1.7.0",
-        "text-encoding": "0.6.4"
+        "@sinonjs/formatio": "^2.0.0",
+        "just-extend": "^1.1.27",
+        "lolex": "^2.3.2",
+        "path-to-regexp": "^1.7.0",
+        "text-encoding": "^0.6.4"
       }
     },
     "nyc": {
@@ -713,33 +713,33 @@
       "integrity": "sha512-w8OdJAhXL5izerzZMdqzYKMj/pgHJyY3qEPYBjLLxrhcVoHEY9pU5ENIiZyCgG9OR7x3VcUMoD40o6PtVpfR4g==",
       "dev": true,
       "requires": {
-        "archy": "1.0.0",
-        "arrify": "1.0.1",
-        "caching-transform": "1.0.1",
-        "convert-source-map": "1.5.1",
-        "debug-log": "1.0.1",
-        "default-require-extensions": "1.0.0",
-        "find-cache-dir": "0.1.1",
-        "find-up": "2.1.0",
-        "foreground-child": "1.5.6",
-        "glob": "7.1.2",
-        "istanbul-lib-coverage": "1.2.0",
-        "istanbul-lib-hook": "1.1.0",
-        "istanbul-lib-instrument": "1.10.1",
-        "istanbul-lib-report": "1.1.3",
-        "istanbul-lib-source-maps": "1.2.3",
-        "istanbul-reports": "1.4.0",
-        "md5-hex": "1.3.0",
-        "merge-source-map": "1.1.0",
-        "micromatch": "3.1.10",
-        "mkdirp": "0.5.1",
-        "resolve-from": "2.0.0",
-        "rimraf": "2.6.2",
-        "signal-exit": "3.0.2",
-        "spawn-wrap": "1.4.2",
-        "test-exclude": "4.2.1",
+        "archy": "^1.0.0",
+        "arrify": "^1.0.1",
+        "caching-transform": "^1.0.0",
+        "convert-source-map": "^1.5.1",
+        "debug-log": "^1.0.1",
+        "default-require-extensions": "^1.0.0",
+        "find-cache-dir": "^0.1.1",
+        "find-up": "^2.1.0",
+        "foreground-child": "^1.5.3",
+        "glob": "^7.0.6",
+        "istanbul-lib-coverage": "^1.1.2",
+        "istanbul-lib-hook": "^1.1.0",
+        "istanbul-lib-instrument": "^1.10.0",
+        "istanbul-lib-report": "^1.1.3",
+        "istanbul-lib-source-maps": "^1.2.3",
+        "istanbul-reports": "^1.4.0",
+        "md5-hex": "^1.2.0",
+        "merge-source-map": "^1.1.0",
+        "micromatch": "^3.1.10",
+        "mkdirp": "^0.5.0",
+        "resolve-from": "^2.0.0",
+        "rimraf": "^2.6.2",
+        "signal-exit": "^3.0.1",
+        "spawn-wrap": "^1.4.2",
+        "test-exclude": "^4.2.0",
         "yargs": "11.1.0",
-        "yargs-parser": "8.1.0"
+        "yargs-parser": "^8.0.0"
       },
       "dependencies": {
         "align-text": {
@@ -747,9 +747,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "kind-of": "3.2.2",
-            "longest": "1.0.1",
-            "repeat-string": "1.6.1"
+            "kind-of": "^3.0.2",
+            "longest": "^1.0.1",
+            "repeat-string": "^1.5.2"
           }
         },
         "amdefine": {
@@ -772,7 +772,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "default-require-extensions": "1.0.0"
+            "default-require-extensions": "^1.0.0"
           }
         },
         "archy": {
@@ -825,9 +825,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "chalk": "1.1.3",
-            "esutils": "2.0.2",
-            "js-tokens": "3.0.2"
+            "chalk": "^1.1.3",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.2"
           }
         },
         "babel-generator": {
@@ -835,14 +835,14 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "babel-messages": "6.23.0",
-            "babel-runtime": "6.26.0",
-            "babel-types": "6.26.0",
-            "detect-indent": "4.0.0",
-            "jsesc": "1.3.0",
-            "lodash": "4.17.10",
-            "source-map": "0.5.7",
-            "trim-right": "1.0.1"
+            "babel-messages": "^6.23.0",
+            "babel-runtime": "^6.26.0",
+            "babel-types": "^6.26.0",
+            "detect-indent": "^4.0.0",
+            "jsesc": "^1.3.0",
+            "lodash": "^4.17.4",
+            "source-map": "^0.5.7",
+            "trim-right": "^1.0.1"
           }
         },
         "babel-messages": {
@@ -850,7 +850,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "babel-runtime": "6.26.0"
+            "babel-runtime": "^6.22.0"
           }
         },
         "babel-runtime": {
@@ -858,8 +858,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "core-js": "2.5.6",
-            "regenerator-runtime": "0.11.1"
+            "core-js": "^2.4.0",
+            "regenerator-runtime": "^0.11.0"
           }
         },
         "babel-template": {
@@ -867,11 +867,11 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "babel-runtime": "6.26.0",
-            "babel-traverse": "6.26.0",
-            "babel-types": "6.26.0",
-            "babylon": "6.18.0",
-            "lodash": "4.17.10"
+            "babel-runtime": "^6.26.0",
+            "babel-traverse": "^6.26.0",
+            "babel-types": "^6.26.0",
+            "babylon": "^6.18.0",
+            "lodash": "^4.17.4"
           }
         },
         "babel-traverse": {
@@ -879,15 +879,15 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "babel-code-frame": "6.26.0",
-            "babel-messages": "6.23.0",
-            "babel-runtime": "6.26.0",
-            "babel-types": "6.26.0",
-            "babylon": "6.18.0",
-            "debug": "2.6.9",
-            "globals": "9.18.0",
-            "invariant": "2.2.4",
-            "lodash": "4.17.10"
+            "babel-code-frame": "^6.26.0",
+            "babel-messages": "^6.23.0",
+            "babel-runtime": "^6.26.0",
+            "babel-types": "^6.26.0",
+            "babylon": "^6.18.0",
+            "debug": "^2.6.8",
+            "globals": "^9.18.0",
+            "invariant": "^2.2.2",
+            "lodash": "^4.17.4"
           }
         },
         "babel-types": {
@@ -895,10 +895,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "babel-runtime": "6.26.0",
-            "esutils": "2.0.2",
-            "lodash": "4.17.10",
-            "to-fast-properties": "1.0.3"
+            "babel-runtime": "^6.26.0",
+            "esutils": "^2.0.2",
+            "lodash": "^4.17.4",
+            "to-fast-properties": "^1.0.3"
           }
         },
         "babylon": {
@@ -916,13 +916,13 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "cache-base": "1.0.1",
-            "class-utils": "0.3.6",
-            "component-emitter": "1.2.1",
-            "define-property": "1.0.0",
-            "isobject": "3.0.1",
-            "mixin-deep": "1.3.1",
-            "pascalcase": "0.1.1"
+            "cache-base": "^1.0.1",
+            "class-utils": "^0.3.5",
+            "component-emitter": "^1.2.1",
+            "define-property": "^1.0.0",
+            "isobject": "^3.0.1",
+            "mixin-deep": "^1.2.0",
+            "pascalcase": "^0.1.1"
           },
           "dependencies": {
             "define-property": {
@@ -930,7 +930,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-descriptor": "1.0.2"
+                "is-descriptor": "^1.0.0"
               }
             },
             "is-accessor-descriptor": {
@@ -938,7 +938,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-data-descriptor": {
@@ -946,7 +946,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-descriptor": {
@@ -954,9 +954,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-accessor-descriptor": "1.0.0",
-                "is-data-descriptor": "1.0.0",
-                "kind-of": "6.0.2"
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
               }
             },
             "isobject": {
@@ -976,7 +976,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "balanced-match": "1.0.0",
+            "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
           }
         },
@@ -985,16 +985,16 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "arr-flatten": "1.1.0",
-            "array-unique": "0.3.2",
-            "extend-shallow": "2.0.1",
-            "fill-range": "4.0.0",
-            "isobject": "3.0.1",
-            "repeat-element": "1.1.2",
-            "snapdragon": "0.8.2",
-            "snapdragon-node": "2.1.1",
-            "split-string": "3.1.0",
-            "to-regex": "3.0.2"
+            "arr-flatten": "^1.1.0",
+            "array-unique": "^0.3.2",
+            "extend-shallow": "^2.0.1",
+            "fill-range": "^4.0.0",
+            "isobject": "^3.0.1",
+            "repeat-element": "^1.1.2",
+            "snapdragon": "^0.8.1",
+            "snapdragon-node": "^2.0.1",
+            "split-string": "^3.0.2",
+            "to-regex": "^3.0.1"
           },
           "dependencies": {
             "extend-shallow": {
@@ -1002,7 +1002,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-extendable": "0.1.1"
+                "is-extendable": "^0.1.0"
               }
             }
           }
@@ -1017,15 +1017,15 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "collection-visit": "1.0.0",
-            "component-emitter": "1.2.1",
-            "get-value": "2.0.6",
-            "has-value": "1.0.0",
-            "isobject": "3.0.1",
-            "set-value": "2.0.0",
-            "to-object-path": "0.3.0",
-            "union-value": "1.0.0",
-            "unset-value": "1.0.0"
+            "collection-visit": "^1.0.0",
+            "component-emitter": "^1.2.1",
+            "get-value": "^2.0.6",
+            "has-value": "^1.0.0",
+            "isobject": "^3.0.1",
+            "set-value": "^2.0.0",
+            "to-object-path": "^0.3.0",
+            "union-value": "^1.0.0",
+            "unset-value": "^1.0.0"
           },
           "dependencies": {
             "isobject": {
@@ -1040,9 +1040,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "md5-hex": "1.3.0",
-            "mkdirp": "0.5.1",
-            "write-file-atomic": "1.3.4"
+            "md5-hex": "^1.2.0",
+            "mkdirp": "^0.5.1",
+            "write-file-atomic": "^1.1.4"
           }
         },
         "camelcase": {
@@ -1057,8 +1057,8 @@
           "dev": true,
           "optional": true,
           "requires": {
-            "align-text": "0.1.4",
-            "lazy-cache": "1.0.4"
+            "align-text": "^0.1.3",
+            "lazy-cache": "^1.0.3"
           }
         },
         "chalk": {
@@ -1066,11 +1066,11 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "ansi-styles": "2.2.1",
-            "escape-string-regexp": "1.0.5",
-            "has-ansi": "2.0.0",
-            "strip-ansi": "3.0.1",
-            "supports-color": "2.0.0"
+            "ansi-styles": "^2.2.1",
+            "escape-string-regexp": "^1.0.2",
+            "has-ansi": "^2.0.0",
+            "strip-ansi": "^3.0.0",
+            "supports-color": "^2.0.0"
           }
         },
         "class-utils": {
@@ -1078,10 +1078,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "arr-union": "3.1.0",
-            "define-property": "0.2.5",
-            "isobject": "3.0.1",
-            "static-extend": "0.1.2"
+            "arr-union": "^3.1.0",
+            "define-property": "^0.2.5",
+            "isobject": "^3.0.0",
+            "static-extend": "^0.1.1"
           },
           "dependencies": {
             "define-property": {
@@ -1089,7 +1089,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-descriptor": "0.1.6"
+                "is-descriptor": "^0.1.0"
               }
             },
             "isobject": {
@@ -1105,8 +1105,8 @@
           "dev": true,
           "optional": true,
           "requires": {
-            "center-align": "0.1.3",
-            "right-align": "0.1.3",
+            "center-align": "^0.1.1",
+            "right-align": "^0.1.1",
             "wordwrap": "0.0.2"
           },
           "dependencies": {
@@ -1128,8 +1128,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "map-visit": "1.0.0",
-            "object-visit": "1.0.1"
+            "map-visit": "^1.0.0",
+            "object-visit": "^1.0.0"
           }
         },
         "commondir": {
@@ -1167,8 +1167,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "lru-cache": "4.1.3",
-            "which": "1.3.0"
+            "lru-cache": "^4.0.1",
+            "which": "^1.2.9"
           }
         },
         "debug": {
@@ -1199,7 +1199,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "strip-bom": "2.0.0"
+            "strip-bom": "^2.0.0"
           }
         },
         "define-property": {
@@ -1207,8 +1207,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-descriptor": "1.0.2",
-            "isobject": "3.0.1"
+            "is-descriptor": "^1.0.2",
+            "isobject": "^3.0.1"
           },
           "dependencies": {
             "is-accessor-descriptor": {
@@ -1216,7 +1216,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-data-descriptor": {
@@ -1224,7 +1224,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-descriptor": {
@@ -1232,9 +1232,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-accessor-descriptor": "1.0.0",
-                "is-data-descriptor": "1.0.0",
-                "kind-of": "6.0.2"
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
               }
             },
             "isobject": {
@@ -1254,7 +1254,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "repeating": "2.0.1"
+            "repeating": "^2.0.0"
           }
         },
         "error-ex": {
@@ -1262,7 +1262,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-arrayish": "0.2.1"
+            "is-arrayish": "^0.2.1"
           }
         },
         "escape-string-regexp": {
@@ -1280,13 +1280,13 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "cross-spawn": "5.1.0",
-            "get-stream": "3.0.0",
-            "is-stream": "1.1.0",
-            "npm-run-path": "2.0.2",
-            "p-finally": "1.0.0",
-            "signal-exit": "3.0.2",
-            "strip-eof": "1.0.0"
+            "cross-spawn": "^5.0.1",
+            "get-stream": "^3.0.0",
+            "is-stream": "^1.1.0",
+            "npm-run-path": "^2.0.0",
+            "p-finally": "^1.0.0",
+            "signal-exit": "^3.0.0",
+            "strip-eof": "^1.0.0"
           },
           "dependencies": {
             "cross-spawn": {
@@ -1294,9 +1294,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "lru-cache": "4.1.3",
-                "shebang-command": "1.2.0",
-                "which": "1.3.0"
+                "lru-cache": "^4.0.1",
+                "shebang-command": "^1.2.0",
+                "which": "^1.2.9"
               }
             }
           }
@@ -1306,13 +1306,13 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "debug": "2.6.9",
-            "define-property": "0.2.5",
-            "extend-shallow": "2.0.1",
-            "posix-character-classes": "0.1.1",
-            "regex-not": "1.0.2",
-            "snapdragon": "0.8.2",
-            "to-regex": "3.0.2"
+            "debug": "^2.3.3",
+            "define-property": "^0.2.5",
+            "extend-shallow": "^2.0.1",
+            "posix-character-classes": "^0.1.0",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.1"
           },
           "dependencies": {
             "define-property": {
@@ -1320,7 +1320,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-descriptor": "0.1.6"
+                "is-descriptor": "^0.1.0"
               }
             },
             "extend-shallow": {
@@ -1328,7 +1328,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-extendable": "0.1.1"
+                "is-extendable": "^0.1.0"
               }
             }
           }
@@ -1338,8 +1338,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "assign-symbols": "1.0.0",
-            "is-extendable": "1.0.1"
+            "assign-symbols": "^1.0.0",
+            "is-extendable": "^1.0.1"
           },
           "dependencies": {
             "is-extendable": {
@@ -1347,7 +1347,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-plain-object": "2.0.4"
+                "is-plain-object": "^2.0.4"
               }
             }
           }
@@ -1357,14 +1357,14 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "array-unique": "0.3.2",
-            "define-property": "1.0.0",
-            "expand-brackets": "2.1.4",
-            "extend-shallow": "2.0.1",
-            "fragment-cache": "0.2.1",
-            "regex-not": "1.0.2",
-            "snapdragon": "0.8.2",
-            "to-regex": "3.0.2"
+            "array-unique": "^0.3.2",
+            "define-property": "^1.0.0",
+            "expand-brackets": "^2.1.4",
+            "extend-shallow": "^2.0.1",
+            "fragment-cache": "^0.2.1",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.1"
           },
           "dependencies": {
             "define-property": {
@@ -1372,7 +1372,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-descriptor": "1.0.2"
+                "is-descriptor": "^1.0.0"
               }
             },
             "extend-shallow": {
@@ -1380,7 +1380,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-extendable": "0.1.1"
+                "is-extendable": "^0.1.0"
               }
             },
             "is-accessor-descriptor": {
@@ -1388,7 +1388,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-data-descriptor": {
@@ -1396,7 +1396,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-descriptor": {
@@ -1404,9 +1404,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-accessor-descriptor": "1.0.0",
-                "is-data-descriptor": "1.0.0",
-                "kind-of": "6.0.2"
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
               }
             },
             "kind-of": {
@@ -1421,10 +1421,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "extend-shallow": "2.0.1",
-            "is-number": "3.0.0",
-            "repeat-string": "1.6.1",
-            "to-regex-range": "2.1.1"
+            "extend-shallow": "^2.0.1",
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1",
+            "to-regex-range": "^2.1.0"
           },
           "dependencies": {
             "extend-shallow": {
@@ -1432,7 +1432,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-extendable": "0.1.1"
+                "is-extendable": "^0.1.0"
               }
             }
           }
@@ -1442,9 +1442,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "commondir": "1.0.1",
-            "mkdirp": "0.5.1",
-            "pkg-dir": "1.0.0"
+            "commondir": "^1.0.1",
+            "mkdirp": "^0.5.1",
+            "pkg-dir": "^1.0.0"
           }
         },
         "find-up": {
@@ -1452,7 +1452,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "locate-path": "2.0.0"
+            "locate-path": "^2.0.0"
           }
         },
         "for-in": {
@@ -1465,8 +1465,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "cross-spawn": "4.0.2",
-            "signal-exit": "3.0.2"
+            "cross-spawn": "^4",
+            "signal-exit": "^3.0.0"
           }
         },
         "fragment-cache": {
@@ -1474,7 +1474,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "map-cache": "0.2.2"
+            "map-cache": "^0.2.2"
           }
         },
         "fs.realpath": {
@@ -1502,12 +1502,12 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
           }
         },
         "globals": {
@@ -1525,10 +1525,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "async": "1.5.2",
-            "optimist": "0.6.1",
-            "source-map": "0.4.4",
-            "uglify-js": "2.8.29"
+            "async": "^1.4.0",
+            "optimist": "^0.6.1",
+            "source-map": "^0.4.4",
+            "uglify-js": "^2.6"
           },
           "dependencies": {
             "source-map": {
@@ -1536,7 +1536,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "amdefine": "1.0.1"
+                "amdefine": ">=0.0.4"
               }
             }
           }
@@ -1546,7 +1546,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "ansi-regex": "2.1.1"
+            "ansi-regex": "^2.0.0"
           }
         },
         "has-flag": {
@@ -1559,9 +1559,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "get-value": "2.0.6",
-            "has-values": "1.0.0",
-            "isobject": "3.0.1"
+            "get-value": "^2.0.6",
+            "has-values": "^1.0.0",
+            "isobject": "^3.0.0"
           },
           "dependencies": {
             "isobject": {
@@ -1576,8 +1576,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-number": "3.0.0",
-            "kind-of": "4.0.0"
+            "is-number": "^3.0.0",
+            "kind-of": "^4.0.0"
           },
           "dependencies": {
             "is-number": {
@@ -1585,7 +1585,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "3.2.2"
+                "kind-of": "^3.0.2"
               },
               "dependencies": {
                 "kind-of": {
@@ -1593,7 +1593,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-buffer": "1.1.6"
+                    "is-buffer": "^1.1.5"
                   }
                 }
               }
@@ -1603,7 +1603,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-buffer": "1.1.6"
+                "is-buffer": "^1.1.5"
               }
             }
           }
@@ -1623,8 +1623,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "once": "1.4.0",
-            "wrappy": "1.0.2"
+            "once": "^1.3.0",
+            "wrappy": "1"
           }
         },
         "inherits": {
@@ -1637,7 +1637,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "loose-envify": "1.3.1"
+            "loose-envify": "^1.0.0"
           }
         },
         "invert-kv": {
@@ -1650,7 +1650,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "kind-of": "3.2.2"
+            "kind-of": "^3.0.2"
           }
         },
         "is-arrayish": {
@@ -1668,7 +1668,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "builtin-modules": "1.1.1"
+            "builtin-modules": "^1.0.0"
           }
         },
         "is-data-descriptor": {
@@ -1676,7 +1676,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "kind-of": "3.2.2"
+            "kind-of": "^3.0.2"
           }
         },
         "is-descriptor": {
@@ -1684,9 +1684,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-accessor-descriptor": "0.1.6",
-            "is-data-descriptor": "0.1.4",
-            "kind-of": "5.1.0"
+            "is-accessor-descriptor": "^0.1.6",
+            "is-data-descriptor": "^0.1.4",
+            "kind-of": "^5.0.0"
           },
           "dependencies": {
             "kind-of": {
@@ -1706,7 +1706,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "number-is-nan": "1.0.1"
+            "number-is-nan": "^1.0.0"
           }
         },
         "is-fullwidth-code-point": {
@@ -1719,7 +1719,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "kind-of": "3.2.2"
+            "kind-of": "^3.0.2"
           }
         },
         "is-odd": {
@@ -1727,7 +1727,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-number": "4.0.0"
+            "is-number": "^4.0.0"
           },
           "dependencies": {
             "is-number": {
@@ -1742,7 +1742,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "isobject": "3.0.1"
+            "isobject": "^3.0.1"
           },
           "dependencies": {
             "isobject": {
@@ -1792,7 +1792,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "append-transform": "0.4.0"
+            "append-transform": "^0.4.0"
           }
         },
         "istanbul-lib-instrument": {
@@ -1800,13 +1800,13 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "babel-generator": "6.26.1",
-            "babel-template": "6.26.0",
-            "babel-traverse": "6.26.0",
-            "babel-types": "6.26.0",
-            "babylon": "6.18.0",
-            "istanbul-lib-coverage": "1.2.0",
-            "semver": "5.5.0"
+            "babel-generator": "^6.18.0",
+            "babel-template": "^6.16.0",
+            "babel-traverse": "^6.18.0",
+            "babel-types": "^6.18.0",
+            "babylon": "^6.18.0",
+            "istanbul-lib-coverage": "^1.2.0",
+            "semver": "^5.3.0"
           }
         },
         "istanbul-lib-report": {
@@ -1814,10 +1814,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "istanbul-lib-coverage": "1.2.0",
-            "mkdirp": "0.5.1",
-            "path-parse": "1.0.5",
-            "supports-color": "3.2.3"
+            "istanbul-lib-coverage": "^1.1.2",
+            "mkdirp": "^0.5.1",
+            "path-parse": "^1.0.5",
+            "supports-color": "^3.1.2"
           },
           "dependencies": {
             "supports-color": {
@@ -1825,7 +1825,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "has-flag": "1.0.0"
+                "has-flag": "^1.0.0"
               }
             }
           }
@@ -1835,11 +1835,11 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "debug": "3.1.0",
-            "istanbul-lib-coverage": "1.2.0",
-            "mkdirp": "0.5.1",
-            "rimraf": "2.6.2",
-            "source-map": "0.5.7"
+            "debug": "^3.1.0",
+            "istanbul-lib-coverage": "^1.1.2",
+            "mkdirp": "^0.5.1",
+            "rimraf": "^2.6.1",
+            "source-map": "^0.5.3"
           },
           "dependencies": {
             "debug": {
@@ -1857,7 +1857,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "handlebars": "4.0.11"
+            "handlebars": "^4.0.3"
           }
         },
         "js-tokens": {
@@ -1875,7 +1875,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-buffer": "1.1.6"
+            "is-buffer": "^1.1.5"
           }
         },
         "lazy-cache": {
@@ -1889,7 +1889,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "invert-kv": "1.0.0"
+            "invert-kv": "^1.0.0"
           }
         },
         "load-json-file": {
@@ -1897,11 +1897,11 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "graceful-fs": "4.1.11",
-            "parse-json": "2.2.0",
-            "pify": "2.3.0",
-            "pinkie-promise": "2.0.1",
-            "strip-bom": "2.0.0"
+            "graceful-fs": "^4.1.2",
+            "parse-json": "^2.2.0",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0",
+            "strip-bom": "^2.0.0"
           }
         },
         "locate-path": {
@@ -1909,8 +1909,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "p-locate": "2.0.0",
-            "path-exists": "3.0.0"
+            "p-locate": "^2.0.0",
+            "path-exists": "^3.0.0"
           },
           "dependencies": {
             "path-exists": {
@@ -1935,7 +1935,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "js-tokens": "3.0.2"
+            "js-tokens": "^3.0.0"
           }
         },
         "lru-cache": {
@@ -1943,8 +1943,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "pseudomap": "1.0.2",
-            "yallist": "2.1.2"
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
           }
         },
         "map-cache": {
@@ -1957,7 +1957,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "object-visit": "1.0.1"
+            "object-visit": "^1.0.0"
           }
         },
         "md5-hex": {
@@ -1965,7 +1965,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "md5-o-matic": "0.1.1"
+            "md5-o-matic": "^0.1.1"
           }
         },
         "md5-o-matic": {
@@ -1978,7 +1978,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "mimic-fn": "1.2.0"
+            "mimic-fn": "^1.0.0"
           }
         },
         "merge-source-map": {
@@ -1986,7 +1986,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "source-map": "0.6.1"
+            "source-map": "^0.6.1"
           },
           "dependencies": {
             "source-map": {
@@ -2001,19 +2001,19 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "arr-diff": "4.0.0",
-            "array-unique": "0.3.2",
-            "braces": "2.3.2",
-            "define-property": "2.0.2",
-            "extend-shallow": "3.0.2",
-            "extglob": "2.0.4",
-            "fragment-cache": "0.2.1",
-            "kind-of": "6.0.2",
-            "nanomatch": "1.2.9",
-            "object.pick": "1.3.0",
-            "regex-not": "1.0.2",
-            "snapdragon": "0.8.2",
-            "to-regex": "3.0.2"
+            "arr-diff": "^4.0.0",
+            "array-unique": "^0.3.2",
+            "braces": "^2.3.1",
+            "define-property": "^2.0.2",
+            "extend-shallow": "^3.0.2",
+            "extglob": "^2.0.4",
+            "fragment-cache": "^0.2.1",
+            "kind-of": "^6.0.2",
+            "nanomatch": "^1.2.9",
+            "object.pick": "^1.3.0",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.2"
           },
           "dependencies": {
             "kind-of": {
@@ -2033,7 +2033,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "brace-expansion": "1.1.11"
+            "brace-expansion": "^1.1.7"
           }
         },
         "minimist": {
@@ -2046,8 +2046,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "for-in": "1.0.2",
-            "is-extendable": "1.0.1"
+            "for-in": "^1.0.2",
+            "is-extendable": "^1.0.1"
           },
           "dependencies": {
             "is-extendable": {
@@ -2055,7 +2055,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-plain-object": "2.0.4"
+                "is-plain-object": "^2.0.4"
               }
             }
           }
@@ -2078,18 +2078,18 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "arr-diff": "4.0.0",
-            "array-unique": "0.3.2",
-            "define-property": "2.0.2",
-            "extend-shallow": "3.0.2",
-            "fragment-cache": "0.2.1",
-            "is-odd": "2.0.0",
-            "is-windows": "1.0.2",
-            "kind-of": "6.0.2",
-            "object.pick": "1.3.0",
-            "regex-not": "1.0.2",
-            "snapdragon": "0.8.2",
-            "to-regex": "3.0.2"
+            "arr-diff": "^4.0.0",
+            "array-unique": "^0.3.2",
+            "define-property": "^2.0.2",
+            "extend-shallow": "^3.0.2",
+            "fragment-cache": "^0.2.1",
+            "is-odd": "^2.0.0",
+            "is-windows": "^1.0.2",
+            "kind-of": "^6.0.2",
+            "object.pick": "^1.3.0",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.1"
           },
           "dependencies": {
             "arr-diff": {
@@ -2114,10 +2114,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "hosted-git-info": "2.6.0",
-            "is-builtin-module": "1.0.0",
-            "semver": "5.5.0",
-            "validate-npm-package-license": "3.0.3"
+            "hosted-git-info": "^2.1.4",
+            "is-builtin-module": "^1.0.0",
+            "semver": "2 || 3 || 4 || 5",
+            "validate-npm-package-license": "^3.0.1"
           }
         },
         "npm-run-path": {
@@ -2125,7 +2125,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "path-key": "2.0.1"
+            "path-key": "^2.0.0"
           }
         },
         "number-is-nan": {
@@ -2143,9 +2143,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "copy-descriptor": "0.1.1",
-            "define-property": "0.2.5",
-            "kind-of": "3.2.2"
+            "copy-descriptor": "^0.1.0",
+            "define-property": "^0.2.5",
+            "kind-of": "^3.0.3"
           },
           "dependencies": {
             "define-property": {
@@ -2153,7 +2153,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-descriptor": "0.1.6"
+                "is-descriptor": "^0.1.0"
               }
             }
           }
@@ -2163,7 +2163,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "isobject": "3.0.1"
+            "isobject": "^3.0.0"
           },
           "dependencies": {
             "isobject": {
@@ -2178,7 +2178,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "isobject": "3.0.1"
+            "isobject": "^3.0.1"
           },
           "dependencies": {
             "isobject": {
@@ -2193,7 +2193,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "wrappy": "1.0.2"
+            "wrappy": "1"
           }
         },
         "optimist": {
@@ -2201,8 +2201,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "minimist": "0.0.8",
-            "wordwrap": "0.0.3"
+            "minimist": "~0.0.1",
+            "wordwrap": "~0.0.2"
           }
         },
         "os-homedir": {
@@ -2215,9 +2215,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "execa": "0.7.0",
-            "lcid": "1.0.0",
-            "mem": "1.1.0"
+            "execa": "^0.7.0",
+            "lcid": "^1.0.0",
+            "mem": "^1.1.0"
           }
         },
         "p-finally": {
@@ -2230,7 +2230,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "p-try": "1.0.0"
+            "p-try": "^1.0.0"
           }
         },
         "p-locate": {
@@ -2238,7 +2238,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "p-limit": "1.2.0"
+            "p-limit": "^1.1.0"
           }
         },
         "p-try": {
@@ -2251,7 +2251,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "error-ex": "1.3.1"
+            "error-ex": "^1.2.0"
           }
         },
         "pascalcase": {
@@ -2264,7 +2264,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "pinkie-promise": "2.0.1"
+            "pinkie-promise": "^2.0.0"
           }
         },
         "path-is-absolute": {
@@ -2287,9 +2287,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "graceful-fs": "4.1.11",
-            "pify": "2.3.0",
-            "pinkie-promise": "2.0.1"
+            "graceful-fs": "^4.1.2",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
           }
         },
         "pify": {
@@ -2307,7 +2307,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "pinkie": "2.0.4"
+            "pinkie": "^2.0.0"
           }
         },
         "pkg-dir": {
@@ -2315,7 +2315,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "find-up": "1.1.2"
+            "find-up": "^1.0.0"
           },
           "dependencies": {
             "find-up": {
@@ -2323,8 +2323,8 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "path-exists": "2.1.0",
-                "pinkie-promise": "2.0.1"
+                "path-exists": "^2.0.0",
+                "pinkie-promise": "^2.0.0"
               }
             }
           }
@@ -2344,9 +2344,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "load-json-file": "1.1.0",
-            "normalize-package-data": "2.4.0",
-            "path-type": "1.1.0"
+            "load-json-file": "^1.0.0",
+            "normalize-package-data": "^2.3.2",
+            "path-type": "^1.0.0"
           }
         },
         "read-pkg-up": {
@@ -2354,8 +2354,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "find-up": "1.1.2",
-            "read-pkg": "1.1.0"
+            "find-up": "^1.0.0",
+            "read-pkg": "^1.0.0"
           },
           "dependencies": {
             "find-up": {
@@ -2363,8 +2363,8 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "path-exists": "2.1.0",
-                "pinkie-promise": "2.0.1"
+                "path-exists": "^2.0.0",
+                "pinkie-promise": "^2.0.0"
               }
             }
           }
@@ -2379,8 +2379,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "extend-shallow": "3.0.2",
-            "safe-regex": "1.1.0"
+            "extend-shallow": "^3.0.2",
+            "safe-regex": "^1.1.0"
           }
         },
         "repeat-element": {
@@ -2398,7 +2398,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-finite": "1.0.2"
+            "is-finite": "^1.0.0"
           }
         },
         "require-directory": {
@@ -2432,7 +2432,7 @@
           "dev": true,
           "optional": true,
           "requires": {
-            "align-text": "0.1.4"
+            "align-text": "^0.1.1"
           }
         },
         "rimraf": {
@@ -2440,7 +2440,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "glob": "7.1.2"
+            "glob": "^7.0.5"
           }
         },
         "safe-regex": {
@@ -2448,7 +2448,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "ret": "0.1.15"
+            "ret": "~0.1.10"
           }
         },
         "semver": {
@@ -2466,10 +2466,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "extend-shallow": "2.0.1",
-            "is-extendable": "0.1.1",
-            "is-plain-object": "2.0.4",
-            "split-string": "3.1.0"
+            "extend-shallow": "^2.0.1",
+            "is-extendable": "^0.1.1",
+            "is-plain-object": "^2.0.3",
+            "split-string": "^3.0.1"
           },
           "dependencies": {
             "extend-shallow": {
@@ -2477,7 +2477,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-extendable": "0.1.1"
+                "is-extendable": "^0.1.0"
               }
             }
           }
@@ -2487,7 +2487,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "shebang-regex": "1.0.0"
+            "shebang-regex": "^1.0.0"
           }
         },
         "shebang-regex": {
@@ -2510,14 +2510,14 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "base": "0.11.2",
-            "debug": "2.6.9",
-            "define-property": "0.2.5",
-            "extend-shallow": "2.0.1",
-            "map-cache": "0.2.2",
-            "source-map": "0.5.7",
-            "source-map-resolve": "0.5.1",
-            "use": "3.1.0"
+            "base": "^0.11.1",
+            "debug": "^2.2.0",
+            "define-property": "^0.2.5",
+            "extend-shallow": "^2.0.1",
+            "map-cache": "^0.2.2",
+            "source-map": "^0.5.6",
+            "source-map-resolve": "^0.5.0",
+            "use": "^3.1.0"
           },
           "dependencies": {
             "define-property": {
@@ -2525,7 +2525,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-descriptor": "0.1.6"
+                "is-descriptor": "^0.1.0"
               }
             },
             "extend-shallow": {
@@ -2533,7 +2533,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-extendable": "0.1.1"
+                "is-extendable": "^0.1.0"
               }
             }
           }
@@ -2543,9 +2543,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "define-property": "1.0.0",
-            "isobject": "3.0.1",
-            "snapdragon-util": "3.0.1"
+            "define-property": "^1.0.0",
+            "isobject": "^3.0.0",
+            "snapdragon-util": "^3.0.1"
           },
           "dependencies": {
             "define-property": {
@@ -2553,7 +2553,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-descriptor": "1.0.2"
+                "is-descriptor": "^1.0.0"
               }
             },
             "is-accessor-descriptor": {
@@ -2561,7 +2561,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-data-descriptor": {
@@ -2569,7 +2569,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-descriptor": {
@@ -2577,9 +2577,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-accessor-descriptor": "1.0.0",
-                "is-data-descriptor": "1.0.0",
-                "kind-of": "6.0.2"
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
               }
             },
             "isobject": {
@@ -2599,7 +2599,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "kind-of": "3.2.2"
+            "kind-of": "^3.2.0"
           }
         },
         "source-map": {
@@ -2612,11 +2612,11 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "atob": "2.1.1",
-            "decode-uri-component": "0.2.0",
-            "resolve-url": "0.2.1",
-            "source-map-url": "0.4.0",
-            "urix": "0.1.0"
+            "atob": "^2.0.0",
+            "decode-uri-component": "^0.2.0",
+            "resolve-url": "^0.2.1",
+            "source-map-url": "^0.4.0",
+            "urix": "^0.1.0"
           }
         },
         "source-map-url": {
@@ -2629,12 +2629,12 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "foreground-child": "1.5.6",
-            "mkdirp": "0.5.1",
-            "os-homedir": "1.0.2",
-            "rimraf": "2.6.2",
-            "signal-exit": "3.0.2",
-            "which": "1.3.0"
+            "foreground-child": "^1.5.6",
+            "mkdirp": "^0.5.0",
+            "os-homedir": "^1.0.1",
+            "rimraf": "^2.6.2",
+            "signal-exit": "^3.0.2",
+            "which": "^1.3.0"
           }
         },
         "spdx-correct": {
@@ -2642,8 +2642,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "spdx-expression-parse": "3.0.0",
-            "spdx-license-ids": "3.0.0"
+            "spdx-expression-parse": "^3.0.0",
+            "spdx-license-ids": "^3.0.0"
           }
         },
         "spdx-exceptions": {
@@ -2656,8 +2656,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "spdx-exceptions": "2.1.0",
-            "spdx-license-ids": "3.0.0"
+            "spdx-exceptions": "^2.1.0",
+            "spdx-license-ids": "^3.0.0"
           }
         },
         "spdx-license-ids": {
@@ -2670,7 +2670,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "extend-shallow": "3.0.2"
+            "extend-shallow": "^3.0.0"
           }
         },
         "static-extend": {
@@ -2678,8 +2678,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "define-property": "0.2.5",
-            "object-copy": "0.1.0"
+            "define-property": "^0.2.5",
+            "object-copy": "^0.1.0"
           },
           "dependencies": {
             "define-property": {
@@ -2687,7 +2687,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-descriptor": "0.1.6"
+                "is-descriptor": "^0.1.0"
               }
             }
           }
@@ -2697,8 +2697,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-fullwidth-code-point": "2.0.0",
-            "strip-ansi": "4.0.0"
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
           },
           "dependencies": {
             "ansi-regex": {
@@ -2711,7 +2711,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "ansi-regex": "3.0.0"
+                "ansi-regex": "^3.0.0"
               }
             }
           }
@@ -2721,7 +2721,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "ansi-regex": "2.1.1"
+            "ansi-regex": "^2.0.0"
           }
         },
         "strip-bom": {
@@ -2729,7 +2729,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-utf8": "0.2.1"
+            "is-utf8": "^0.2.0"
           }
         },
         "strip-eof": {
@@ -2747,11 +2747,11 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "arrify": "1.0.1",
-            "micromatch": "3.1.10",
-            "object-assign": "4.1.1",
-            "read-pkg-up": "1.0.1",
-            "require-main-filename": "1.0.1"
+            "arrify": "^1.0.1",
+            "micromatch": "^3.1.8",
+            "object-assign": "^4.1.0",
+            "read-pkg-up": "^1.0.1",
+            "require-main-filename": "^1.0.1"
           },
           "dependencies": {
             "arr-diff": {
@@ -2769,16 +2769,16 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "arr-flatten": "1.1.0",
-                "array-unique": "0.3.2",
-                "extend-shallow": "2.0.1",
-                "fill-range": "4.0.0",
-                "isobject": "3.0.1",
-                "repeat-element": "1.1.2",
-                "snapdragon": "0.8.2",
-                "snapdragon-node": "2.1.1",
-                "split-string": "3.1.0",
-                "to-regex": "3.0.2"
+                "arr-flatten": "^1.1.0",
+                "array-unique": "^0.3.2",
+                "extend-shallow": "^2.0.1",
+                "fill-range": "^4.0.0",
+                "isobject": "^3.0.1",
+                "repeat-element": "^1.1.2",
+                "snapdragon": "^0.8.1",
+                "snapdragon-node": "^2.0.1",
+                "split-string": "^3.0.2",
+                "to-regex": "^3.0.1"
               },
               "dependencies": {
                 "extend-shallow": {
@@ -2786,7 +2786,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-extendable": "0.1.1"
+                    "is-extendable": "^0.1.0"
                   }
                 }
               }
@@ -2796,13 +2796,13 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "debug": "2.6.9",
-                "define-property": "0.2.5",
-                "extend-shallow": "2.0.1",
-                "posix-character-classes": "0.1.1",
-                "regex-not": "1.0.2",
-                "snapdragon": "0.8.2",
-                "to-regex": "3.0.2"
+                "debug": "^2.3.3",
+                "define-property": "^0.2.5",
+                "extend-shallow": "^2.0.1",
+                "posix-character-classes": "^0.1.0",
+                "regex-not": "^1.0.0",
+                "snapdragon": "^0.8.1",
+                "to-regex": "^3.0.1"
               },
               "dependencies": {
                 "define-property": {
@@ -2810,7 +2810,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-descriptor": "0.1.6"
+                    "is-descriptor": "^0.1.0"
                   }
                 },
                 "extend-shallow": {
@@ -2818,7 +2818,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-extendable": "0.1.1"
+                    "is-extendable": "^0.1.0"
                   }
                 },
                 "is-accessor-descriptor": {
@@ -2826,7 +2826,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "kind-of": "3.2.2"
+                    "kind-of": "^3.0.2"
                   },
                   "dependencies": {
                     "kind-of": {
@@ -2834,7 +2834,7 @@
                       "bundled": true,
                       "dev": true,
                       "requires": {
-                        "is-buffer": "1.1.6"
+                        "is-buffer": "^1.1.5"
                       }
                     }
                   }
@@ -2844,7 +2844,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "kind-of": "3.2.2"
+                    "kind-of": "^3.0.2"
                   },
                   "dependencies": {
                     "kind-of": {
@@ -2852,7 +2852,7 @@
                       "bundled": true,
                       "dev": true,
                       "requires": {
-                        "is-buffer": "1.1.6"
+                        "is-buffer": "^1.1.5"
                       }
                     }
                   }
@@ -2862,9 +2862,9 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-accessor-descriptor": "0.1.6",
-                    "is-data-descriptor": "0.1.4",
-                    "kind-of": "5.1.0"
+                    "is-accessor-descriptor": "^0.1.6",
+                    "is-data-descriptor": "^0.1.4",
+                    "kind-of": "^5.0.0"
                   }
                 },
                 "kind-of": {
@@ -2879,14 +2879,14 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "array-unique": "0.3.2",
-                "define-property": "1.0.0",
-                "expand-brackets": "2.1.4",
-                "extend-shallow": "2.0.1",
-                "fragment-cache": "0.2.1",
-                "regex-not": "1.0.2",
-                "snapdragon": "0.8.2",
-                "to-regex": "3.0.2"
+                "array-unique": "^0.3.2",
+                "define-property": "^1.0.0",
+                "expand-brackets": "^2.1.4",
+                "extend-shallow": "^2.0.1",
+                "fragment-cache": "^0.2.1",
+                "regex-not": "^1.0.0",
+                "snapdragon": "^0.8.1",
+                "to-regex": "^3.0.1"
               },
               "dependencies": {
                 "define-property": {
@@ -2894,7 +2894,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-descriptor": "1.0.2"
+                    "is-descriptor": "^1.0.0"
                   }
                 },
                 "extend-shallow": {
@@ -2902,7 +2902,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-extendable": "0.1.1"
+                    "is-extendable": "^0.1.0"
                   }
                 }
               }
@@ -2912,10 +2912,10 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "extend-shallow": "2.0.1",
-                "is-number": "3.0.0",
-                "repeat-string": "1.6.1",
-                "to-regex-range": "2.1.1"
+                "extend-shallow": "^2.0.1",
+                "is-number": "^3.0.0",
+                "repeat-string": "^1.6.1",
+                "to-regex-range": "^2.1.0"
               },
               "dependencies": {
                 "extend-shallow": {
@@ -2923,7 +2923,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-extendable": "0.1.1"
+                    "is-extendable": "^0.1.0"
                   }
                 }
               }
@@ -2933,7 +2933,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-data-descriptor": {
@@ -2941,7 +2941,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "6.0.2"
+                "kind-of": "^6.0.0"
               }
             },
             "is-descriptor": {
@@ -2949,9 +2949,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-accessor-descriptor": "1.0.0",
-                "is-data-descriptor": "1.0.0",
-                "kind-of": "6.0.2"
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
               }
             },
             "is-number": {
@@ -2959,7 +2959,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "3.2.2"
+                "kind-of": "^3.0.2"
               },
               "dependencies": {
                 "kind-of": {
@@ -2967,7 +2967,7 @@
                   "bundled": true,
                   "dev": true,
                   "requires": {
-                    "is-buffer": "1.1.6"
+                    "is-buffer": "^1.1.5"
                   }
                 }
               }
@@ -2987,19 +2987,19 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "arr-diff": "4.0.0",
-                "array-unique": "0.3.2",
-                "braces": "2.3.2",
-                "define-property": "2.0.2",
-                "extend-shallow": "3.0.2",
-                "extglob": "2.0.4",
-                "fragment-cache": "0.2.1",
-                "kind-of": "6.0.2",
-                "nanomatch": "1.2.9",
-                "object.pick": "1.3.0",
-                "regex-not": "1.0.2",
-                "snapdragon": "0.8.2",
-                "to-regex": "3.0.2"
+                "arr-diff": "^4.0.0",
+                "array-unique": "^0.3.2",
+                "braces": "^2.3.1",
+                "define-property": "^2.0.2",
+                "extend-shallow": "^3.0.2",
+                "extglob": "^2.0.4",
+                "fragment-cache": "^0.2.1",
+                "kind-of": "^6.0.2",
+                "nanomatch": "^1.2.9",
+                "object.pick": "^1.3.0",
+                "regex-not": "^1.0.0",
+                "snapdragon": "^0.8.1",
+                "to-regex": "^3.0.2"
               }
             }
           }
@@ -3014,7 +3014,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "kind-of": "3.2.2"
+            "kind-of": "^3.0.2"
           }
         },
         "to-regex": {
@@ -3022,10 +3022,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "define-property": "2.0.2",
-            "extend-shallow": "3.0.2",
-            "regex-not": "1.0.2",
-            "safe-regex": "1.1.0"
+            "define-property": "^2.0.2",
+            "extend-shallow": "^3.0.2",
+            "regex-not": "^1.0.2",
+            "safe-regex": "^1.1.0"
           }
         },
         "to-regex-range": {
@@ -3033,8 +3033,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "is-number": "3.0.0",
-            "repeat-string": "1.6.1"
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1"
           },
           "dependencies": {
             "is-number": {
@@ -3042,7 +3042,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "kind-of": "3.2.2"
+                "kind-of": "^3.0.2"
               }
             }
           }
@@ -3058,9 +3058,9 @@
           "dev": true,
           "optional": true,
           "requires": {
-            "source-map": "0.5.7",
-            "uglify-to-browserify": "1.0.2",
-            "yargs": "3.10.0"
+            "source-map": "~0.5.1",
+            "uglify-to-browserify": "~1.0.0",
+            "yargs": "~3.10.0"
           },
           "dependencies": {
             "yargs": {
@@ -3069,9 +3069,9 @@
               "dev": true,
               "optional": true,
               "requires": {
-                "camelcase": "1.2.1",
-                "cliui": "2.1.0",
-                "decamelize": "1.2.0",
+                "camelcase": "^1.0.2",
+                "cliui": "^2.1.0",
+                "decamelize": "^1.0.0",
                 "window-size": "0.1.0"
               }
             }
@@ -3088,10 +3088,10 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "arr-union": "3.1.0",
-            "get-value": "2.0.6",
-            "is-extendable": "0.1.1",
-            "set-value": "0.4.3"
+            "arr-union": "^3.1.0",
+            "get-value": "^2.0.6",
+            "is-extendable": "^0.1.1",
+            "set-value": "^0.4.3"
           },
           "dependencies": {
             "extend-shallow": {
@@ -3099,7 +3099,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "is-extendable": "0.1.1"
+                "is-extendable": "^0.1.0"
               }
             },
             "set-value": {
@@ -3107,10 +3107,10 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "extend-shallow": "2.0.1",
-                "is-extendable": "0.1.1",
-                "is-plain-object": "2.0.4",
-                "to-object-path": "0.3.0"
+                "extend-shallow": "^2.0.1",
+                "is-extendable": "^0.1.1",
+                "is-plain-object": "^2.0.1",
+                "to-object-path": "^0.3.0"
               }
             }
           }
@@ -3120,8 +3120,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "has-value": "0.3.1",
-            "isobject": "3.0.1"
+            "has-value": "^0.3.1",
+            "isobject": "^3.0.0"
           },
           "dependencies": {
             "has-value": {
@@ -3129,9 +3129,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "get-value": "2.0.6",
-                "has-values": "0.1.4",
-                "isobject": "2.1.0"
+                "get-value": "^2.0.3",
+                "has-values": "^0.1.4",
+                "isobject": "^2.0.0"
               },
               "dependencies": {
                 "isobject": {
@@ -3166,7 +3166,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "kind-of": "6.0.2"
+            "kind-of": "^6.0.2"
           },
           "dependencies": {
             "kind-of": {
@@ -3181,8 +3181,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "spdx-correct": "3.0.0",
-            "spdx-expression-parse": "3.0.0"
+            "spdx-correct": "^3.0.0",
+            "spdx-expression-parse": "^3.0.0"
           }
         },
         "which": {
@@ -3190,7 +3190,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "isexe": "2.0.0"
+            "isexe": "^2.0.0"
           }
         },
         "which-module": {
@@ -3214,8 +3214,8 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "string-width": "1.0.2",
-            "strip-ansi": "3.0.1"
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1"
           },
           "dependencies": {
             "is-fullwidth-code-point": {
@@ -3223,7 +3223,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "number-is-nan": "1.0.1"
+                "number-is-nan": "^1.0.0"
               }
             },
             "string-width": {
@@ -3231,9 +3231,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "code-point-at": "1.1.0",
-                "is-fullwidth-code-point": "1.0.0",
-                "strip-ansi": "3.0.1"
+                "code-point-at": "^1.0.0",
+                "is-fullwidth-code-point": "^1.0.0",
+                "strip-ansi": "^3.0.0"
               }
             }
           }
@@ -3248,9 +3248,9 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "graceful-fs": "4.1.11",
-            "imurmurhash": "0.1.4",
-            "slide": "1.1.6"
+            "graceful-fs": "^4.1.11",
+            "imurmurhash": "^0.1.4",
+            "slide": "^1.1.5"
           }
         },
         "y18n": {
@@ -3268,18 +3268,18 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "cliui": "4.1.0",
-            "decamelize": "1.2.0",
-            "find-up": "2.1.0",
-            "get-caller-file": "1.0.2",
-            "os-locale": "2.1.0",
-            "require-directory": "2.1.1",
-            "require-main-filename": "1.0.1",
-            "set-blocking": "2.0.0",
-            "string-width": "2.1.1",
-            "which-module": "2.0.0",
-            "y18n": "3.2.1",
-            "yargs-parser": "9.0.2"
+            "cliui": "^4.0.0",
+            "decamelize": "^1.1.1",
+            "find-up": "^2.1.0",
+            "get-caller-file": "^1.0.1",
+            "os-locale": "^2.0.0",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^1.0.1",
+            "set-blocking": "^2.0.0",
+            "string-width": "^2.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^3.2.1",
+            "yargs-parser": "^9.0.2"
           },
           "dependencies": {
             "ansi-regex": {
@@ -3297,9 +3297,9 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "string-width": "2.1.1",
-                "strip-ansi": "4.0.0",
-                "wrap-ansi": "2.1.0"
+                "string-width": "^2.1.1",
+                "strip-ansi": "^4.0.0",
+                "wrap-ansi": "^2.0.0"
               }
             },
             "strip-ansi": {
@@ -3307,7 +3307,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "ansi-regex": "3.0.0"
+                "ansi-regex": "^3.0.0"
               }
             },
             "yargs-parser": {
@@ -3315,7 +3315,7 @@
               "bundled": true,
               "dev": true,
               "requires": {
-                "camelcase": "4.1.0"
+                "camelcase": "^4.1.0"
               }
             }
           }
@@ -3325,7 +3325,7 @@
           "bundled": true,
           "dev": true,
           "requires": {
-            "camelcase": "4.1.0"
+            "camelcase": "^4.1.0"
           },
           "dependencies": {
             "camelcase": {
@@ -3349,7 +3349,7 @@
       "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
       "dev": true,
       "requires": {
-        "wrappy": "1.0.2"
+        "wrappy": "1"
       }
     },
     "onetime": {
@@ -3357,7 +3357,7 @@
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
       "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
       "requires": {
-        "mimic-fn": "1.2.0"
+        "mimic-fn": "^1.0.0"
       }
     },
     "ora": {
@@ -3365,10 +3365,10 @@
       "resolved": "https://registry.npmjs.org/ora/-/ora-1.4.0.tgz",
       "integrity": "sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw==",
       "requires": {
-        "chalk": "2.4.1",
-        "cli-cursor": "2.1.0",
-        "cli-spinners": "1.3.1",
-        "log-symbols": "2.2.0"
+        "chalk": "^2.1.0",
+        "cli-cursor": "^2.1.0",
+        "cli-spinners": "^1.0.1",
+        "log-symbols": "^2.1.0"
       }
     },
     "os-tmpdir": {
@@ -3421,28 +3421,28 @@
       "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==",
       "dev": true,
       "requires": {
-        "aws-sign2": "0.7.0",
-        "aws4": "1.7.0",
-        "caseless": "0.12.0",
-        "combined-stream": "1.0.6",
-        "extend": "3.0.1",
-        "forever-agent": "0.6.1",
-        "form-data": "2.3.2",
-        "har-validator": "5.0.3",
-        "hawk": "6.0.2",
-        "http-signature": "1.2.0",
-        "is-typedarray": "1.0.0",
-        "isstream": "0.1.2",
-        "json-stringify-safe": "5.0.1",
-        "mime-types": "2.1.18",
-        "oauth-sign": "0.8.2",
-        "performance-now": "2.1.0",
-        "qs": "6.5.2",
-        "safe-buffer": "5.1.2",
-        "stringstream": "0.0.5",
-        "tough-cookie": "2.3.4",
-        "tunnel-agent": "0.6.0",
-        "uuid": "3.3.2"
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.6.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.5",
+        "extend": "~3.0.1",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.1",
+        "har-validator": "~5.0.3",
+        "hawk": "~6.0.2",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.17",
+        "oauth-sign": "~0.8.2",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.1",
+        "safe-buffer": "^5.1.1",
+        "stringstream": "~0.0.5",
+        "tough-cookie": "~2.3.3",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.1.0"
       }
     },
     "restore-cursor": {
@@ -3450,8 +3450,8 @@
       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
       "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
       "requires": {
-        "onetime": "2.0.1",
-        "signal-exit": "3.0.2"
+        "onetime": "^2.0.0",
+        "signal-exit": "^3.0.2"
       }
     },
     "safe-buffer": {
@@ -3477,13 +3477,13 @@
       "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==",
       "dev": true,
       "requires": {
-        "@sinonjs/formatio": "2.0.0",
-        "diff": "3.2.0",
-        "lodash.get": "4.4.2",
-        "lolex": "2.4.1",
-        "nise": "1.3.3",
-        "supports-color": "5.4.0",
-        "type-detect": "4.0.8"
+        "@sinonjs/formatio": "^2.0.0",
+        "diff": "^3.1.0",
+        "lodash.get": "^4.4.2",
+        "lolex": "^2.2.0",
+        "nise": "^1.2.0",
+        "supports-color": "^5.1.0",
+        "type-detect": "^4.0.5"
       }
     },
     "sntp": {
@@ -3492,7 +3492,7 @@
       "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
       "dev": true,
       "requires": {
-        "hoek": "4.2.1"
+        "hoek": "4.x.x"
       }
     },
     "sprintf-js": {
@@ -3506,20 +3506,20 @@
       "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
       "dev": true,
       "requires": {
-        "asn1": "0.2.3",
-        "assert-plus": "1.0.0",
-        "bcrypt-pbkdf": "1.0.1",
-        "dashdash": "1.14.1",
-        "ecc-jsbn": "0.1.1",
-        "getpass": "0.1.7",
-        "jsbn": "0.1.1",
-        "tweetnacl": "0.14.5"
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "tweetnacl": "~0.14.0"
       }
     },
     "stringstream": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
-      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",
+      "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==",
       "dev": true
     },
     "supports-color": {
@@ -3527,7 +3527,7 @@
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
       "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
       "requires": {
-        "has-flag": "3.0.0"
+        "has-flag": "^3.0.0"
       }
     },
     "text-encoding": {
@@ -3542,7 +3542,7 @@
       "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
       "dev": true,
       "requires": {
-        "os-tmpdir": "1.0.2"
+        "os-tmpdir": "~1.0.2"
       }
     },
     "tmp-promise": {
@@ -3551,7 +3551,7 @@
       "integrity": "sha512-hOabTz9Tp49wCozFwuJe5ISrOqkECm6kzw66XTP23DuzNU7QS/KiZq5LC9Y7QSy8f1rPSLy4bKaViP0OwGI1cA==",
       "dev": true,
       "requires": {
-        "bluebird": "3.5.1",
+        "bluebird": "^3.5.0",
         "tmp": "0.0.33"
       }
     },
@@ -3561,7 +3561,7 @@
       "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
       "dev": true,
       "requires": {
-        "punycode": "1.4.1"
+        "punycode": "^1.4.1"
       }
     },
     "tunnel-agent": {
@@ -3570,7 +3570,7 @@
       "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
       "dev": true,
       "requires": {
-        "safe-buffer": "5.1.2"
+        "safe-buffer": "^5.0.1"
       }
     },
     "tweetnacl": {
@@ -3602,9 +3602,9 @@
       "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
       "dev": true,
       "requires": {
-        "assert-plus": "1.0.0",
+        "assert-plus": "^1.0.0",
         "core-util-is": "1.0.2",
-        "extsprintf": "1.3.0"
+        "extsprintf": "^1.2.0"
       }
     },
     "wrappy": {
diff --git a/package.json b/package.json
index 45c1f2e..947342a 100644
--- a/package.json
+++ b/package.json
@@ -1,10 +1,10 @@
 {
   "name": "unity-cache-server",
-  "version": "6.1.1",
+  "version": "6.1.2-beta.0",
   "description": "Unity Cache Server",
   "main": "lib/index.js",
   "engines": {
-    "node": "^8.11.3"
+    "node": "^8.12.0"
   },
   "directories": {
     "test": "test"

From a74aece688909100e1c0753ace86fd5b2debff3b Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Mon, 17 Sep 2018 15:20:03 -0500
Subject: [PATCH 08/14] Bumping beta version number

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 947342a..b9ac9ef 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "unity-cache-server",
-  "version": "6.1.2-beta.0",
+  "version": "6.1.2-beta.1",
   "description": "Unity Cache Server",
   "main": "lib/index.js",
   "engines": {

From 3823fd97c0cce985fc2a6776d223243ba38c5e56 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Mon, 17 Sep 2018 15:57:42 -0500
Subject: [PATCH 09/14] Fixed unhandled promise rejections and stalls in the
 test suite. The former was caused by lokiJS persistence adapter trying to
 write to temp locations that no longer exist (disabled autosave to fix), and
 the latter was caused by test servers stalling waiting for clients to end
 their connections.

---
 lib/server/transaction_mirror.js |  4 ++--
 package-lock.json                |  2 +-
 test/cache_api.js                | 16 +++++++++-------
 test/cache_base.js               |  6 +++---
 test/cache_fs.js                 |  2 ++
 test/cache_ram.js                |  6 ++++--
 test/command_processor.js        |  2 ++
 test/protocol.js                 | 28 +++++++++++++++++-----------
 test/reliability_manager.js      |  2 ++
 test/server.js                   | 12 ++++++------
 test/test_init.js                |  7 +++++++
 test/transaction_mirror.js       | 12 +++++++++++-
 12 files changed, 66 insertions(+), 33 deletions(-)
 create mode 100644 test/test_init.js

diff --git a/lib/server/transaction_mirror.js b/lib/server/transaction_mirror.js
index 4f3ab58..33e2038 100644
--- a/lib/server/transaction_mirror.js
+++ b/lib/server/transaction_mirror.js
@@ -21,11 +21,11 @@ class TransactionMirror {
         this._cache = cache;
         this._queue = [];
         this._processing = false;
-        this._queueProcessDelay = TransactionMirror.options.queueProcessDelay || PROCESS_DELAY_MS;
+        this._queueProcessDelay = connectOptions.queueProcessDelay || TransactionMirror.options.queueProcessDelay || PROCESS_DELAY_MS;
 
         const host = connectOptions.host;
         const port = connectOptions.port;
-        const idleTimeout = TransactionMirror.options.idleTimeout || CONNECT_IDLE_TIMEOUT_MS;
+        const idleTimeout = connectOptions.idleTimeout || TransactionMirror.options.idleTimeout || CONNECT_IDLE_TIMEOUT_MS;
         this._client = new Client(host, port, {idleTimeout: idleTimeout});
         helpers.log(consts.LOG_INFO, `[TransactionMirror] Mirroring transactions to ${host}:${port}`);
     }
diff --git a/package-lock.json b/package-lock.json
index 840a102..89ed39d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "unity-cache-server",
-  "version": "6.1.2-beta.0",
+  "version": "6.1.2-beta.1",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/test/cache_api.js b/test/cache_api.js
index 0df6904..c37f1c0 100644
--- a/test/cache_api.js
+++ b/test/cache_api.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const assert = require('assert');
 const tmp = require('tmp-promise');
 const loki = require('lokijs');
@@ -18,6 +20,7 @@ const test_modules = [
             pageSize: 1024 * 1024,
             minFreeBlockSize: 1024,
             persistenceOptions: {
+                autosave: false,
                 adapter: new loki.LokiMemoryAdapter()
             },
             highReliability: false
@@ -28,7 +31,10 @@ const test_modules = [
         path: "../lib/cache/cache_fs",
         options: {
             cachePath: tmp.tmpNameSync({}),
-            highReliability: false
+            highReliability: false,
+            persistenceOptions: {
+                autosave: false
+            }
         }
     }
 ];
@@ -44,9 +50,7 @@ describe("Cache API", () => {
                 cache = new CacheModule();
             });
 
-            after(() => {
-                return fs.remove(module.options.cachePath);
-            });
+            after(() => fs.remove(module.options.cachePath));
 
             describe("static get properties", () => {
                 it("should return an object with common property values", () => {
@@ -340,9 +344,7 @@ describe("PutTransaction API", () => {
                 fileData = generateCommandData(1024, 1024);
             });
 
-            after(() => {
-                return fs.remove(module.options.cachePath);
-            });
+            after(() => fs.remove(module.options.cachePath));
 
             beforeEach( async () => {
                 trx = await cache.createPutTransaction(fileData.guid, fileData.hash);
diff --git a/test/cache_base.js b/test/cache_base.js
index 7283525..d4944ec 100644
--- a/test/cache_base.js
+++ b/test/cache_base.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const tmp = require('tmp');
 const fs = require('fs-extra');
 const { CacheBase, PutTransaction } = require('../lib/cache/cache_base');
@@ -86,9 +88,7 @@ describe("Cache: Base Class", () => {
 
     describe("init", () => {
 
-        after(() => {
-            return fs.remove(opts.cachePath);
-        });
+        after(() => fs.remove(opts.cachePath));
 
         it("should create the cache working directory if it doesn't exist", () => {
             return cache.init(opts)
diff --git a/test/cache_fs.js b/test/cache_fs.js
index f996c62..ba33119 100644
--- a/test/cache_fs.js
+++ b/test/cache_fs.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const tmp = require('tmp');
 const fs = require('fs-extra');
 const Cache = require('../lib/cache/cache_fs');
diff --git a/test/cache_ram.js b/test/cache_ram.js
index 85948c6..6f5dde4 100644
--- a/test/cache_ram.js
+++ b/test/cache_ram.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const tmp = require('tmp');
 const fs = require('fs-extra');
 const Cache = require('../lib/cache/cache_ram');
@@ -140,9 +142,9 @@ describe("Cache: RAM", () => {
 
         });
 
-        afterEach(async () => {
+        afterEach(() => {
             cache._clearCache();
-            await fs.remove(opts.cachePath);
+            return fs.remove(opts.cachePath);
         });
 
         describe("_serialize", () => {
diff --git a/test/command_processor.js b/test/command_processor.js
index e45aead..411bcc3 100644
--- a/test/command_processor.js
+++ b/test/command_processor.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const assert = require('assert');
 const sinon = require('sinon');
 const { CommandProcessor, CacheBase , PutTransaction } = require('../lib');
diff --git a/test/protocol.js b/test/protocol.js
index 1682c4f..439cda4 100644
--- a/test/protocol.js
+++ b/test/protocol.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const assert = require('assert');
 const crypto = require('crypto');
 const helpers = require('../lib/helpers');
@@ -37,6 +39,7 @@ const test_modules = [
                 reliabilityThreshold: 0
             },
             persistenceOptions: {
+                autosave: false,
                 adapter: new loki.LokiMemoryAdapter()
             }
         }
@@ -49,6 +52,9 @@ const test_modules = [
             highReliability: true,
             highReliabilityOptions: {
                 reliabilityThreshold: 0
+            },
+            persistenceOptions: {
+                autosave: false
             }
         }
     }
@@ -58,10 +64,6 @@ describe("Protocol", () => {
     test_modules.forEach(module => {
         describe(module.name, function() {
 
-            beforeEach(() => {
-                helpers.setLogger(() => {});
-            });
-
             before(async () => {
                 /** @type {CacheBase} **/
                 const CacheModule = require(module.path);
@@ -74,8 +76,8 @@ describe("Protocol", () => {
                 await server.start(err => assert(!err, `Cache Server reported error!  ${err}`));
             });
 
-            after(() => {
-                server.stop();
+            after(async () => {
+                await server.stop();
                 module.tmpDir.removeCallback();
             });
 
@@ -142,6 +144,8 @@ describe("Protocol", () => {
                     await clientWrite(client, helpers.encodeInt32(consts.PROTOCOL_VERSION));
                 });
 
+                afterEach(() => client.end());
+
                 it("should close the socket on an invalid PUT type", (done) => {
                     expectLog(client, /Unrecognized command/i, done);
                     const buf = Buffer.from(
@@ -185,7 +189,7 @@ describe("Protocol", () => {
                     });
                 });
 
-                it("should not allow replacing files for a version that already exists", () => {
+                it("should not allow replacing files for a version that already exists", async () => {
                     const newData = Buffer.from(crypto.randomBytes(self.data.bin.length).toString('ascii'), 'ascii');
 
                     const buf = Buffer.from(
@@ -193,10 +197,10 @@ describe("Protocol", () => {
                         encodeCommand(cmd.putAsset, null, null, newData) +
                         encodeCommand(cmd.transactionEnd), 'ascii');
 
-                    return clientWrite(client, buf)
-                        .then(() => cache.getFileStream(consts.FILE_TYPE.BIN, self.data.guid, self.data.hash))
-                        .then(stream => readStream(stream, self.data.bin.length))
-                        .then(buffer => assert.strictEqual(buffer.compare(self.data.bin), 0));
+                    await clientWrite(client, buf);
+                    const stream = await cache.getFileStream(consts.FILE_TYPE.BIN, self.data.guid, self.data.hash);
+                    const data = await readStream(stream, self.data.bin.length);
+                    assert.strictEqual(data.compare(self.data.bin), 0);
                 });
             });
 
@@ -228,6 +232,8 @@ describe("Protocol", () => {
                     await clientWrite(client, helpers.encodeInt32(consts.PROTOCOL_VERSION));
                 });
 
+                afterEach(() => client.end());
+
                 it("should close the socket on an invalid GET type", (done) => {
                     expectLog(client, /Unrecognized command/i, done);
                     clientWrite(client, encodeCommand('gx', self.data.guid, self.data.hash)).catch(err => done(err));
diff --git a/test/reliability_manager.js b/test/reliability_manager.js
index 1d9b8be..230465d 100644
--- a/test/reliability_manager.js
+++ b/test/reliability_manager.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const loki = require('lokijs');
 const tmp = require('tmp-promise');
 const randomBuffer = require('./test_utils').randomBuffer;
diff --git a/test/server.js b/test/server.js
index d792c4f..b8ee687 100644
--- a/test/server.js
+++ b/test/server.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const assert = require('assert');
 const net = require('net');
 const os = require('os');
@@ -15,10 +17,6 @@ let client;
 
 describe("Server common", function() {
 
-    beforeEach(function() {
-        helpers.setLogger(() => {});
-    });
-
     before(function () {
         return server.start(err => assert(!err, `Cache Server reported error! ${err}`));
     });
@@ -33,6 +31,8 @@ describe("Server common", function() {
             client = net.connect({port: server.port}, done);
         });
 
+        afterEach(() => client.end());
+
         it("should echo the version if supported", function (done) {
             client.on('data', function (data) {
                 const ver = helpers.readUInt32(data);
@@ -129,7 +129,7 @@ describe("Server common", function() {
                 });
 
                 client.write(helpers.encodeInt32(consts.PROTOCOL_VERSION));
-                client.write(cmd.quit);
+                client.end(cmd.quit);
             });
         });
 
@@ -142,7 +142,7 @@ describe("Server common", function() {
                 });
 
                 client.write(helpers.encodeInt32(consts.PROTOCOL_VERSION));
-                client.write('xx');
+                client.end('xx');
             });
         });
     })
diff --git a/test/test_init.js b/test/test_init.js
new file mode 100644
index 0000000..52b45c6
--- /dev/null
+++ b/test/test_init.js
@@ -0,0 +1,7 @@
+const helpers = require('../lib/helpers');
+
+process.on('unhandledRejection', (reason) => {
+    console.error(reason);
+});
+
+helpers.setLogger(() => {});
\ No newline at end of file
diff --git a/test/transaction_mirror.js b/test/transaction_mirror.js
index ad3c0bf..fffee11 100644
--- a/test/transaction_mirror.js
+++ b/test/transaction_mirror.js
@@ -1,3 +1,5 @@
+require('./test_init');
+
 const { Server, CacheRAM } = require('../lib');
 const TransactionMirror = require('../lib/server/transaction_mirror');
 const tmp = require('tmp');
@@ -25,16 +27,24 @@ describe("TransactionMirror", () => {
     before(async () => {
         this.sourceCache = new CacheRAM();
         this.targetCache = new CacheRAM();
+
         await this.sourceCache.init(cacheOpts);
         await this.targetCache.init(cacheOpts);
 
         this.targetServer = new Server(this.targetCache, {port: 0});
         await this.targetServer.start(err => assert(!err, `Server reported error! ${err}`));
-        const opts = { host: 'localhost', port: this.targetServer.port };
+        const opts = { host: 'localhost', port: this.targetServer.port, idleTimeout: 100 };
         this.mirror = new TransactionMirror(opts, this.sourceCache);
         this.mirror._queueProcessDelay = 1;
     });
 
+    after(async () => {
+        await this.sourceCache.shutdown();
+        await this.targetCache.shutdown();
+        await this.targetServer.stop();
+
+    });
+
     it("should mirror all queued transactions to the target Cache Server", async () => {
         const fileData = [
                 generateCommandData(1024, 1024),

From ddb802cb1692ba6e5da186e7539870295ee8cad5 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Wed, 19 Sep 2018 07:42:48 -0500
Subject: [PATCH 10/14] whitespace cleanup

---
 test/transaction_mirror.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/test/transaction_mirror.js b/test/transaction_mirror.js
index fffee11..2f66669 100644
--- a/test/transaction_mirror.js
+++ b/test/transaction_mirror.js
@@ -42,7 +42,6 @@ describe("TransactionMirror", () => {
         await this.sourceCache.shutdown();
         await this.targetCache.shutdown();
         await this.targetServer.stop();
-
     });
 
     it("should mirror all queued transactions to the target Cache Server", async () => {

From bd023da4238c628b1bc7513bd7b0dfa0c1e87fa0 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Wed, 19 Sep 2018 14:41:17 -0500
Subject: [PATCH 11/14] Improve test coverage, and fix some minor syntax
 issues. Removed _writev implementation of HashedWriteStream because it was
 unused and untested.

---
 lib/cache/cache_fs.js |   5 ---
 lib/client/client.js  |   2 +
 lib/helpers.js        |  10 +++--
 test/client.js        | 101 ++++++++++++++++++++++++++++++++++++++++++
 test/helpers.js       |  14 ++++++
 test/server.js        |   1 -
 6 files changed, 123 insertions(+), 10 deletions(-)
 create mode 100644 test/client.js

diff --git a/lib/cache/cache_fs.js b/lib/cache/cache_fs.js
index e7c0a3f..5d36b0d 100644
--- a/lib/cache/cache_fs.js
+++ b/lib/cache/cache_fs.js
@@ -361,11 +361,6 @@ class HashedWriteStream extends fs.WriteStream {
         super._write(data, encoding, cb);
     }
 
-    _writev (chunks, cb) {
-        chunks.forEach(chunk => this._hash.update(chunk, 'ascii'));
-        super._writev(chunks, cb);
-    }
-
     get byteHash() {
         return this._hash.digest();
     }
diff --git a/lib/client/client.js b/lib/client/client.js
index 0dd0311..63a34ce 100644
--- a/lib/client/client.js
+++ b/lib/client/client.js
@@ -85,6 +85,8 @@ class CacheClient {
      * @returns {Promise<any>}
      */
     quit() {
+        if(!this._client) return Promise.resolve();
+
         return new Promise(resolve => {
             this._client.once('close', () => resolve());
             this._client.end(cmd.quit);
diff --git a/lib/helpers.js b/lib/helpers.js
index 5b7b762..915ee9a 100644
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -93,6 +93,9 @@ exports.isBuffer = function(obj) {
  * @returns {Promise<any>}
  */
 exports.parseAndValidateAddressString = function(address, defaultPort) {
+    if(ip.isV6Format(address) && !ip.isV4Format(address))
+        return Promise.reject("IPV6 mirrors not supported");
+
     // eslint-disable-next-line prefer-const
     let [host, port] = address.split(':');
     port = port || defaultPort;
@@ -217,10 +220,9 @@ function locationOf(item, array, compare, start, end) {
     start = start || 0;
     end = end || array.length;
 
-    let pivot = (start + end) >> 1;
-
-    let c = compare(item, array[pivot]);
-    if (end - start <= 1) return c == -1 ? pivot - 1 : pivot;
+    const pivot = (start + end) >> 1;
+    const c = compare(item, array[pivot]);
+    if (end - start <= 1) return c === -1 ? pivot - 1 : pivot;
 
     switch (c) {
         case -1: return locationOf(item, array, compare, start, pivot);
diff --git a/test/client.js b/test/client.js
new file mode 100644
index 0000000..9c8f9c4
--- /dev/null
+++ b/test/client.js
@@ -0,0 +1,101 @@
+require('./test_init');
+
+const assert = require('assert');
+const net = require('net');
+const Client = require('../lib/client/client');
+const WritableStream = require('stream').Writable;
+const consts = require('../lib/constants');
+const generateCommandData = require('./test_utils').generateCommandData;
+
+describe("Client", () => {
+    this.getClient = () => {
+        return new Client("127.0.0.1", 9999);
+    };
+
+    this.getConnectedClient = async (onConnect) => {
+        return new Promise((resolve) => {
+            const s = net.createServer(socket => onConnect(socket));
+            s.listen(0, "0.0.0.0", () => {
+                const a = s.address();
+                resolve({server: s, client: new Client(a.address, a.port)});
+            });
+        });
+    };
+
+    describe("close", () => {
+        it("should resolve without error if called before connect()", async () => {
+            await this.getClient().quit();
+        });
+    });
+
+    describe("connect", () => {
+        it("should return the client object if called one or more times", async () => {
+            const data = await this.getConnectedClient(() => {});
+            assert.strictEqual(await data.client.connect(), data.client);
+            assert.strictEqual(await data.client.connect(), data.client);
+            data.server.close();
+        });
+    });
+
+    describe("putFile", () => {
+        it("should throw an error if an unrecognized type is specified", async () => {
+            const b = Buffer.alloc(16);
+            await this.getClient().putFile('x', b, b, b, 16)
+                .then(() => { throw new Error("Expected error"); }, err => assert(err));
+        });
+
+        it("should throw an error if an invalid guid is specified", async () => {
+            const b = Buffer.alloc(16);
+
+            // wrong size buffer
+            await this.getClient().putFile('a', Buffer.alloc(12), b, b, 16)
+                .then(() => { throw new Error("Expected error"); }, err => assert(err));
+
+            // wrong type
+            await this.getClient().putFile('a', "not a buffer", b, b, 16)
+                .then(() => { throw new Error("Expected error"); }, err => assert(err));
+        });
+
+        it("should throw an error if an invalid hash is specified", async () => {
+            const b = Buffer.alloc(16);
+
+            // wrong size buffer
+            await this.getClient().putFile(Client.fileTypes.BIN, b, Buffer.alloc(12), b, 16)
+                .then(() => { throw new Error("Expected error"); }, err => assert(err));
+
+            // wrong type
+            await this.getClient().putFile(Client.fileTypes.BIN, b, "not a buffer", b, 16)
+                .then(() => { throw new Error("Expected error"); }, err => assert(err));
+        });
+
+        it("should throw an error if client is not connected", async () => {
+            const b = Buffer.alloc(16);
+            await this.getClient().putFile(Client.fileTypes.BIN, b, b, b, 16)
+                .then(() => { throw new Error("Expected error"); }, err => assert(err));
+        });
+
+        it("should send the given buffer to the server", (done) => {
+            const data = generateCommandData(256, 256);
+            let client, server;
+
+            this.getConnectedClient(socket => {
+                socket.pipe(new WritableStream({
+                    write(chunk, encoding, callback) {
+                        const len = consts.VERSION_SIZE + consts.CMD_SIZE + consts.SIZE_SIZE;
+                        const slice = chunk.slice(len, len + data.bin.length);
+                        assert.strictEqual(data.bin.compare(slice), 0);
+                        callback();
+                    },
+                    final(cb) {
+                        cb();
+                        done();
+                    }
+                }));
+            })
+                .then(data => { client = data.client; server = data.server; return client.connect(); })
+                .then(() => client.putFile(Client.fileTypes.BIN, data.guid, data.hash, data.bin, data.bin.length))
+                .then(() => client.quit())
+                .then(() => server.close());
+        });
+    });
+});
\ No newline at end of file
diff --git a/test/helpers.js b/test/helpers.js
index e431c42..2ea0d70 100644
--- a/test/helpers.js
+++ b/test/helpers.js
@@ -50,6 +50,20 @@ describe("Helper functions", () => {
             assert.strictEqual(result.port, 0);
         });
 
+        it("should return the same IP address passed in if already in ip v4 format", async () => {
+            const result = await helpers.parseAndValidateAddressString("1.2.3.4", 1234);
+            assert.equal(result.host, "1.2.3.4");
+            assert.strictEqual(result.port, 1234);
+        });
+
+        it("should throw an error if address in ip v6 format", async () => {
+            await helpers.parseAndValidateAddressString("2001::4860::4860::8888", 0)
+                .then(() => { throw new Error("Expected error"); }).catch(err => assert(err));
+
+            await helpers.parseAndValidateAddressString("2001:db8:0:0:0:0:2:1", 0)
+                .then(() => { throw new Error("Expected error"); }).catch(err => assert(err));
+        });
+
         it("should parse an address:port string", async () => {
             const result = await helpers.parseAndValidateAddressString("localhost:1234", 0);
             assert.equal(result.host, "127.0.0.1");
diff --git a/test/server.js b/test/server.js
index b8ee687..f10507f 100644
--- a/test/server.js
+++ b/test/server.js
@@ -10,7 +10,6 @@ const Cache = require('../lib/cache/cache_base').CacheBase;
 const sleep = require('./test_utils').sleep;
 const cmd = require('./test_utils').cmd;
 
-helpers.setLogger(()=>{});
 const cache = new Cache();
 const server = new CacheServer(cache, {port: 0});
 let client;

From d7f338df21657d0bda5f2b804dd0907ac2587942 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Wed, 19 Sep 2018 15:00:43 -0500
Subject: [PATCH 12/14] Refactored test to better cleanup client/server
 connections

---
 test/client.js | 46 ++++++++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/test/client.js b/test/client.js
index 9c8f9c4..87a283d 100644
--- a/test/client.js
+++ b/test/client.js
@@ -8,20 +8,33 @@ const consts = require('../lib/constants');
 const generateCommandData = require('./test_utils').generateCommandData;
 
 describe("Client", () => {
-    this.getClient = () => {
-        return new Client("127.0.0.1", 9999);
-    };
+    
+    beforeEach(() => {
+        this._client = null;
+        this._server = null;
+    });
+
+    afterEach(async () => {
+        if(this._client) { await this._client.quit(); }
+        if(this._server) { await this._server.close(); }
+    });
 
-    this.getConnectedClient = async (onConnect) => {
+    this.initClientServer = async (onConnect) => {
+        const self = this;
         return new Promise((resolve) => {
-            const s = net.createServer(socket => onConnect(socket));
-            s.listen(0, "0.0.0.0", () => {
-                const a = s.address();
-                resolve({server: s, client: new Client(a.address, a.port)});
+            self._server = net.createServer(socket => onConnect(socket));
+            self._server.listen(0, "0.0.0.0", () => {
+                const a = self._server.address();
+                self._client = new Client(a.address, a.port);
+                resolve();
             });
         });
     };
 
+    this.getClient = () => {
+        return new Client("127.0.0.1", 9999);
+    };
+
     describe("close", () => {
         it("should resolve without error if called before connect()", async () => {
             await this.getClient().quit();
@@ -30,10 +43,9 @@ describe("Client", () => {
 
     describe("connect", () => {
         it("should return the client object if called one or more times", async () => {
-            const data = await this.getConnectedClient(() => {});
-            assert.strictEqual(await data.client.connect(), data.client);
-            assert.strictEqual(await data.client.connect(), data.client);
-            data.server.close();
+            await this.initClientServer(() => {});
+            assert.strictEqual(await this._client.connect(), this._client);
+            assert.strictEqual(await this._client.connect(), this._client);
         });
     });
 
@@ -76,9 +88,8 @@ describe("Client", () => {
 
         it("should send the given buffer to the server", (done) => {
             const data = generateCommandData(256, 256);
-            let client, server;
 
-            this.getConnectedClient(socket => {
+            this.initClientServer(socket => {
                 socket.pipe(new WritableStream({
                     write(chunk, encoding, callback) {
                         const len = consts.VERSION_SIZE + consts.CMD_SIZE + consts.SIZE_SIZE;
@@ -92,10 +103,9 @@ describe("Client", () => {
                     }
                 }));
             })
-                .then(data => { client = data.client; server = data.server; return client.connect(); })
-                .then(() => client.putFile(Client.fileTypes.BIN, data.guid, data.hash, data.bin, data.bin.length))
-                .then(() => client.quit())
-                .then(() => server.close());
+                .then(() => this._client.connect())
+                .then(() => this._client.putFile(Client.fileTypes.BIN, data.guid, data.hash, data.bin, data.bin.length))
+                .then(() => this._client.quit());
         });
     });
 });
\ No newline at end of file

From 61ab79ac0578d64ff729107fb1ad3381ab755057 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Thu, 20 Sep 2018 06:24:21 -0500
Subject: [PATCH 13/14] Package version bump

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index b9ac9ef..60cd7ee 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "unity-cache-server",
-  "version": "6.1.2-beta.1",
+  "version": "6.1.2-beta.3",
   "description": "Unity Cache Server",
   "main": "lib/index.js",
   "engines": {

From 96b312fe2b58771e3ae4c1a18a272b5699999029 Mon Sep 17 00:00:00 2001
From: Stephen Palmer <stephenp@unity3d.com>
Date: Wed, 26 Sep 2018 07:31:29 -0500
Subject: [PATCH 14/14] - minor syntax fixes - bump version for release

---
 lib/cache/cache_fs.js | 4 ++--
 package.json          | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/cache/cache_fs.js b/lib/cache/cache_fs.js
index 5d36b0d..f9aa82a 100644
--- a/lib/cache/cache_fs.js
+++ b/lib/cache/cache_fs.js
@@ -123,7 +123,7 @@ class CacheFS extends CacheBase {
         let deleteSize = 0;
         let deletedItemCount = 0;
         let deleteItems = [];
-        let verb = dryRun ? 'Gathering' : 'Removing';
+        const verb = dryRun ? 'Gathering' : 'Removing';
         let spinnerMessage = verb + ' expired files';
 
         const progressData = () => {
@@ -184,7 +184,7 @@ class CacheFS extends CacheBase {
                         needsSorted = false;
                     }
 
-                    let i = deleteItems[deleteItems.length - 1]; // i is the MRU out of the current delete list
+                    const i = deleteItems[deleteItems.length - 1]; // i is the MRU out of the current delete list
 
                     if (item.stats.atime < i.stats.atime) {
                         deleteItems = helpers.insertSorted(item, deleteItems, (a, b) => {
diff --git a/package.json b/package.json
index 60cd7ee..d1b0021 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "unity-cache-server",
-  "version": "6.1.2-beta.3",
+  "version": "6.1.2",
   "description": "Unity Cache Server",
   "main": "lib/index.js",
   "engines": {