Index: frontend/node_modules/@leichtgewicht/ip-codec/LICENSE
===================================================================
--- frontend/node_modules/@leichtgewicht/ip-codec/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@leichtgewicht/ip-codec/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Martin Heidegger
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Index: frontend/node_modules/@leichtgewicht/ip-codec/Readme.md
===================================================================
--- frontend/node_modules/@leichtgewicht/ip-codec/Readme.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@leichtgewicht/ip-codec/Readme.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,69 @@
+# @leichtgewicht/ip-codec
+
+Small package to encode or decode IP addresses from buffers to strings.
+Supports IPV4 and IPV6.
+
+## Usage
+
+The basics are straigthforward
+
+```js
+import { encode, decode, sizeOf, familyOf } from '@leichtgewicht/ip-codec'
+
+const uint8Array = encode("127.0.0.1")
+const str = decode(uint8Array)
+
+try {
+  switch sizeOf(str) {
+    case 4: // IPv4
+    case 16: // IPv6
+  }
+  switch familyOf(str) {
+    case: 1: // IPv4
+    case: 2: // IPv6
+  }
+} catch (err) {
+  // Invalid IP
+}
+```
+
+By default the library will work with Uint8Array's but you can bring your own buffer:
+
+```js
+const buf = Buffer.alloc(4)
+encode('127.0.0.1', buf)
+```
+
+It is also possible to de-encode at a location inside a given buffer
+
+```js
+const buf = Buffer.alloc(10)
+encode('127.0.0.1', buf, 4)
+```
+
+Allocation of a buffer may be difficult if you don't know what type the buffer:
+you can pass in a generator to allocate it for you:
+
+```js
+encode('127.0.0.1', Buffer.alloc)
+```
+
+You can also de/encode ipv4 or ipv6 specifically:
+
+```js
+import { v4, v6 } from '@leichtgewicht/ip-codec'
+
+v4.decode(v4.encode('127.0.0.1'))
+v6.decode(v6.encode('::'))
+```
+
+## History
+
+The code in this package was originally extracted from [node-ip](https://github.com/indutny/node-ip) and since improved.
+
+Notable changes are the removal of the `Buffer` dependency and better support for detection of
+formats and allocation of buffers.
+
+## License
+
+[MIT](./LICENSE)
Index: frontend/node_modules/@leichtgewicht/ip-codec/index.cjs
===================================================================
--- frontend/node_modules/@leichtgewicht/ip-codec/index.cjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@leichtgewicht/ip-codec/index.cjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,250 @@
+// GENERATED FILE. DO NOT EDIT.
+var ipCodec = (function(exports) {
+  "use strict";
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.decode = decode;
+  exports.encode = encode;
+  exports.familyOf = familyOf;
+  exports.name = void 0;
+  exports.sizeOf = sizeOf;
+  exports.v6 = exports.v4 = void 0;
+  const v4Regex = /^(\d{1,3}\.){3,3}\d{1,3}$/;
+  const v4Size = 4;
+  const v6Regex = /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i;
+  const v6Size = 16;
+  const v4 = {
+    name: 'v4',
+    size: v4Size,
+    isFormat: ip => v4Regex.test(ip),
+  
+    encode(ip, buff, offset) {
+      offset = ~~offset;
+      buff = buff || new Uint8Array(offset + v4Size);
+      const max = ip.length;
+      let n = 0;
+  
+      for (let i = 0; i < max;) {
+        const c = ip.charCodeAt(i++);
+  
+        if (c === 46) {
+          // "."
+          buff[offset++] = n;
+          n = 0;
+        } else {
+          n = n * 10 + (c - 48);
+        }
+      }
+  
+      buff[offset] = n;
+      return buff;
+    },
+  
+    decode(buff, offset) {
+      offset = ~~offset;
+      return `${buff[offset++]}.${buff[offset++]}.${buff[offset++]}.${buff[offset]}`;
+    }
+  
+  };
+  exports.v4 = v4;
+  const v6 = {
+    name: 'v6',
+    size: v6Size,
+    isFormat: ip => ip.length > 0 && v6Regex.test(ip),
+  
+    encode(ip, buff, offset) {
+      offset = ~~offset;
+      let end = offset + v6Size;
+      let fill = -1;
+      let hexN = 0;
+      let decN = 0;
+      let prevColon = true;
+      let useDec = false;
+      buff = buff || new Uint8Array(offset + v6Size); // Note: This algorithm needs to check if the offset
+      // could exceed the buffer boundaries as it supports
+      // non-standard compliant encodings that may go beyond
+      // the boundary limits. if (offset < end) checks should
+      // not be necessary...
+  
+      for (let i = 0; i < ip.length; i++) {
+        let c = ip.charCodeAt(i);
+  
+        if (c === 58) {
+          // :
+          if (prevColon) {
+            if (fill !== -1) {
+              // Not Standard! (standard doesn't allow multiple ::)
+              // We need to treat
+              if (offset < end) buff[offset] = 0;
+              if (offset < end - 1) buff[offset + 1] = 0;
+              offset += 2;
+            } else if (offset < end) {
+              // :: in the middle
+              fill = offset;
+            }
+          } else {
+            // : ends the previous number
+            if (useDec === true) {
+              // Non-standard! (ipv4 should be at end only)
+              // A ipv4 address should not be found anywhere else but at
+              // the end. This codec also support putting characters
+              // after the ipv4 address..
+              if (offset < end) buff[offset] = decN;
+              offset++;
+            } else {
+              if (offset < end) buff[offset] = hexN >> 8;
+              if (offset < end - 1) buff[offset + 1] = hexN & 0xff;
+              offset += 2;
+            }
+  
+            hexN = 0;
+            decN = 0;
+          }
+  
+          prevColon = true;
+          useDec = false;
+        } else if (c === 46) {
+          // . indicates IPV4 notation
+          if (offset < end) buff[offset] = decN;
+          offset++;
+          decN = 0;
+          hexN = 0;
+          prevColon = false;
+          useDec = true;
+        } else {
+          prevColon = false;
+  
+          if (c >= 97) {
+            c -= 87; // a-f ... 97~102 -87 => 10~15
+          } else if (c >= 65) {
+            c -= 55; // A-F ... 65~70 -55 => 10~15
+          } else {
+            c -= 48; // 0-9 ... starting from charCode 48
+  
+            decN = decN * 10 + c;
+          } // We don't know yet if its a dec or hex number
+  
+  
+          hexN = (hexN << 4) + c;
+        }
+      }
+  
+      if (prevColon === false) {
+        // Commiting last number
+        if (useDec === true) {
+          if (offset < end) buff[offset] = decN;
+          offset++;
+        } else {
+          if (offset < end) buff[offset] = hexN >> 8;
+          if (offset < end - 1) buff[offset + 1] = hexN & 0xff;
+          offset += 2;
+        }
+      } else if (fill === 0) {
+        // Not Standard! (standard doesn't allow multiple ::)
+        // This means that a : was found at the start AND end which means the
+        // end needs to be treated as 0 entry...
+        if (offset < end) buff[offset] = 0;
+        if (offset < end - 1) buff[offset + 1] = 0;
+        offset += 2;
+      } else if (fill !== -1) {
+        // Non-standard! (standard doens't allow multiple ::)
+        // Here we find that there has been a :: somewhere in the middle
+        // and the end. To treat the end with priority we need to move all
+        // written data two bytes to the right.
+        offset += 2;
+  
+        for (let i = Math.min(offset - 1, end - 1); i >= fill + 2; i--) {
+          buff[i] = buff[i - 2];
+        }
+  
+        buff[fill] = 0;
+        buff[fill + 1] = 0;
+        fill = offset;
+      }
+  
+      if (fill !== offset && fill !== -1) {
+        // Move the written numbers to the end while filling the everything
+        // "fill" to the bytes with zeros.
+        if (offset > end - 2) {
+          // Non Standard support, when the cursor exceeds bounds.
+          offset = end - 2;
+        }
+  
+        while (end > fill) {
+          buff[--end] = offset < end && offset > fill ? buff[--offset] : 0;
+        }
+      } else {
+        // Fill the rest with zeros
+        while (offset < end) {
+          buff[offset++] = 0;
+        }
+      }
+  
+      return buff;
+    },
+  
+    decode(buff, offset) {
+      offset = ~~offset;
+      let result = '';
+  
+      for (let i = 0; i < v6Size; i += 2) {
+        if (i !== 0) {
+          result += ':';
+        }
+  
+        result += (buff[offset + i] << 8 | buff[offset + i + 1]).toString(16);
+      }
+  
+      return result.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3').replace(/:{3,4}/, '::');
+    }
+  
+  };
+  exports.v6 = v6;
+  const name = 'ip';
+  exports.name = name;
+  
+  function sizeOf(ip) {
+    if (v4.isFormat(ip)) return v4.size;
+    if (v6.isFormat(ip)) return v6.size;
+    throw Error(`Invalid ip address: ${ip}`);
+  }
+  
+  function familyOf(string) {
+    return sizeOf(string) === v4.size ? 1 : 2;
+  }
+  
+  function encode(ip, buff, offset) {
+    offset = ~~offset;
+    const size = sizeOf(ip);
+  
+    if (typeof buff === 'function') {
+      buff = buff(offset + size);
+    }
+  
+    if (size === v4.size) {
+      return v4.encode(ip, buff, offset);
+    }
+  
+    return v6.encode(ip, buff, offset);
+  }
+  
+  function decode(buff, offset, length) {
+    offset = ~~offset;
+    length = length || buff.length - offset;
+  
+    if (length === v4.size) {
+      return v4.decode(buff, offset, length);
+    }
+  
+    if (length === v6.size) {
+      return v6.decode(buff, offset, length);
+    }
+  
+    throw Error(`Invalid buffer size needs to be ${v4.size} for v4 or ${v6.size} for v6.`);
+  }
+  return "default" in exports ? exports.default : exports;
+})({});
+if (typeof define === 'function' && define.amd) define([], function() { return ipCodec; });
+else if (typeof module === 'object' && typeof exports==='object') module.exports = ipCodec;
Index: frontend/node_modules/@leichtgewicht/ip-codec/index.mjs
===================================================================
--- frontend/node_modules/@leichtgewicht/ip-codec/index.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@leichtgewicht/ip-codec/index.mjs	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,201 @@
+const v4Regex = /^(\d{1,3}\.){3,3}\d{1,3}$/
+const v4Size = 4
+const v6Regex = /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i
+const v6Size = 16
+
+export const v4 = {
+  name: 'v4',
+  size: v4Size,
+  isFormat: ip => v4Regex.test(ip),
+  encode (ip, buff, offset) {
+    offset = ~~offset
+    buff = buff || new Uint8Array(offset + v4Size)
+    const max = ip.length
+    let n = 0
+    for (let i = 0; i < max;) {
+      const c = ip.charCodeAt(i++)
+      if (c === 46) { // "."
+        buff[offset++] = n
+        n = 0
+      } else {
+        n = n * 10 + (c - 48)
+      }
+    }
+    buff[offset] = n
+    return buff
+  },
+  decode (buff, offset) {
+    offset = ~~offset
+    return `${buff[offset++]}.${buff[offset++]}.${buff[offset++]}.${buff[offset]}`
+  }
+}
+
+export const v6 = {
+  name: 'v6',
+  size: v6Size,
+  isFormat: ip => ip.length > 0 && v6Regex.test(ip),
+  encode (ip, buff, offset) {
+    offset = ~~offset
+    let end = offset + v6Size
+    let fill = -1
+    let hexN = 0
+    let decN = 0
+    let prevColon = true
+    let useDec = false
+    buff = buff || new Uint8Array(offset + v6Size)
+    // Note: This algorithm needs to check if the offset
+    // could exceed the buffer boundaries as it supports
+    // non-standard compliant encodings that may go beyond
+    // the boundary limits. if (offset < end) checks should
+    // not be necessary...
+    for (let i = 0; i < ip.length; i++) {
+      let c = ip.charCodeAt(i)
+      if (c === 58) { // :
+        if (prevColon) {
+          if (fill !== -1) {
+            // Not Standard! (standard doesn't allow multiple ::)
+            // We need to treat
+            if (offset < end) buff[offset] = 0
+            if (offset < end - 1) buff[offset + 1] = 0
+            offset += 2
+          } else if (offset < end) {
+            // :: in the middle
+            fill = offset
+          }
+        } else {
+          // : ends the previous number
+          if (useDec === true) {
+            // Non-standard! (ipv4 should be at end only)
+            // A ipv4 address should not be found anywhere else but at
+            // the end. This codec also support putting characters
+            // after the ipv4 address..
+            if (offset < end) buff[offset] = decN
+            offset++
+          } else {
+            if (offset < end) buff[offset] = hexN >> 8
+            if (offset < end - 1) buff[offset + 1] = hexN & 0xff
+            offset += 2
+          }
+          hexN = 0
+          decN = 0
+        }
+        prevColon = true
+        useDec = false
+      } else if (c === 46) { // . indicates IPV4 notation
+        if (offset < end) buff[offset] = decN
+        offset++
+        decN = 0
+        hexN = 0
+        prevColon = false
+        useDec = true
+      } else {
+        prevColon = false
+        if (c >= 97) {
+          c -= 87 // a-f ... 97~102 -87 => 10~15
+        } else if (c >= 65) {
+          c -= 55 // A-F ... 65~70 -55 => 10~15
+        } else {
+          c -= 48 // 0-9 ... starting from charCode 48
+          decN = decN * 10 + c
+        }
+        // We don't know yet if its a dec or hex number
+        hexN = (hexN << 4) + c
+      }
+    }
+    if (prevColon === false) {
+      // Commiting last number
+      if (useDec === true) {
+        if (offset < end) buff[offset] = decN
+        offset++
+      } else {
+        if (offset < end) buff[offset] = hexN >> 8
+        if (offset < end - 1) buff[offset + 1] = hexN & 0xff
+        offset += 2
+      }
+    } else if (fill === 0) {
+      // Not Standard! (standard doesn't allow multiple ::)
+      // This means that a : was found at the start AND end which means the
+      // end needs to be treated as 0 entry...
+      if (offset < end) buff[offset] = 0
+      if (offset < end - 1) buff[offset + 1] = 0
+      offset += 2
+    } else if (fill !== -1) {
+      // Non-standard! (standard doens't allow multiple ::)
+      // Here we find that there has been a :: somewhere in the middle
+      // and the end. To treat the end with priority we need to move all
+      // written data two bytes to the right.
+      offset += 2
+      for (let i = Math.min(offset - 1, end - 1); i >= fill + 2; i--) {
+        buff[i] = buff[i - 2]
+      }
+      buff[fill] = 0
+      buff[fill + 1] = 0
+      fill = offset
+    }
+    if (fill !== offset && fill !== -1) {
+      // Move the written numbers to the end while filling the everything
+      // "fill" to the bytes with zeros.
+      if (offset > end - 2) {
+        // Non Standard support, when the cursor exceeds bounds.
+        offset = end - 2
+      }
+      while (end > fill) {
+        buff[--end] = offset < end && offset > fill ? buff[--offset] : 0
+      }
+    } else {
+      // Fill the rest with zeros
+      while (offset < end) {
+        buff[offset++] = 0
+      }
+    }
+    return buff
+  },
+  decode (buff, offset) {
+    offset = ~~offset
+    let result = ''
+    for (let i = 0; i < v6Size; i += 2) {
+      if (i !== 0) {
+        result += ':'
+      }
+      result += (buff[offset + i] << 8 | buff[offset + i + 1]).toString(16)
+    }
+    return result
+      .replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3')
+      .replace(/:{3,4}/, '::')
+  }
+}
+
+export const name = 'ip'
+export function sizeOf (ip) {
+  if (v4.isFormat(ip)) return v4.size
+  if (v6.isFormat(ip)) return v6.size
+  throw Error(`Invalid ip address: ${ip}`)
+}
+
+export function familyOf (string) {
+  return sizeOf(string) === v4.size ? 1 : 2
+}
+
+export function encode (ip, buff, offset) {
+  offset = ~~offset
+  const size = sizeOf(ip)
+  if (typeof buff === 'function') {
+    buff = buff(offset + size)
+  }
+  if (size === v4.size) {
+    return v4.encode(ip, buff, offset)
+  }
+  return v6.encode(ip, buff, offset)
+}
+
+export function decode (buff, offset, length) {
+  offset = ~~offset
+  length = length || (buff.length - offset)
+  if (length === v4.size) {
+    return v4.decode(buff, offset, length)
+  }
+  if (length === v6.size) {
+    return v6.decode(buff, offset, length)
+  }
+  throw Error(`Invalid buffer size needs to be ${v4.size} for v4 or ${v6.size} for v6.`)
+}
Index: frontend/node_modules/@leichtgewicht/ip-codec/package.json
===================================================================
--- frontend/node_modules/@leichtgewicht/ip-codec/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@leichtgewicht/ip-codec/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,48 @@
+{
+  "name": "@leichtgewicht/ip-codec",
+  "version": "2.0.5",
+  "description": "Small package to encode or decode IP addresses from buffers to strings.",
+  "main": "index.cjs",
+  "types": "types",
+  "exports": {
+    ".": {
+      "types": "./types/index.d.ts",
+      "import": "./index.mjs",
+      "require": "./index.cjs"
+    }
+  },
+  "scripts": {
+    "lint": "standard && dtslint --localTs node_modules/typescript/lib types",
+    "test": "npm run lint && npm run unit",
+    "unit": "fresh-tape test.mjs",
+    "coverage": "c8 npm run unit",
+    "prepare": "npx @leichtgewicht/esm2umd ipCodec"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/martinheidegger/ip-codec.git"
+  },
+  "keywords": [
+    "ip",
+    "ipv4",
+    "ipv6",
+    "codec",
+    "codecs",
+    "buffer",
+    "conversion"
+  ],
+  "author": "Martin Heidegger",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/martinheidegger/ip-codec/issues"
+  },
+  "homepage": "https://github.com/martinheidegger/ip-codec#readme",
+  "devDependencies": {
+    "@definitelytyped/dtslint": "0.2.19",
+    "@leichtgewicht/esm2umd": "^0.4.0",
+    "c8": "^9.1.0",
+    "fresh-tape": "^5.5.3",
+    "standard": "^17.1.0",
+    "typescript": "^5.4.3"
+  }
+}
Index: frontend/node_modules/@leichtgewicht/ip-codec/types/index.d.ts
===================================================================
--- frontend/node_modules/@leichtgewicht/ip-codec/types/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/@leichtgewicht/ip-codec/types/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,26 @@
+interface Encoder {
+  (ip: string): Uint8Array;
+  <TIn extends Uint8Array = Uint8Array> (ip: string, buff: TIn, offset?: number): TIn;
+}
+type Decoder = (ip: Uint8Array, offset?: number) => string;
+
+interface Codec<TName extends string, TSize extends number> {
+  name: TName;
+  size: TSize;
+  encode: Encoder;
+  decode: Decoder;
+  isFormat(ip: string): boolean;
+}
+
+export function sizeOf(ip: string): 4 | 16;
+export function familyOf(ip: string): 1 | 2;
+export const v4: Codec<"ipv4", 4>;
+export const v6: Codec<"ipv6", 16>;
+export const name: "ip";
+export const encode: {
+  (ip: string): Uint8Array;
+  <TIn extends Uint8Array = Uint8Array> (ip: string, buff: TIn | ((size: number) => TIn), offset?: number): TIn
+};
+export function decode(ip: Uint8Array, offset?: number, length?: number): string;
+
+export {};
