Index: trip-planner-front/node_modules/ws/lib/buffer-util.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/buffer-util.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/buffer-util.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -16,13 +16,11 @@
 
   const target = Buffer.allocUnsafe(totalLength);
-  let offset = 0;
+  var offset = 0;
 
-  for (let i = 0; i < list.length; i++) {
+  for (var i = 0; i < list.length; i++) {
     const buf = list[i];
-    target.set(buf, offset);
+    buf.copy(target, offset);
     offset += buf.length;
   }
-
-  if (offset < totalLength) return target.slice(0, offset);
 
   return target;
@@ -40,5 +38,5 @@
  */
 function _mask(source, mask, output, offset, length) {
-  for (let i = 0; i < length; i++) {
+  for (var i = 0; i < length; i++) {
     output[offset + i] = source[i] ^ mask[i & 3];
   }
@@ -55,5 +53,5 @@
   // Required until https://github.com/nodejs/node/issues/9006 is resolved.
   const length = buffer.length;
-  for (let i = 0; i < length; i++) {
+  for (var i = 0; i < length; i++) {
     buffer[i] ^= mask[i & 3];
   }
@@ -88,13 +86,30 @@
   if (Buffer.isBuffer(data)) return data;
 
-  let buf;
+  var buf;
 
   if (data instanceof ArrayBuffer) {
     buf = Buffer.from(data);
   } else if (ArrayBuffer.isView(data)) {
-    buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
+    buf = viewToBuffer(data);
   } else {
     buf = Buffer.from(data);
     toBuffer.readOnly = false;
+  }
+
+  return buf;
+}
+
+/**
+ * Converts an `ArrayBuffer` view into a buffer.
+ *
+ * @param {(DataView|TypedArray)} view The view to convert
+ * @return {Buffer} Converted view
+ * @private
+ */
+function viewToBuffer(view) {
+  const buf = Buffer.from(view.buffer);
+
+  if (view.byteLength !== view.buffer.byteLength) {
+    return buf.slice(view.byteOffset, view.byteOffset + view.byteLength);
   }
 
Index: trip-planner-front/node_modules/ws/lib/event-target.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/event-target.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/event-target.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -11,6 +11,5 @@
    *
    * @param {String} type The name of the event
-   * @param {Object} target A reference to the target to which the event was
-   *     dispatched
+   * @param {Object} target A reference to the target to which the event was dispatched
    */
   constructor(type, target) {
@@ -31,6 +30,5 @@
    *
    * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data
-   * @param {WebSocket} target A reference to the target to which the event was
-   *     dispatched
+   * @param {WebSocket} target A reference to the target to which the event was dispatched
    */
   constructor(data, target) {
@@ -51,10 +49,7 @@
    * Create a new `CloseEvent`.
    *
-   * @param {Number} code The status code explaining why the connection is being
-   *     closed
-   * @param {String} reason A human-readable string explaining why the
-   *     connection is closing
-   * @param {WebSocket} target A reference to the target to which the event was
-   *     dispatched
+   * @param {Number} code The status code explaining why the connection is being closed
+   * @param {String} reason A human-readable string explaining why the connection is closing
+   * @param {WebSocket} target A reference to the target to which the event was dispatched
    */
   constructor(code, reason, target) {
@@ -77,6 +72,5 @@
    * Create a new `OpenEvent`.
    *
-   * @param {WebSocket} target A reference to the target to which the event was
-   *     dispatched
+   * @param {WebSocket} target A reference to the target to which the event was dispatched
    */
   constructor(target) {
@@ -96,6 +90,5 @@
    *
    * @param {Object} error The error that generated this event
-   * @param {WebSocket} target A reference to the target to which the event was
-   *     dispatched
+   * @param {WebSocket} target A reference to the target to which the event was dispatched
    */
   constructor(error, target) {
@@ -117,14 +110,9 @@
    * Register an event listener.
    *
-   * @param {String} type A string representing the event type to listen for
+   * @param {String} method A string representing the event type to listen for
    * @param {Function} listener The listener to add
-   * @param {Object} [options] An options object specifies characteristics about
-   *     the event listener
-   * @param {Boolean} [options.once=false] A `Boolean`` indicating that the
-   *     listener should be invoked at most once after being added. If `true`,
-   *     the listener would be automatically removed when invoked.
    * @public
    */
-  addEventListener(type, listener, options) {
+  addEventListener(method, listener) {
     if (typeof listener !== 'function') return;
 
@@ -145,20 +133,18 @@
     }
 
-    const method = options && options.once ? 'once' : 'on';
-
-    if (type === 'message') {
+    if (method === 'message') {
       onMessage._listener = listener;
-      this[method](type, onMessage);
-    } else if (type === 'close') {
+      this.on(method, onMessage);
+    } else if (method === 'close') {
       onClose._listener = listener;
-      this[method](type, onClose);
-    } else if (type === 'error') {
+      this.on(method, onClose);
+    } else if (method === 'error') {
       onError._listener = listener;
-      this[method](type, onError);
-    } else if (type === 'open') {
+      this.on(method, onError);
+    } else if (method === 'open') {
       onOpen._listener = listener;
-      this[method](type, onOpen);
+      this.on(method, onOpen);
     } else {
-      this[method](type, listener);
+      this.on(method, listener);
     }
   },
@@ -167,14 +153,14 @@
    * Remove an event listener.
    *
-   * @param {String} type A string representing the event type to remove
+   * @param {String} method A string representing the event type to remove
    * @param {Function} listener The listener to remove
    * @public
    */
-  removeEventListener(type, listener) {
-    const listeners = this.listeners(type);
+  removeEventListener(method, listener) {
+    const listeners = this.listeners(method);
 
-    for (let i = 0; i < listeners.length; i++) {
+    for (var i = 0; i < listeners.length; i++) {
       if (listeners[i] === listener || listeners[i]._listener === listener) {
-        this.removeListener(type, listeners[i]);
+        this.removeListener(method, listeners[i]);
       }
     }
Index: trip-planner-front/node_modules/ws/lib/extension.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/extension.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/extension.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -35,6 +35,6 @@
  */
 function push(dest, name, elem) {
-  if (dest[name] === undefined) dest[name] = [elem];
-  else dest[name].push(elem);
+  if (Object.prototype.hasOwnProperty.call(dest, name)) dest[name].push(elem);
+  else dest[name] = [elem];
 }
 
@@ -47,19 +47,18 @@
  */
 function parse(header) {
-  const offers = Object.create(null);
+  const offers = {};
 
   if (header === undefined || header === '') return offers;
 
-  let params = Object.create(null);
-  let mustUnescape = false;
-  let isEscaping = false;
-  let inQuotes = false;
-  let extensionName;
-  let paramName;
-  let start = -1;
-  let end = -1;
-  let i = 0;
-
-  for (; i < header.length; i++) {
+  var params = {};
+  var mustUnescape = false;
+  var isEscaping = false;
+  var inQuotes = false;
+  var extensionName;
+  var paramName;
+  var start = -1;
+  var end = -1;
+
+  for (var i = 0; i < header.length; i++) {
     const code = header.charCodeAt(i);
 
@@ -78,5 +77,5 @@
         if (code === 0x2c) {
           push(offers, name, params);
-          params = Object.create(null);
+          params = {};
         } else {
           extensionName = name;
@@ -101,5 +100,5 @@
         if (code === 0x2c) {
           push(offers, extensionName, params);
-          params = Object.create(null);
+          params = {};
           extensionName = undefined;
         }
@@ -148,5 +147,5 @@
 
         if (end === -1) end = i;
-        let value = header.slice(start, end);
+        var value = header.slice(start, end);
         if (mustUnescape) {
           value = value.replace(/\\/g, '');
@@ -156,5 +155,5 @@
         if (code === 0x2c) {
           push(offers, extensionName, params);
-          params = Object.create(null);
+          params = {};
           extensionName = undefined;
         }
@@ -175,5 +174,5 @@
   const token = header.slice(start, end);
   if (extensionName === undefined) {
-    push(offers, token, params);
+    push(offers, token, {});
   } else {
     if (paramName === undefined) {
@@ -200,5 +199,5 @@
   return Object.keys(extensions)
     .map((extension) => {
-      let configurations = extensions[extension];
+      var configurations = extensions[extension];
       if (!Array.isArray(configurations)) configurations = [configurations];
       return configurations
@@ -207,5 +206,5 @@
             .concat(
               Object.keys(params).map((k) => {
-                let values = params[k];
+                var values = params[k];
                 if (!Array.isArray(values)) values = [values];
                 return values
Index: trip-planner-front/node_modules/ws/lib/limiter.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/limiter.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ 	(revision )
@@ -1,55 +1,0 @@
-'use strict';
-
-const kDone = Symbol('kDone');
-const kRun = Symbol('kRun');
-
-/**
- * A very simple job queue with adjustable concurrency. Adapted from
- * https://github.com/STRML/async-limiter
- */
-class Limiter {
-  /**
-   * Creates a new `Limiter`.
-   *
-   * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed
-   *     to run concurrently
-   */
-  constructor(concurrency) {
-    this[kDone] = () => {
-      this.pending--;
-      this[kRun]();
-    };
-    this.concurrency = concurrency || Infinity;
-    this.jobs = [];
-    this.pending = 0;
-  }
-
-  /**
-   * Adds a job to the queue.
-   *
-   * @param {Function} job The job to run
-   * @public
-   */
-  add(job) {
-    this.jobs.push(job);
-    this[kRun]();
-  }
-
-  /**
-   * Removes a job from the queue and runs it if possible.
-   *
-   * @private
-   */
-  [kRun]() {
-    if (this.pending === this.concurrency) return;
-
-    if (this.jobs.length) {
-      const job = this.jobs.shift();
-
-      this.pending++;
-      job(this[kDone]);
-    }
-  }
-}
-
-module.exports = Limiter;
Index: trip-planner-front/node_modules/ws/lib/permessage-deflate.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/permessage-deflate.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/permessage-deflate.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -1,11 +1,13 @@
 'use strict';
 
+const Limiter = require('async-limiter');
 const zlib = require('zlib');
 
 const bufferUtil = require('./buffer-util');
-const Limiter = require('./limiter');
 const { kStatusCode, NOOP } = require('./constants');
 
 const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
+const EMPTY_BLOCK = Buffer.from([0x00]);
+
 const kPerMessageDeflate = Symbol('permessage-deflate');
 const kTotalLength = Symbol('total-length');
@@ -30,24 +32,22 @@
    * Creates a PerMessageDeflate instance.
    *
-   * @param {Object} [options] Configuration options
-   * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
-   *     disabling of server context takeover
-   * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/
-   *     acknowledge disabling of client context takeover
-   * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
+   * @param {Object} options Configuration options
+   * @param {Boolean} options.serverNoContextTakeover Request/accept disabling
+   *     of server context takeover
+   * @param {Boolean} options.clientNoContextTakeover Advertise/acknowledge
+   *     disabling of client context takeover
+   * @param {(Boolean|Number)} options.serverMaxWindowBits Request/confirm the
    *     use of a custom server window size
-   * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support
+   * @param {(Boolean|Number)} options.clientMaxWindowBits Advertise support
    *     for, or request, a custom client window size
-   * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on
-   *     deflate
-   * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
-   *     inflate
-   * @param {Number} [options.threshold=1024] Size (in bytes) below which
-   *     messages should not be compressed
-   * @param {Number} [options.concurrencyLimit=10] The number of concurrent
-   *     calls to zlib
-   * @param {Boolean} [isServer=false] Create the instance in either server or
-   *     client mode
-   * @param {Number} [maxPayload=0] The maximum allowed message length
+   * @param {Object} options.zlibDeflateOptions Options to pass to zlib on deflate
+   * @param {Object} options.zlibInflateOptions Options to pass to zlib on inflate
+   * @param {Number} options.threshold Size (in bytes) below which messages
+   *     should not be compressed
+   * @param {Number} options.concurrencyLimit The number of concurrent calls to
+   *     zlib
+   * @param {Boolean} isServer Create the instance in either server or client
+   *     mode
+   * @param {Number} maxPayload The maximum allowed message length
    */
   constructor(options, isServer, maxPayload) {
@@ -67,5 +67,5 @@
           ? this._options.concurrencyLimit
           : 10;
-      zlibLimiter = new Limiter(concurrency);
+      zlibLimiter = new Limiter({ concurrency });
     }
   }
@@ -134,16 +134,6 @@
 
     if (this._deflate) {
-      const callback = this._deflate[kCallback];
-
       this._deflate.close();
       this._deflate = null;
-
-      if (callback) {
-        callback(
-          new Error(
-            'The deflate stream was closed while data was being processed'
-          )
-        );
-      }
     }
   }
@@ -244,5 +234,5 @@
     configurations.forEach((params) => {
       Object.keys(params).forEach((key) => {
-        let value = params[key];
+        var value = params[key];
 
         if (value.length > 1) {
@@ -295,5 +285,5 @@
 
   /**
-   * Decompress data. Concurrency limited.
+   * Decompress data. Concurrency limited by async-limiter.
    *
    * @param {Buffer} data Compressed data
@@ -303,5 +293,5 @@
    */
   decompress(data, fin, callback) {
-    zlibLimiter.add((done) => {
+    zlibLimiter.push((done) => {
       this._decompress(data, fin, (err, result) => {
         done();
@@ -312,5 +302,5 @@
 
   /**
-   * Compress data. Concurrency limited.
+   * Compress data. Concurrency limited by async-limiter.
    *
    * @param {Buffer} data Data to compress
@@ -320,5 +310,5 @@
    */
   compress(data, fin, callback) {
-    zlibLimiter.add((done) => {
+    zlibLimiter.push((done) => {
       this._compress(data, fin, (err, result) => {
         done();
@@ -346,8 +336,7 @@
           : this.params[key];
 
-      this._inflate = zlib.createInflateRaw({
-        ...this._options.zlibInflateOptions,
-        windowBits
-      });
+      this._inflate = zlib.createInflateRaw(
+        Object.assign({}, this._options.zlibInflateOptions, { windowBits })
+      );
       this._inflate[kPerMessageDeflate] = this;
       this._inflate[kTotalLength] = 0;
@@ -377,5 +366,5 @@
       );
 
-      if (this._inflate._readableState.endEmitted) {
+      if (fin && this.params[`${endpoint}_no_context_takeover`]) {
         this._inflate.close();
         this._inflate = null;
@@ -383,8 +372,4 @@
         this._inflate[kTotalLength] = 0;
         this._inflate[kBuffers] = [];
-
-        if (fin && this.params[`${endpoint}_no_context_takeover`]) {
-          this._inflate.reset();
-        }
       }
 
@@ -402,4 +387,9 @@
    */
   _compress(data, fin, callback) {
+    if (!data || data.length === 0) {
+      process.nextTick(callback, null, EMPTY_BLOCK);
+      return;
+    }
+
     const endpoint = this._isServer ? 'server' : 'client';
 
@@ -411,8 +401,7 @@
           : this.params[key];
 
-      this._deflate = zlib.createDeflateRaw({
-        ...this._options.zlibDeflateOptions,
-        windowBits
-      });
+      this._deflate = zlib.createDeflateRaw(
+        Object.assign({}, this._options.zlibDeflateOptions, { windowBits })
+      );
 
       this._deflate[kTotalLength] = 0;
@@ -429,16 +418,17 @@
     }
 
-    this._deflate[kCallback] = callback;
-
     this._deflate.write(data);
     this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
       if (!this._deflate) {
         //
-        // The deflate stream was closed while data was being processed.
+        // This `if` statement is only needed for Node.js < 10.0.0 because as of
+        // commit https://github.com/nodejs/node/commit/5e3f5164, the flush
+        // callback is no longer called if the deflate stream is closed while
+        // data is being processed.
         //
         return;
       }
 
-      let data = bufferUtil.concat(
+      var data = bufferUtil.concat(
         this._deflate[kBuffers],
         this._deflate[kTotalLength]
@@ -447,15 +437,10 @@
       if (fin) data = data.slice(0, data.length - 4);
 
-      //
-      // Ensure that the callback will not be called again in
-      // `PerMessageDeflate#cleanup()`.
-      //
-      this._deflate[kCallback] = null;
-
-      this._deflate[kTotalLength] = 0;
-      this._deflate[kBuffers] = [];
-
       if (fin && this.params[`${endpoint}_no_context_takeover`]) {
-        this._deflate.reset();
+        this._deflate.close();
+        this._deflate = null;
+      } else {
+        this._deflate[kTotalLength] = 0;
+        this._deflate[kBuffers] = [];
       }
 
Index: trip-planner-front/node_modules/ws/lib/receiver.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/receiver.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/receiver.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -29,11 +29,9 @@
    * Creates a Receiver instance.
    *
-   * @param {String} [binaryType=nodebuffer] The type for binary data
-   * @param {Object} [extensions] An object containing the negotiated extensions
-   * @param {Boolean} [isServer=false] Specifies whether to operate in client or
-   *     server mode
-   * @param {Number} [maxPayload=0] The maximum allowed message length
-   */
-  constructor(binaryType, extensions, isServer, maxPayload) {
+   * @param {String} binaryType The type for binary data
+   * @param {Object} extensions An object containing the negotiated extensions
+   * @param {Number} maxPayload The maximum allowed message length
+   */
+  constructor(binaryType, extensions, maxPayload) {
     super();
 
@@ -41,5 +39,4 @@
     this[kWebSocket] = undefined;
     this._extensions = extensions || {};
-    this._isServer = !!isServer;
     this._maxPayload = maxPayload | 0;
 
@@ -69,5 +66,4 @@
    * @param {String} encoding The character encoding of `chunk`
    * @param {Function} cb Callback
-   * @private
    */
   _write(chunk, encoding, cb) {
@@ -101,10 +97,9 @@
     do {
       const buf = this._buffers[0];
-      const offset = dst.length - n;
 
       if (n >= buf.length) {
-        dst.set(this._buffers.shift(), offset);
+        this._buffers.shift().copy(dst, dst.length - n);
       } else {
-        dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
+        buf.copy(dst, dst.length - n, 0, n);
         this._buffers[0] = buf.slice(n);
       }
@@ -123,5 +118,5 @@
    */
   startLoop(cb) {
-    let err;
+    var err;
     this._loop = true;
 
@@ -230,14 +225,4 @@
     this._masked = (buf[1] & 0x80) === 0x80;
 
-    if (this._isServer) {
-      if (!this._masked) {
-        this._loop = false;
-        return error(RangeError, 'MASK must be set', true, 1002);
-      }
-    } else if (this._masked) {
-      this._loop = false;
-      return error(RangeError, 'MASK must be clear', true, 1002);
-    }
-
     if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;
     else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;
@@ -336,5 +321,5 @@
    */
   getData(cb) {
-    let data = EMPTY_BUFFER;
+    var data = EMPTY_BUFFER;
 
     if (this._payloadLength) {
@@ -416,5 +401,5 @@
 
       if (this._opcode === 2) {
-        let data;
+        var data;
 
         if (this._binaryType === 'nodebuffer') {
Index: trip-planner-front/node_modules/ws/lib/sender.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/sender.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/sender.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -1,5 +1,5 @@
 'use strict';
 
-const { randomFillSync } = require('crypto');
+const { randomBytes } = require('crypto');
 
 const PerMessageDeflate = require('./permessage-deflate');
@@ -8,6 +8,4 @@
 const { mask: applyMask, toBuffer } = require('./buffer-util');
 
-const mask = Buffer.alloc(4);
-
 /**
  * HyBi Sender implementation.
@@ -18,5 +16,5 @@
    *
    * @param {net.Socket} socket The connection socket
-   * @param {Object} [extensions] An object containing the negotiated extensions
+   * @param {Object} extensions An object containing the negotiated extensions
    */
   constructor(socket, extensions) {
@@ -38,12 +36,8 @@
    * @param {Object} options Options object
    * @param {Number} options.opcode The opcode
-   * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
-   *     modified
-   * @param {Boolean} [options.fin=false] Specifies whether or not to set the
-   *     FIN bit
-   * @param {Boolean} [options.mask=false] Specifies whether or not to mask
-   *     `data`
-   * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
-   *     RSV1 bit
+   * @param {Boolean} options.readOnly Specifies whether `data` can be modified
+   * @param {Boolean} options.fin Specifies whether or not to set the FIN bit
+   * @param {Boolean} options.mask Specifies whether or not to mask `data`
+   * @param {Boolean} options.rsv1 Specifies whether or not to set the RSV1 bit
    * @return {Buffer[]} The framed data as a list of `Buffer` instances
    * @public
@@ -51,6 +45,6 @@
   static frame(data, options) {
     const merge = options.mask && options.readOnly;
-    let offset = options.mask ? 6 : 2;
-    let payloadLength = data.length;
+    var offset = options.mask ? 6 : 2;
+    var payloadLength = data.length;
 
     if (data.length >= 65536) {
@@ -78,5 +72,5 @@
     if (!options.mask) return [target, data];
 
-    randomFillSync(mask, 0, 4);
+    const mask = randomBytes(4);
 
     target[1] |= 0x80;
@@ -98,12 +92,12 @@
    * Sends a close message to the other peer.
    *
-   * @param {Number} [code] The status code component of the body
-   * @param {String} [data] The message component of the body
-   * @param {Boolean} [mask=false] Specifies whether or not to mask the message
-   * @param {Function} [cb] Callback
+   * @param {(Number|undefined)} code The status code component of the body
+   * @param {String} data The message component of the body
+   * @param {Boolean} mask Specifies whether or not to mask the message
+   * @param {Function} cb Callback
    * @public
    */
   close(code, data, mask, cb) {
-    let buf;
+    var buf;
 
     if (code === undefined) {
@@ -115,11 +109,5 @@
       buf.writeUInt16BE(code, 0);
     } else {
-      const length = Buffer.byteLength(data);
-
-      if (length > 123) {
-        throw new RangeError('The message must not be greater than 123 bytes');
-      }
-
-      buf = Buffer.allocUnsafe(2 + length);
+      buf = Buffer.allocUnsafe(2 + Buffer.byteLength(data));
       buf.writeUInt16BE(code, 0);
       buf.write(data, 2);
@@ -137,6 +125,6 @@
    *
    * @param {Buffer} data The message to send
-   * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
-   * @param {Function} [cb] Callback
+   * @param {Boolean} mask Specifies whether or not to mask `data`
+   * @param {Function} cb Callback
    * @private
    */
@@ -158,6 +146,6 @@
    *
    * @param {*} data The message to send
-   * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
-   * @param {Function} [cb] Callback
+   * @param {Boolean} mask Specifies whether or not to mask `data`
+   * @param {Function} cb Callback
    * @public
    */
@@ -165,8 +153,4 @@
     const buf = toBuffer(data);
 
-    if (buf.length > 125) {
-      throw new RangeError('The data size must not be greater than 125 bytes');
-    }
-
     if (this._deflating) {
       this.enqueue([this.doPing, buf, mask, toBuffer.readOnly, cb]);
@@ -179,8 +163,8 @@
    * Frames and sends a ping message.
    *
-   * @param {Buffer} data The message to send
-   * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
-   * @param {Boolean} [readOnly=false] Specifies whether `data` can be modified
-   * @param {Function} [cb] Callback
+   * @param {*} data The message to send
+   * @param {Boolean} mask Specifies whether or not to mask `data`
+   * @param {Boolean} readOnly Specifies whether `data` can be modified
+   * @param {Function} cb Callback
    * @private
    */
@@ -202,6 +186,6 @@
    *
    * @param {*} data The message to send
-   * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
-   * @param {Function} [cb] Callback
+   * @param {Boolean} mask Specifies whether or not to mask `data`
+   * @param {Function} cb Callback
    * @public
    */
@@ -209,8 +193,4 @@
     const buf = toBuffer(data);
 
-    if (buf.length > 125) {
-      throw new RangeError('The data size must not be greater than 125 bytes');
-    }
-
     if (this._deflating) {
       this.enqueue([this.doPong, buf, mask, toBuffer.readOnly, cb]);
@@ -223,8 +203,8 @@
    * Frames and sends a pong message.
    *
-   * @param {Buffer} data The message to send
-   * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
-   * @param {Boolean} [readOnly=false] Specifies whether `data` can be modified
-   * @param {Function} [cb] Callback
+   * @param {*} data The message to send
+   * @param {Boolean} mask Specifies whether or not to mask `data`
+   * @param {Boolean} readOnly Specifies whether `data` can be modified
+   * @param {Function} cb Callback
    * @private
    */
@@ -247,13 +227,9 @@
    * @param {*} data The message to send
    * @param {Object} options Options object
-   * @param {Boolean} [options.compress=false] Specifies whether or not to
-   *     compress `data`
-   * @param {Boolean} [options.binary=false] Specifies whether `data` is binary
-   *     or text
-   * @param {Boolean} [options.fin=false] Specifies whether the fragment is the
-   *     last one
-   * @param {Boolean} [options.mask=false] Specifies whether or not to mask
-   *     `data`
-   * @param {Function} [cb] Callback
+   * @param {Boolean} options.compress Specifies whether or not to compress `data`
+   * @param {Boolean} options.binary Specifies whether `data` is binary or text
+   * @param {Boolean} options.fin Specifies whether the fragment is the last one
+   * @param {Boolean} options.mask Specifies whether or not to mask `data`
+   * @param {Function} cb Callback
    * @public
    */
@@ -261,6 +237,6 @@
     const buf = toBuffer(data);
     const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
-    let opcode = options.binary ? 2 : 1;
-    let rsv1 = options.compress;
+    var opcode = options.binary ? 2 : 1;
+    var rsv1 = options.compress;
 
     if (this._firstFragment) {
@@ -309,17 +285,12 @@
    *
    * @param {Buffer} data The message to send
-   * @param {Boolean} [compress=false] Specifies whether or not to compress
-   *     `data`
+   * @param {Boolean} compress Specifies whether or not to compress `data`
    * @param {Object} options Options object
    * @param {Number} options.opcode The opcode
-   * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
-   *     modified
-   * @param {Boolean} [options.fin=false] Specifies whether or not to set the
-   *     FIN bit
-   * @param {Boolean} [options.mask=false] Specifies whether or not to mask
-   *     `data`
-   * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
-   *     RSV1 bit
-   * @param {Function} [cb] Callback
+   * @param {Boolean} options.readOnly Specifies whether `data` can be modified
+   * @param {Boolean} options.fin Specifies whether or not to set the FIN bit
+   * @param {Boolean} options.mask Specifies whether or not to mask `data`
+   * @param {Boolean} options.rsv1 Specifies whether or not to set the RSV1 bit
+   * @param {Function} cb Callback
    * @private
    */
@@ -332,24 +303,6 @@
     const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
 
-    this._bufferedBytes += data.length;
     this._deflating = true;
     perMessageDeflate.compress(data, options.fin, (_, buf) => {
-      if (this._socket.destroyed) {
-        const err = new Error(
-          'The socket was closed while data was being compressed'
-        );
-
-        if (typeof cb === 'function') cb(err);
-
-        for (let i = 0; i < this._queue.length; i++) {
-          const callback = this._queue[i][4];
-
-          if (typeof callback === 'function') callback(err);
-        }
-
-        return;
-      }
-
-      this._bufferedBytes -= data.length;
       this._deflating = false;
       options.readOnly = false;
@@ -369,5 +322,5 @@
 
       this._bufferedBytes -= params[1].length;
-      Reflect.apply(params[0], this, params.slice(1));
+      params[0].apply(this, params.slice(1));
     }
   }
@@ -388,5 +341,5 @@
    *
    * @param {Buffer[]} list The frame to send
-   * @param {Function} [cb] Callback
+   * @param {Function} cb Callback
    * @private
    */
Index: trip-planner-front/node_modules/ws/lib/stream.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/stream.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ 	(revision )
@@ -1,165 +1,0 @@
-'use strict';
-
-const { Duplex } = require('stream');
-
-/**
- * Emits the `'close'` event on a stream.
- *
- * @param {stream.Duplex} The stream.
- * @private
- */
-function emitClose(stream) {
-  stream.emit('close');
-}
-
-/**
- * The listener of the `'end'` event.
- *
- * @private
- */
-function duplexOnEnd() {
-  if (!this.destroyed && this._writableState.finished) {
-    this.destroy();
-  }
-}
-
-/**
- * The listener of the `'error'` event.
- *
- * @param {Error} err The error
- * @private
- */
-function duplexOnError(err) {
-  this.removeListener('error', duplexOnError);
-  this.destroy();
-  if (this.listenerCount('error') === 0) {
-    // Do not suppress the throwing behavior.
-    this.emit('error', err);
-  }
-}
-
-/**
- * Wraps a `WebSocket` in a duplex stream.
- *
- * @param {WebSocket} ws The `WebSocket` to wrap
- * @param {Object} [options] The options for the `Duplex` constructor
- * @return {stream.Duplex} The duplex stream
- * @public
- */
-function createWebSocketStream(ws, options) {
-  let resumeOnReceiverDrain = true;
-
-  function receiverOnDrain() {
-    if (resumeOnReceiverDrain) ws._socket.resume();
-  }
-
-  if (ws.readyState === ws.CONNECTING) {
-    ws.once('open', function open() {
-      ws._receiver.removeAllListeners('drain');
-      ws._receiver.on('drain', receiverOnDrain);
-    });
-  } else {
-    ws._receiver.removeAllListeners('drain');
-    ws._receiver.on('drain', receiverOnDrain);
-  }
-
-  const duplex = new Duplex({
-    ...options,
-    autoDestroy: false,
-    emitClose: false,
-    objectMode: false,
-    writableObjectMode: false
-  });
-
-  ws.on('message', function message(msg) {
-    if (!duplex.push(msg)) {
-      resumeOnReceiverDrain = false;
-      ws._socket.pause();
-    }
-  });
-
-  ws.once('error', function error(err) {
-    if (duplex.destroyed) return;
-
-    duplex.destroy(err);
-  });
-
-  ws.once('close', function close() {
-    if (duplex.destroyed) return;
-
-    duplex.push(null);
-  });
-
-  duplex._destroy = function (err, callback) {
-    if (ws.readyState === ws.CLOSED) {
-      callback(err);
-      process.nextTick(emitClose, duplex);
-      return;
-    }
-
-    let called = false;
-
-    ws.once('error', function error(err) {
-      called = true;
-      callback(err);
-    });
-
-    ws.once('close', function close() {
-      if (!called) callback(err);
-      process.nextTick(emitClose, duplex);
-    });
-    ws.terminate();
-  };
-
-  duplex._final = function (callback) {
-    if (ws.readyState === ws.CONNECTING) {
-      ws.once('open', function open() {
-        duplex._final(callback);
-      });
-      return;
-    }
-
-    // If the value of the `_socket` property is `null` it means that `ws` is a
-    // client websocket and the handshake failed. In fact, when this happens, a
-    // socket is never assigned to the websocket. Wait for the `'error'` event
-    // that will be emitted by the websocket.
-    if (ws._socket === null) return;
-
-    if (ws._socket._writableState.finished) {
-      callback();
-      if (duplex._readableState.endEmitted) duplex.destroy();
-    } else {
-      ws._socket.once('finish', function finish() {
-        // `duplex` is not destroyed here because the `'end'` event will be
-        // emitted on `duplex` after this `'finish'` event. The EOF signaling
-        // `null` chunk is, in fact, pushed when the websocket emits `'close'`.
-        callback();
-      });
-      ws.close();
-    }
-  };
-
-  duplex._read = function () {
-    if (ws.readyState === ws.OPEN && !resumeOnReceiverDrain) {
-      resumeOnReceiverDrain = true;
-      if (!ws._receiver._writableState.needDrain) ws._socket.resume();
-    }
-  };
-
-  duplex._write = function (chunk, encoding, callback) {
-    if (ws.readyState === ws.CONNECTING) {
-      ws.once('open', function open() {
-        duplex._write(chunk, encoding, callback);
-      });
-      return;
-    }
-
-    ws.send(chunk, callback);
-  };
-
-  duplex.on('end', duplexOnEnd);
-  duplex.on('error', duplexOnError);
-  return duplex;
-}
-
-module.exports = createWebSocketStream;
Index: trip-planner-front/node_modules/ws/lib/validation.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/validation.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/validation.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -1,3 +1,14 @@
 'use strict';
+
+try {
+  const isValidUTF8 = require('utf-8-validate');
+
+  exports.isValidUTF8 =
+    typeof isValidUTF8 === 'object'
+      ? isValidUTF8.Validation.isValidUTF8 // utf-8-validate@<3.0.0
+      : isValidUTF8;
+} catch (e) /* istanbul ignore next */ {
+  exports.isValidUTF8 = () => true;
+}
 
 /**
@@ -8,8 +19,8 @@
  * @public
  */
-function isValidStatusCode(code) {
+exports.isValidStatusCode = (code) => {
   return (
     (code >= 1000 &&
-      code <= 1014 &&
+      code <= 1013 &&
       code !== 1004 &&
       code !== 1005 &&
@@ -17,88 +28,3 @@
     (code >= 3000 && code <= 4999)
   );
-}
-
-/**
- * Checks if a given buffer contains only correct UTF-8.
- * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by
- * Markus Kuhn.
- *
- * @param {Buffer} buf The buffer to check
- * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`
- * @public
- */
-function _isValidUTF8(buf) {
-  const len = buf.length;
-  let i = 0;
-
-  while (i < len) {
-    if ((buf[i] & 0x80) === 0) {
-      // 0xxxxxxx
-      i++;
-    } else if ((buf[i] & 0xe0) === 0xc0) {
-      // 110xxxxx 10xxxxxx
-      if (
-        i + 1 === len ||
-        (buf[i + 1] & 0xc0) !== 0x80 ||
-        (buf[i] & 0xfe) === 0xc0 // Overlong
-      ) {
-        return false;
-      }
-
-      i += 2;
-    } else if ((buf[i] & 0xf0) === 0xe0) {
-      // 1110xxxx 10xxxxxx 10xxxxxx
-      if (
-        i + 2 >= len ||
-        (buf[i + 1] & 0xc0) !== 0x80 ||
-        (buf[i + 2] & 0xc0) !== 0x80 ||
-        (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong
-        (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)
-      ) {
-        return false;
-      }
-
-      i += 3;
-    } else if ((buf[i] & 0xf8) === 0xf0) {
-      // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-      if (
-        i + 3 >= len ||
-        (buf[i + 1] & 0xc0) !== 0x80 ||
-        (buf[i + 2] & 0xc0) !== 0x80 ||
-        (buf[i + 3] & 0xc0) !== 0x80 ||
-        (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong
-        (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||
-        buf[i] > 0xf4 // > U+10FFFF
-      ) {
-        return false;
-      }
-
-      i += 4;
-    } else {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-try {
-  let isValidUTF8 = require('utf-8-validate');
-
-  /* istanbul ignore if */
-  if (typeof isValidUTF8 === 'object') {
-    isValidUTF8 = isValidUTF8.Validation.isValidUTF8; // utf-8-validate@<3.0.0
-  }
-
-  module.exports = {
-    isValidStatusCode,
-    isValidUTF8(buf) {
-      return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf);
-    }
-  };
-} catch (e) /* istanbul ignore next */ {
-  module.exports = {
-    isValidStatusCode,
-    isValidUTF8: _isValidUTF8
-  };
-}
+};
Index: trip-planner-front/node_modules/ws/lib/websocket-server.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/websocket-server.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/websocket-server.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -2,11 +2,11 @@
 
 const EventEmitter = require('events');
-const { createHash } = require('crypto');
-const { createServer, STATUS_CODES } = require('http');
+const crypto = require('crypto');
+const http = require('http');
 
 const PerMessageDeflate = require('./permessage-deflate');
+const extension = require('./extension');
 const WebSocket = require('./websocket');
-const { format, parse } = require('./extension');
-const { GUID, kWebSocket } = require('./constants');
+const { GUID } = require('./constants');
 
 const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
@@ -22,38 +22,39 @@
    *
    * @param {Object} options Configuration options
-   * @param {Number} [options.backlog=511] The maximum length of the queue of
-   *     pending connections
-   * @param {Boolean} [options.clientTracking=true] Specifies whether or not to
-   *     track clients
-   * @param {Function} [options.handleProtocols] A hook to handle protocols
-   * @param {String} [options.host] The hostname where to bind the server
-   * @param {Number} [options.maxPayload=104857600] The maximum allowed message
-   *     size
-   * @param {Boolean} [options.noServer=false] Enable no server mode
-   * @param {String} [options.path] Accept only connections matching this path
-   * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable
+   * @param {Number} options.backlog The maximum length of the queue of pending
+   *     connections
+   * @param {Boolean} options.clientTracking Specifies whether or not to track
+   *     clients
+   * @param {Function} options.handleProtocols An hook to handle protocols
+   * @param {String} options.host The hostname where to bind the server
+   * @param {Number} options.maxPayload The maximum allowed message size
+   * @param {Boolean} options.noServer Enable no server mode
+   * @param {String} options.path Accept only connections matching this path
+   * @param {(Boolean|Object)} options.perMessageDeflate Enable/disable
    *     permessage-deflate
-   * @param {Number} [options.port] The port where to bind the server
-   * @param {http.Server} [options.server] A pre-created HTTP/S server to use
-   * @param {Function} [options.verifyClient] A hook to reject connections
-   * @param {Function} [callback] A listener for the `listening` event
+   * @param {Number} options.port The port where to bind the server
+   * @param {http.Server} options.server A pre-created HTTP/S server to use
+   * @param {Function} options.verifyClient An hook to reject connections
+   * @param {Function} callback A listener for the `listening` event
    */
   constructor(options, callback) {
     super();
 
-    options = {
-      maxPayload: 100 * 1024 * 1024,
-      perMessageDeflate: false,
-      handleProtocols: null,
-      clientTracking: true,
-      verifyClient: null,
-      noServer: false,
-      backlog: null, // use default (511 as implemented in net.js)
-      server: null,
-      host: null,
-      path: null,
-      port: null,
-      ...options
-    };
+    options = Object.assign(
+      {
+        maxPayload: 100 * 1024 * 1024,
+        perMessageDeflate: false,
+        handleProtocols: null,
+        clientTracking: true,
+        verifyClient: null,
+        noServer: false,
+        backlog: null, // use default (511 as implemented in net.js)
+        server: null,
+        host: null,
+        path: null,
+        port: null
+      },
+      options
+    );
 
     if (options.port == null && !options.server && !options.noServer) {
@@ -64,6 +65,6 @@
 
     if (options.port != null) {
-      this._server = createServer((req, res) => {
-        const body = STATUS_CODES[426];
+      this._server = http.createServer((req, res) => {
+        const body = http.STATUS_CODES[426];
 
         res.writeHead(426, {
@@ -84,11 +85,11 @@
 
     if (this._server) {
-      const emitConnection = this.emit.bind(this, 'connection');
-
       this._removeListeners = addListeners(this._server, {
         listening: this.emit.bind(this, 'listening'),
         error: this.emit.bind(this, 'error'),
         upgrade: (req, socket, head) => {
-          this.handleUpgrade(req, socket, head, emitConnection);
+          this.handleUpgrade(req, socket, head, (ws) => {
+            this.emit('connection', ws, req);
+          });
         }
       });
@@ -121,5 +122,5 @@
    * Close the server.
    *
-   * @param {Function} [cb] Callback
+   * @param {Function} cb Callback
    * @public
    */
@@ -208,5 +209,5 @@
 
       try {
-        const offers = parse(req.headers['sec-websocket-extensions']);
+        const offers = extension.parse(req.headers['sec-websocket-extensions']);
 
         if (offers[PerMessageDeflate.extensionName]) {
@@ -226,5 +227,5 @@
         origin:
           req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
-        secure: !!(req.socket.authorized || req.socket.encrypted),
+        secure: !!(req.connection.authorized || req.connection.encrypted),
         req
       };
@@ -256,5 +257,4 @@
    * @param {Buffer} head The first packet of the upgraded stream
    * @param {Function} cb Callback
-   * @throws {Error} If called more than once with the same socket
    * @private
    */
@@ -265,12 +265,6 @@
     if (!socket.readable || !socket.writable) return socket.destroy();
 
-    if (socket[kWebSocket]) {
-      throw new Error(
-        'server.handleUpgrade() was called more than once with the same ' +
-          'socket, possibly due to a misconfiguration'
-      );
-    }
-
-    const digest = createHash('sha1')
+    const digest = crypto
+      .createHash('sha1')
       .update(key + GUID)
       .digest('base64');
@@ -284,5 +278,5 @@
 
     const ws = new WebSocket(null);
-    let protocol = req.headers['sec-websocket-protocol'];
+    var protocol = req.headers['sec-websocket-protocol'];
 
     if (protocol) {
@@ -300,5 +294,5 @@
       if (protocol) {
         headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
-        ws._protocol = protocol;
+        ws.protocol = protocol;
       }
     }
@@ -306,5 +300,5 @@
     if (extensions[PerMessageDeflate.extensionName]) {
       const params = extensions[PerMessageDeflate.extensionName].params;
-      const value = format({
+      const value = extension.format({
         [PerMessageDeflate.extensionName]: [params]
       });
@@ -328,5 +322,5 @@
     }
 
-    cb(ws, req);
+    cb(ws);
   }
 }
@@ -340,6 +334,5 @@
  * @param {EventEmitter} server The event emitter
  * @param {Object.<String, Function>} map The listeners to add
- * @return {Function} A function that will remove the added listeners when
- *     called
+ * @return {Function} A function that will remove the added listeners when called
  * @private
  */
@@ -384,14 +377,16 @@
 function abortHandshake(socket, code, message, headers) {
   if (socket.writable) {
-    message = message || STATUS_CODES[code];
-    headers = {
-      Connection: 'close',
-      'Content-Type': 'text/html',
-      'Content-Length': Buffer.byteLength(message),
-      ...headers
-    };
+    message = message || http.STATUS_CODES[code];
+    headers = Object.assign(
+      {
+        Connection: 'close',
+        'Content-type': 'text/html',
+        'Content-Length': Buffer.byteLength(message)
+      },
+      headers
+    );
 
     socket.write(
-      `HTTP/1.1 ${code} ${STATUS_CODES[code]}\r\n` +
+      `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
         Object.keys(headers)
           .map((h) => `${h}: ${headers[h]}`)
Index: trip-planner-front/node_modules/ws/lib/websocket.js
===================================================================
--- trip-planner-front/node_modules/ws/lib/websocket.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/ws/lib/websocket.js	(revision bdd64917749115bbdd228a9569a675d590c112e3)
@@ -2,12 +2,14 @@
 
 const EventEmitter = require('events');
+const crypto = require('crypto');
 const https = require('https');
 const http = require('http');
 const net = require('net');
 const tls = require('tls');
-const { randomBytes, createHash } = require('crypto');
-const { URL } = require('url');
+const url = require('url');
 
 const PerMessageDeflate = require('./permessage-deflate');
+const EventTarget = require('./event-target');
+const extension = require('./extension');
 const Receiver = require('./receiver');
 const Sender = require('./sender');
@@ -20,7 +22,4 @@
   NOOP
 } = require('./constants');
-const { addEventListener, removeEventListener } = require('./event-target');
-const { format, parse } = require('./extension');
-const { toBuffer } = require('./buffer-util');
 
 const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
@@ -37,20 +36,21 @@
    * Create a new `WebSocket`.
    *
-   * @param {(String|url.URL)} address The URL to which to connect
-   * @param {(String|String[])} [protocols] The subprotocols
-   * @param {Object} [options] Connection options
+   * @param {(String|url.Url|url.URL)} address The URL to which to connect
+   * @param {(String|String[])} protocols The subprotocols
+   * @param {Object} options Connection options
    */
   constructor(address, protocols, options) {
     super();
 
+    this.readyState = WebSocket.CONNECTING;
+    this.protocol = '';
+
     this._binaryType = BINARY_TYPES[0];
-    this._closeCode = 1006;
     this._closeFrameReceived = false;
     this._closeFrameSent = false;
     this._closeMessage = '';
     this._closeTimer = null;
+    this._closeCode = 1006;
     this._extensions = {};
-    this._protocol = '';
-    this._readyState = WebSocket.CONNECTING;
     this._receiver = null;
     this._sender = null;
@@ -58,5 +58,4 @@
 
     if (address !== null) {
-      this._bufferedAmount = 0;
       this._isServer = false;
       this._redirects = 0;
@@ -75,4 +74,17 @@
   }
 
+  get CONNECTING() {
+    return WebSocket.CONNECTING;
+  }
+  get CLOSING() {
+    return WebSocket.CLOSING;
+  }
+  get CLOSED() {
+    return WebSocket.CLOSED;
+  }
+  get OPEN() {
+    return WebSocket.OPEN;
+  }
+
   /**
    * This deviates from the WHATWG interface since ws doesn't support the
@@ -101,7 +113,10 @@
    */
   get bufferedAmount() {
-    if (!this._socket) return this._bufferedAmount;
-
-    return this._socket._writableState.length + this._sender._bufferedBytes;
+    if (!this._socket) return 0;
+
+    //
+    // `socket.bufferSize` is `undefined` if the socket is closed.
+    //
+    return (this._socket.bufferSize || 0) + this._sender._bufferedBytes;
   }
 
@@ -114,37 +129,15 @@
 
   /**
-   * @type {String}
-   */
-  get protocol() {
-    return this._protocol;
-  }
-
-  /**
-   * @type {Number}
-   */
-  get readyState() {
-    return this._readyState;
-  }
-
-  /**
-   * @type {String}
-   */
-  get url() {
-    return this._url;
-  }
-
-  /**
    * Set up the socket and the internal resources.
    *
    * @param {net.Socket} socket The network socket between the server and client
    * @param {Buffer} head The first packet of the upgraded stream
-   * @param {Number} [maxPayload=0] The maximum allowed message size
+   * @param {Number} maxPayload The maximum allowed message size
    * @private
    */
   setSocket(socket, head, maxPayload) {
     const receiver = new Receiver(
-      this.binaryType,
+      this._binaryType,
       this._extensions,
-      this._isServer,
       maxPayload
     );
@@ -174,5 +167,5 @@
     socket.on('error', socketOnError);
 
-    this._readyState = WebSocket.OPEN;
+    this.readyState = WebSocket.OPEN;
     this.emit('open');
   }
@@ -184,6 +177,7 @@
    */
   emitClose() {
+    this.readyState = WebSocket.CLOSED;
+
     if (!this._socket) {
-      this._readyState = WebSocket.CLOSED;
       this.emit('close', this._closeCode, this._closeMessage);
       return;
@@ -195,5 +189,4 @@
 
     this._receiver.removeAllListeners();
-    this._readyState = WebSocket.CLOSED;
     this.emit('close', this._closeCode, this._closeMessage);
   }
@@ -214,6 +207,6 @@
    *              +---+
    *
-   * @param {Number} [code] Status code explaining why the connection is closing
-   * @param {String} [data] A string explaining why the connection is closing
+   * @param {Number} code Status code explaining why the connection is closing
+   * @param {String} data A string explaining why the connection is closing
    * @public
    */
@@ -230,5 +223,5 @@
     }
 
-    this._readyState = WebSocket.CLOSING;
+    this.readyState = WebSocket.CLOSING;
     this._sender.close(code, data, !this._isServer, (err) => {
       //
@@ -254,14 +247,10 @@
    * Send a ping.
    *
-   * @param {*} [data] The data to send
-   * @param {Boolean} [mask] Indicates whether or not to mask `data`
-   * @param {Function} [cb] Callback which is executed when the ping is sent
+   * @param {*} data The data to send
+   * @param {Boolean} mask Indicates whether or not to mask `data`
+   * @param {Function} cb Callback which is executed when the ping is sent
    * @public
    */
   ping(data, mask, cb) {
-    if (this.readyState === WebSocket.CONNECTING) {
-      throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
-    }
-
     if (typeof data === 'function') {
       cb = data;
@@ -272,11 +261,15 @@
     }
 
+    if (this.readyState !== WebSocket.OPEN) {
+      const err = new Error(
+        `WebSocket is not open: readyState ${this.readyState} ` +
+          `(${readyStates[this.readyState]})`
+      );
+
+      if (cb) return cb(err);
+      throw err;
+    }
+
     if (typeof data === 'number') data = data.toString();
-
-    if (this.readyState !== WebSocket.OPEN) {
-      sendAfterClose(this, data, cb);
-      return;
-    }
-
     if (mask === undefined) mask = !this._isServer;
     this._sender.ping(data || EMPTY_BUFFER, mask, cb);
@@ -286,14 +279,10 @@
    * Send a pong.
    *
-   * @param {*} [data] The data to send
-   * @param {Boolean} [mask] Indicates whether or not to mask `data`
-   * @param {Function} [cb] Callback which is executed when the pong is sent
+   * @param {*} data The data to send
+   * @param {Boolean} mask Indicates whether or not to mask `data`
+   * @param {Function} cb Callback which is executed when the pong is sent
    * @public
    */
   pong(data, mask, cb) {
-    if (this.readyState === WebSocket.CONNECTING) {
-      throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
-    }
-
     if (typeof data === 'function') {
       cb = data;
@@ -304,11 +293,15 @@
     }
 
+    if (this.readyState !== WebSocket.OPEN) {
+      const err = new Error(
+        `WebSocket is not open: readyState ${this.readyState} ` +
+          `(${readyStates[this.readyState]})`
+      );
+
+      if (cb) return cb(err);
+      throw err;
+    }
+
     if (typeof data === 'number') data = data.toString();
-
-    if (this.readyState !== WebSocket.OPEN) {
-      sendAfterClose(this, data, cb);
-      return;
-    }
-
     if (mask === undefined) mask = !this._isServer;
     this._sender.pong(data || EMPTY_BUFFER, mask, cb);
@@ -319,20 +312,13 @@
    *
    * @param {*} data The message to send
-   * @param {Object} [options] Options object
-   * @param {Boolean} [options.compress] Specifies whether or not to compress
-   *     `data`
-   * @param {Boolean} [options.binary] Specifies whether `data` is binary or
-   *     text
-   * @param {Boolean} [options.fin=true] Specifies whether the fragment is the
-   *     last one
-   * @param {Boolean} [options.mask] Specifies whether or not to mask `data`
-   * @param {Function} [cb] Callback which is executed when data is written out
+   * @param {Object} options Options object
+   * @param {Boolean} options.compress Specifies whether or not to compress `data`
+   * @param {Boolean} options.binary Specifies whether `data` is binary or text
+   * @param {Boolean} options.fin Specifies whether the fragment is the last one
+   * @param {Boolean} options.mask Specifies whether or not to mask `data`
+   * @param {Function} cb Callback which is executed when data is written out
    * @public
    */
   send(data, options, cb) {
-    if (this.readyState === WebSocket.CONNECTING) {
-      throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
-    }
-
     if (typeof options === 'function') {
       cb = options;
@@ -340,18 +326,25 @@
     }
 
+    if (this.readyState !== WebSocket.OPEN) {
+      const err = new Error(
+        `WebSocket is not open: readyState ${this.readyState} ` +
+          `(${readyStates[this.readyState]})`
+      );
+
+      if (cb) return cb(err);
+      throw err;
+    }
+
     if (typeof data === 'number') data = data.toString();
 
-    if (this.readyState !== WebSocket.OPEN) {
-      sendAfterClose(this, data, cb);
-      return;
-    }
-
-    const opts = {
-      binary: typeof data !== 'string',
-      mask: !this._isServer,
-      compress: true,
-      fin: true,
-      ...options
-    };
+    const opts = Object.assign(
+      {
+        binary: typeof data !== 'string',
+        mask: !this._isServer,
+        compress: true,
+        fin: true
+      },
+      options
+    );
 
     if (!this._extensions[PerMessageDeflate.extensionName]) {
@@ -375,5 +368,5 @@
 
     if (this._socket) {
-      this._readyState = WebSocket.CLOSING;
+      this.readyState = WebSocket.CLOSING;
       this._socket.destroy();
     }
@@ -382,19 +375,5 @@
 
 readyStates.forEach((readyState, i) => {
-  const descriptor = { enumerable: true, value: i };
-
-  Object.defineProperty(WebSocket.prototype, readyState, descriptor);
-  Object.defineProperty(WebSocket, readyState, descriptor);
-});
-
-[
-  'binaryType',
-  'bufferedAmount',
-  'extensions',
-  'protocol',
-  'readyState',
-  'url'
-].forEach((property) => {
-  Object.defineProperty(WebSocket.prototype, property, { enumerable: true });
+  WebSocket[readyState] = i;
 });
 
@@ -405,6 +384,4 @@
 ['open', 'error', 'close', 'message'].forEach((method) => {
   Object.defineProperty(WebSocket.prototype, `on${method}`, {
-    configurable: true,
-    enumerable: true,
     /**
      * Return the listener of the event.
@@ -415,5 +392,5 @@
     get() {
       const listeners = this.listeners(method);
-      for (let i = 0; i < listeners.length; i++) {
+      for (var i = 0; i < listeners.length; i++) {
         if (listeners[i]._listener) return listeners[i]._listener;
       }
@@ -429,5 +406,5 @@
     set(listener) {
       const listeners = this.listeners(method);
-      for (let i = 0; i < listeners.length; i++) {
+      for (var i = 0; i < listeners.length; i++) {
         //
         // Remove only the listeners added via `addEventListener`.
@@ -440,6 +417,6 @@
 });
 
-WebSocket.prototype.addEventListener = addEventListener;
-WebSocket.prototype.removeEventListener = removeEventListener;
+WebSocket.prototype.addEventListener = EventTarget.addEventListener;
+WebSocket.prototype.removeEventListener = EventTarget.removeEventListener;
 
 module.exports = WebSocket;
@@ -449,41 +426,43 @@
  *
  * @param {WebSocket} websocket The client to initialize
- * @param {(String|url.URL)} address The URL to which to connect
- * @param {String} [protocols] The subprotocols
- * @param {Object} [options] Connection options
- * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable
+ * @param {(String|url.Url|url.URL)} address The URL to which to connect
+ * @param {String} protocols The subprotocols
+ * @param {Object} options Connection options
+ * @param {(Boolean|Object)} options.perMessageDeflate Enable/disable
  *     permessage-deflate
- * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the
+ * @param {Number} options.handshakeTimeout Timeout in milliseconds for the
  *     handshake request
- * @param {Number} [options.protocolVersion=13] Value of the
- *     `Sec-WebSocket-Version` header
- * @param {String} [options.origin] Value of the `Origin` or
+ * @param {Number} options.protocolVersion Value of the `Sec-WebSocket-Version`
+ *     header
+ * @param {String} options.origin Value of the `Origin` or
  *     `Sec-WebSocket-Origin` header
- * @param {Number} [options.maxPayload=104857600] The maximum allowed message
- *     size
- * @param {Boolean} [options.followRedirects=false] Whether or not to follow
- *     redirects
- * @param {Number} [options.maxRedirects=10] The maximum number of redirects
- *     allowed
+ * @param {Number} options.maxPayload The maximum allowed message size
+ * @param {Boolean} options.followRedirects Whether or not to follow redirects
+ * @param {Number} options.maxRedirects The maximum number of redirects allowed
  * @private
  */
 function initAsClient(websocket, address, protocols, options) {
-  const opts = {
-    protocolVersion: protocolVersions[1],
-    maxPayload: 100 * 1024 * 1024,
-    perMessageDeflate: true,
-    followRedirects: false,
-    maxRedirects: 10,
-    ...options,
-    createConnection: undefined,
-    socketPath: undefined,
-    hostname: undefined,
-    protocol: undefined,
-    timeout: undefined,
-    method: undefined,
-    host: undefined,
-    path: undefined,
-    port: undefined
-  };
+  const opts = Object.assign(
+    {
+      protocolVersion: protocolVersions[1],
+      maxPayload: 100 * 1024 * 1024,
+      perMessageDeflate: true,
+      followRedirects: false,
+      maxRedirects: 10
+    },
+    options,
+    {
+      createConnection: undefined,
+      socketPath: undefined,
+      hostname: undefined,
+      protocol: undefined,
+      timeout: undefined,
+      method: undefined,
+      auth: undefined,
+      host: undefined,
+      path: undefined,
+      port: undefined
+    }
+  );
 
   if (!protocolVersions.includes(opts.protocolVersion)) {
@@ -494,12 +473,15 @@
   }
 
-  let parsedUrl;
-
-  if (address instanceof URL) {
+  var parsedUrl;
+
+  if (typeof address === 'object' && address.href !== undefined) {
     parsedUrl = address;
-    websocket._url = address.href;
+    websocket.url = address.href;
   } else {
-    parsedUrl = new URL(address);
-    websocket._url = address;
+    //
+    // The WHATWG URL constructor is not available on Node.js < 6.13.0
+    //
+    parsedUrl = url.URL ? new url.URL(address) : url.parse(address);
+    websocket.url = address;
   }
 
@@ -513,7 +495,10 @@
     parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
   const defaultPort = isSecure ? 443 : 80;
-  const key = randomBytes(16).toString('base64');
+  const key = crypto.randomBytes(16).toString('base64');
   const get = isSecure ? https.get : http.get;
-  let perMessageDeflate;
+  const path = parsedUrl.search
+    ? `${parsedUrl.pathname || '/'}${parsedUrl.search}`
+    : parsedUrl.pathname || '/';
+  var perMessageDeflate;
 
   opts.createConnection = isSecure ? tlsConnect : netConnect;
@@ -523,12 +508,14 @@
     ? parsedUrl.hostname.slice(1, -1)
     : parsedUrl.hostname;
-  opts.headers = {
-    'Sec-WebSocket-Version': opts.protocolVersion,
-    'Sec-WebSocket-Key': key,
-    Connection: 'Upgrade',
-    Upgrade: 'websocket',
-    ...opts.headers
-  };
-  opts.path = parsedUrl.pathname + parsedUrl.search;
+  opts.headers = Object.assign(
+    {
+      'Sec-WebSocket-Version': opts.protocolVersion,
+      'Sec-WebSocket-Key': key,
+      Connection: 'Upgrade',
+      Upgrade: 'websocket'
+    },
+    opts.headers
+  );
+  opts.path = path;
   opts.timeout = opts.handshakeTimeout;
 
@@ -539,5 +526,5 @@
       opts.maxPayload
     );
-    opts.headers['Sec-WebSocket-Extensions'] = format({
+    opts.headers['Sec-WebSocket-Extensions'] = extension.format({
       [PerMessageDeflate.extensionName]: perMessageDeflate.offer()
     });
@@ -553,10 +540,12 @@
     }
   }
-  if (parsedUrl.username || parsedUrl.password) {
+  if (parsedUrl.auth) {
+    opts.auth = parsedUrl.auth;
+  } else if (parsedUrl.username || parsedUrl.password) {
     opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
   }
 
   if (isUnixSocket) {
-    const parts = opts.path.split(':');
+    const parts = path.split(':');
 
     opts.socketPath = parts[0];
@@ -564,5 +553,5 @@
   }
 
-  let req = (websocket._req = get(opts));
+  var req = (websocket._req = get(opts));
 
   if (opts.timeout) {
@@ -573,8 +562,8 @@
 
   req.on('error', (err) => {
-    if (req === null || req.aborted) return;
+    if (websocket._req.aborted) return;
 
     req = websocket._req = null;
-    websocket._readyState = WebSocket.CLOSING;
+    websocket.readyState = WebSocket.CLOSING;
     websocket.emit('error', err);
     websocket.emitClose();
@@ -598,5 +587,7 @@
       req.abort();
 
-      const addr = new URL(location, address);
+      const addr = url.URL
+        ? new url.URL(location, address)
+        : url.resolve(address, location);
 
       initAsClient(websocket, addr, protocols, options);
@@ -621,5 +612,6 @@
     req = websocket._req = null;
 
-    const digest = createHash('sha1')
+    const digest = crypto
+      .createHash('sha1')
       .update(key + GUID)
       .digest('base64');
@@ -632,5 +624,5 @@
     const serverProt = res.headers['sec-websocket-protocol'];
     const protList = (protocols || '').split(/, */);
-    let protError;
+    var protError;
 
     if (!protocols && serverProt) {
@@ -647,14 +639,17 @@
     }
 
-    if (serverProt) websocket._protocol = serverProt;
+    if (serverProt) websocket.protocol = serverProt;
 
     if (perMessageDeflate) {
       try {
-        const extensions = parse(res.headers['sec-websocket-extensions']);
+        const extensions = extension.parse(
+          res.headers['sec-websocket-extensions']
+        );
 
         if (extensions[PerMessageDeflate.extensionName]) {
           perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
-          websocket._extensions[PerMessageDeflate.extensionName] =
-            perMessageDeflate;
+          websocket._extensions[
+            PerMessageDeflate.extensionName
+          ] = perMessageDeflate;
         }
       } catch (err) {
@@ -680,5 +675,11 @@
  */
 function netConnect(options) {
-  options.path = options.socketPath;
+  //
+  // Override `options.path` only if `options` is a copy of the original options
+  // object. This is always true on Node.js >= 8 but not on Node.js 6 where
+  // `options.socketPath` might be `undefined` even if the `socketPath` option
+  // was originally set.
+  //
+  if (options.protocolVersion) options.path = options.socketPath;
   return net.connect(options);
 }
@@ -693,9 +694,5 @@
 function tlsConnect(options) {
   options.path = undefined;
-
-  if (!options.servername && options.servername !== '') {
-    options.servername = net.isIP(options.host) ? '' : options.host;
-  }
-
+  options.servername = options.servername || options.host;
   return tls.connect(options);
 }
@@ -711,5 +708,5 @@
  */
 function abortHandshake(websocket, stream, message) {
-  websocket._readyState = WebSocket.CLOSING;
+  websocket.readyState = WebSocket.CLOSING;
 
   const err = new Error(message);
@@ -718,14 +715,4 @@
   if (stream.setHeader) {
     stream.abort();
-
-    if (stream.socket && !stream.socket.destroyed) {
-      //
-      // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if
-      // called after the request completed. See
-      // https://github.com/websockets/ws/issues/1869.
-      //
-      stream.socket.destroy();
-    }
-
     stream.once('abort', websocket.emitClose.bind(websocket));
     websocket.emit('error', err);
@@ -738,36 +725,4 @@
 
 /**
- * Handle cases where the `ping()`, `pong()`, or `send()` methods are called
- * when the `readyState` attribute is `CLOSING` or `CLOSED`.
- *
- * @param {WebSocket} websocket The WebSocket instance
- * @param {*} [data] The data to send
- * @param {Function} [cb] Callback
- * @private
- */
-function sendAfterClose(websocket, data, cb) {
-  if (data) {
-    const length = toBuffer(data).length;
-
-    //
-    // The `_bufferedAmount` property is used only when the peer is a client and
-    // the opening handshake fails. Under these circumstances, in fact, the
-    // `setSocket()` method is not called, so the `_socket` and `_sender`
-    // properties are set to `null`.
-    //
-    if (websocket._socket) websocket._sender._bufferedBytes += length;
-    else websocket._bufferedAmount += length;
-  }
-
-  if (cb) {
-    const err = new Error(
-      `WebSocket is not open: readyState ${websocket.readyState} ` +
-        `(${readyStates[websocket.readyState]})`
-    );
-    cb(err);
-  }
-}
-
-/**
  * The listener of the `Receiver` `'conclude'` event.
  *
@@ -810,5 +765,5 @@
   websocket._socket.removeListener('data', socketOnData);
 
-  websocket._readyState = WebSocket.CLOSING;
+  websocket.readyState = WebSocket.CLOSING;
   websocket._closeCode = err[kStatusCode];
   websocket.emit('error', err);
@@ -869,5 +824,5 @@
   this.removeListener('end', socketOnEnd);
 
-  websocket._readyState = WebSocket.CLOSING;
+  websocket.readyState = WebSocket.CLOSING;
 
   //
@@ -920,5 +875,5 @@
   const websocket = this[kWebSocket];
 
-  websocket._readyState = WebSocket.CLOSING;
+  websocket.readyState = WebSocket.CLOSING;
   websocket._receiver.end();
   this.end();
@@ -936,7 +891,5 @@
   this.on('error', NOOP);
 
-  if (websocket) {
-    websocket._readyState = WebSocket.CLOSING;
-    this.destroy();
-  }
-}
+  websocket.readyState = WebSocket.CLOSING;
+  this.destroy();
+}
