venetian 0.3.1-aarch64-linux → 0.4.0-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +151 -0
  3. data/CLAUDE.md +1 -0
  4. data/README.md +11 -0
  5. data/Rakefile +1 -0
  6. data/exe/aarch64-linux/node +2 -2
  7. data/exe/aarch64-linux/package/browsers.json +9 -9
  8. data/exe/aarch64-linux/package/cli.js +1 -0
  9. data/exe/aarch64-linux/package/lib/bootstrap.js +61 -0
  10. data/exe/aarch64-linux/package/lib/coreBundle.js +6393 -4170
  11. data/exe/aarch64-linux/package/lib/server/electron/loader.js +4 -0
  12. data/exe/aarch64-linux/package/lib/tools/cli-client/cli.js +2 -1
  13. data/exe/aarch64-linux/package/lib/tools/cli-client/help.json +99 -12
  14. data/exe/aarch64-linux/package/lib/tools/cli-client/output.js +17 -16
  15. data/exe/aarch64-linux/package/lib/tools/cli-client/program.js +8 -4
  16. data/exe/aarch64-linux/package/lib/tools/cli-client/session.js +2 -0
  17. data/exe/aarch64-linux/package/lib/tools/skills/playwright-cli/SKILL.md +71 -3
  18. data/exe/aarch64-linux/package/lib/tools/skills/playwright-cli/references/pr-attachments.md +60 -0
  19. data/exe/aarch64-linux/package/lib/tools/skills/playwright-cli/references/running-code.md +4 -0
  20. data/exe/aarch64-linux/package/lib/tools/skills/playwright-cli/references/session-management.md +2 -0
  21. data/exe/aarch64-linux/package/lib/tools/skills/playwright-cli/references/test-generation.md +1 -1
  22. data/exe/aarch64-linux/package/lib/tools/skills/playwright-cli/references/video-recording.md +76 -3
  23. data/exe/aarch64-linux/package/lib/tools/skills/playwright-trace/SKILL.md +1 -1
  24. data/exe/aarch64-linux/package/lib/utilsBundle.js +948 -227
  25. data/exe/aarch64-linux/package/lib/utilsBundle.js.LICENSE +6 -6
  26. data/exe/aarch64-linux/package/lib/vite/htmlReport/report.js +1 -1
  27. data/exe/aarch64-linux/package/lib/vite/recorder/assets/{codeMirrorModule-CVQWJZAA.js → codeMirrorModule-DK72OMRi.js} +1 -1
  28. data/exe/aarch64-linux/package/lib/vite/recorder/assets/index-Cn0mmDuv.js +129 -0
  29. data/exe/aarch64-linux/package/lib/vite/recorder/index.html +1 -1
  30. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/{codeMirrorModule-BbkfBe3n.js → codeMirrorModule-BEB2e8M3.js} +1 -1
  31. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/defaultSettingsView-D-g2vrvf.js +184 -0
  32. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/{xtermModule-DywYcAf8.js → xtermModule-B794rD2Z.js} +1 -1
  33. data/exe/aarch64-linux/package/lib/vite/traceViewer/{defaultSettingsView.Bqk9acqE.css → defaultSettingsView.C8BeHuxd.css} +1 -1
  34. data/exe/aarch64-linux/package/lib/vite/traceViewer/{index.B4cLoZK3.js → index.7-c5LSTW.js} +1 -1
  35. data/exe/aarch64-linux/package/lib/vite/traceViewer/index.html +3 -3
  36. data/exe/aarch64-linux/package/lib/vite/traceViewer/sw.bundle.js +3 -3
  37. data/exe/aarch64-linux/package/lib/vite/traceViewer/{uiMode.CU5KtEkS.js → uiMode.CYwC_gH1.js} +4 -4
  38. data/exe/aarch64-linux/package/lib/vite/traceViewer/uiMode.html +3 -3
  39. data/exe/aarch64-linux/package/package.json +1 -1
  40. data/exe/aarch64-linux/package/types/protocol.d.ts +468 -337
  41. data/exe/aarch64-linux/package/types/types.d.ts +572 -37
  42. data/lib/venetian/core.rb +1 -0
  43. data/lib/venetian/executable.rb +24 -5
  44. data/lib/venetian/playwright.rb +1 -0
  45. data/lib/venetian/transport_extensions.rb +17 -0
  46. data/lib/venetian/trust_store.rb +67 -0
  47. data/lib/venetian/upstream.rb +36 -1
  48. data/lib/venetian/version.rb +3 -2
  49. metadata +17 -12
  50. data/exe/aarch64-linux/package/lib/vite/recorder/assets/index-hrlLqLtq.js +0 -129
  51. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/defaultSettingsView-Ds6CBOo0.js +0 -182
@@ -7736,8 +7736,12 @@ var require_common2 = __commonJS({
7736
7736
  "use strict";
7737
7737
  Object.defineProperty(exports2, "__esModule", { value: true });
7738
7738
  exports2.isInSubnet = isInSubnet;
7739
+ exports2.isHostInSubnet = isHostInSubnet;
7740
+ exports2.isGloballyReachable = isGloballyReachable;
7741
+ exports2.offsetBigInt = offsetBigInt;
7739
7742
  exports2.isCorrect = isCorrect;
7740
7743
  exports2.prefixLengthFromMask = prefixLengthFromMask;
7744
+ exports2.assertByteArray = assertByteArray;
7741
7745
  exports2.numberToPaddedHex = numberToPaddedHex;
7742
7746
  exports2.stringToPaddedHex = stringToPaddedHex;
7743
7747
  exports2.testBit = testBit;
@@ -7746,13 +7750,39 @@ var require_common2 = __commonJS({
7746
7750
  if (this.subnetMask < address.subnetMask) {
7747
7751
  return false;
7748
7752
  }
7749
- if (this.mask(address.subnetMask) === address.mask()) {
7750
- return true;
7753
+ return isHostInSubnet.call(this, address);
7754
+ }
7755
+ function isHostInSubnet(address) {
7756
+ if (this.binaryZeroPad().length !== address.binaryZeroPad().length) {
7757
+ return false;
7751
7758
  }
7752
- return false;
7759
+ return this.mask(address.subnetMask) === address.mask();
7760
+ }
7761
+ function isGloballyReachable(entries) {
7762
+ let best = null;
7763
+ for (let i2 = 0; i2 < entries.length; i2++) {
7764
+ const entry = entries[i2];
7765
+ if (entry.reachable !== null && isHostInSubnet.call(this, entry.subnet) && (best === null || entry.subnet.subnetMask > best.subnet.subnetMask)) {
7766
+ best = entry;
7767
+ }
7768
+ }
7769
+ return best === null ? true : best.reachable;
7770
+ }
7771
+ function offsetBigInt(value, n2, bits, family) {
7772
+ if (typeof n2 === "number" && !Number.isSafeInteger(n2)) {
7773
+ throw new address_error_1.AddressError(`${family} offset must be an integer`);
7774
+ }
7775
+ if (typeof n2 !== "number" && typeof n2 !== "bigint") {
7776
+ throw new address_error_1.AddressError(`${family} offset must be an integer`);
7777
+ }
7778
+ const result = value + BigInt(n2);
7779
+ if (result < BigInt(0) || result > (BigInt(1) << BigInt(bits)) - BigInt(1)) {
7780
+ throw new address_error_1.AddressError(`${family} offset leaves the address space`);
7781
+ }
7782
+ return result;
7753
7783
  }
7754
7784
  function isCorrect(defaultBits) {
7755
- return function() {
7785
+ return function isCorrectForm() {
7756
7786
  if (this.addressMinusSuffix !== this.correctForm()) {
7757
7787
  return false;
7758
7788
  }
@@ -7776,6 +7806,16 @@ var require_common2 = __commonJS({
7776
7806
  }
7777
7807
  return firstZero;
7778
7808
  }
7809
+ function assertByteArray(bytes2, byteCount, family, minimum) {
7810
+ if (bytes2.length !== byteCount) {
7811
+ throw new address_error_1.AddressError(`${family} addresses require exactly ${byteCount} bytes`);
7812
+ }
7813
+ for (let i2 = 0; i2 < bytes2.length; i2++) {
7814
+ if (!Number.isInteger(bytes2[i2]) || bytes2[i2] < minimum || bytes2[i2] > 255) {
7815
+ throw new address_error_1.AddressError(`All bytes must be integers between ${minimum} and 255`);
7816
+ }
7817
+ }
7818
+ }
7779
7819
  function numberToPaddedHex(number4) {
7780
7820
  return number4.toString(16).padStart(2, "0");
7781
7821
  }
@@ -7798,11 +7838,39 @@ var require_constants3 = __commonJS({
7798
7838
  "node_modules/ip-address/dist/v4/constants.js"(exports2) {
7799
7839
  "use strict";
7800
7840
  Object.defineProperty(exports2, "__esModule", { value: true });
7801
- exports2.RE_SUBNET_STRING = exports2.RE_ADDRESS = exports2.GROUPS = exports2.BITS = void 0;
7841
+ exports2.SPECIAL_PURPOSE = exports2.RE_SUBNET_STRING = exports2.RE_ADDRESS = exports2.GROUPS = exports2.BITS = void 0;
7802
7842
  exports2.BITS = 32;
7803
7843
  exports2.GROUPS = 4;
7804
- exports2.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g;
7844
+ exports2.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/g;
7805
7845
  exports2.RE_SUBNET_STRING = /\/\d{1,2}$/;
7846
+ exports2.SPECIAL_PURPOSE = [
7847
+ ["0.0.0.0/8", "This network", false],
7848
+ ["0.0.0.0/32", "This host on this network", false],
7849
+ ["10.0.0.0/8", "Private-Use", false],
7850
+ ["100.64.0.0/10", "Shared Address Space", false],
7851
+ ["127.0.0.0/8", "Loopback", false],
7852
+ ["169.254.0.0/16", "Link Local", false],
7853
+ ["172.16.0.0/12", "Private-Use", false],
7854
+ ["192.0.0.0/24", "IETF Protocol Assignments", false],
7855
+ ["192.0.0.0/29", "IPv4 Service Continuity Prefix", false],
7856
+ ["192.0.0.8/32", "IPv4 dummy address", false],
7857
+ ["192.0.0.9/32", "Port Control Protocol Anycast", true],
7858
+ ["192.0.0.10/32", "Traversal Using Relays around NAT Anycast", true],
7859
+ ["192.0.0.170/32", "NAT64/DNS64 Discovery", false],
7860
+ ["192.0.0.171/32", "NAT64/DNS64 Discovery", false],
7861
+ ["192.0.2.0/24", "Documentation (TEST-NET-1)", false],
7862
+ ["192.31.196.0/24", "AS112-v4", true],
7863
+ ["192.52.193.0/24", "AMT", true],
7864
+ ["192.88.99.0/24", "Deprecated (6to4 Relay Anycast)", null],
7865
+ ["192.88.99.2/32", "6a44-relay anycast address", false],
7866
+ ["192.168.0.0/16", "Private-Use", false],
7867
+ ["192.175.48.0/24", "Direct Delegation AS112 Service", true],
7868
+ ["198.18.0.0/15", "Benchmarking", false],
7869
+ ["198.51.100.0/24", "Documentation (TEST-NET-2)", false],
7870
+ ["203.0.113.0/24", "Documentation (TEST-NET-3)", false],
7871
+ ["240.0.0.0/4", "Reserved", false],
7872
+ ["255.255.255.255/32", "Limited Broadcast", false]
7873
+ ];
7806
7874
  }
7807
7875
  });
7808
7876
 
@@ -7845,6 +7913,7 @@ var require_ipv4 = __commonJS({
7845
7913
  var isCorrect4 = common.isCorrect(constants.BITS);
7846
7914
  var Address4 = class _Address4 {
7847
7915
  constructor(address) {
7916
+ this.addressMinusSuffix = "";
7848
7917
  this.groups = constants.GROUPS;
7849
7918
  this.parsedAddress = [];
7850
7919
  this.parsedSubnet = "";
@@ -7853,6 +7922,7 @@ var require_ipv4 = __commonJS({
7853
7922
  this.v4 = true;
7854
7923
  this.isCorrect = isCorrect4;
7855
7924
  this.isInSubnet = common.isInSubnet;
7925
+ this.isHostInSubnet = common.isHostInSubnet;
7856
7926
  this.address = address;
7857
7927
  const subnet = constants.RE_SUBNET_STRING.exec(address);
7858
7928
  if (subnet) {
@@ -7864,6 +7934,10 @@ var require_ipv4 = __commonJS({
7864
7934
  }
7865
7935
  address = address.replace(constants.RE_SUBNET_STRING, "");
7866
7936
  }
7937
+ const longest = constants.GROUPS * 4 - 1;
7938
+ if (address.length > longest) {
7939
+ throw new address_error_1.AddressError(`IPv4 addresses are at most ${longest} characters.`);
7940
+ }
7867
7941
  this.addressMinusSuffix = address;
7868
7942
  this.parsedAddress = this.parse(address);
7869
7943
  }
@@ -7878,7 +7952,7 @@ var require_ipv4 = __commonJS({
7878
7952
  try {
7879
7953
  new _Address4(address);
7880
7954
  return true;
7881
- } catch (e) {
7955
+ } catch {
7882
7956
  return false;
7883
7957
  }
7884
7958
  }
@@ -7890,6 +7964,9 @@ var require_ipv4 = __commonJS({
7890
7964
  */
7891
7965
  parse(address) {
7892
7966
  const groups = address.split(".");
7967
+ if (groups.some((group) => /^0\d/.test(group))) {
7968
+ throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.");
7969
+ }
7893
7970
  if (!address.match(constants.RE_ADDRESS)) {
7894
7971
  throw new address_error_1.AddressError("Invalid IPv4 address.");
7895
7972
  }
@@ -7997,15 +8074,18 @@ var require_ipv4 = __commonJS({
7997
8074
  return _Address4.fromHex(integer2.toString(16).padStart(8, "0"));
7998
8075
  }
7999
8076
  /**
8000
- * Return an address from in-addr.arpa form
8077
+ * Return an address from in-addr.arpa form: the four octets reversed, with
8078
+ * or without the `.in-addr.arpa` suffix and root dot, in any case. Throws
8079
+ * `AddressError` unless the reversed labels form a valid IPv4 address, so
8080
+ * `fromArpa(x.reverseForm())` round-trips {@link reverseForm}.
8001
8081
  * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address
8002
8082
  * @returns {Adress4}
8003
8083
  * @example
8004
- * var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)
8084
+ * var address = Address4.fromArpa('42.2.0.192.in-addr.arpa.')
8005
8085
  * address.correctForm(); // '192.0.2.42'
8006
8086
  */
8007
8087
  static fromArpa(arpaFormAddress) {
8008
- const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.$/, "");
8088
+ const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.?$/i, "");
8009
8089
  const address = leader.split(".").reverse().join(".");
8010
8090
  return new _Address4(address);
8011
8091
  }
@@ -8068,6 +8148,33 @@ var require_ipv4 = __commonJS({
8068
8148
  const adjust = BigInt("1");
8069
8149
  return _Address4.fromBigInt(this._startAddress() + adjust);
8070
8150
  }
8151
+ /**
8152
+ * Returns the address `n` addresses after this one (or before, when `n` is
8153
+ * negative), keeping this address's subnet mask. Throws `AddressError` when
8154
+ * the result would fall outside the IPv4 address space or `n` is not an
8155
+ * integer.
8156
+ * @param {number | bigint} n
8157
+ * @returns {Address4}
8158
+ * @example
8159
+ * new Address4('10.0.0.0/24').offset(1).correctForm(); // '10.0.0.1'
8160
+ */
8161
+ offset(n2) {
8162
+ return _Address4.fromBigInt(common.offsetBigInt(this.bigInt(), n2, constants.BITS, "IPv4")).withSubnetMask(this.subnetMask);
8163
+ }
8164
+ /**
8165
+ * Returns the network that follows this address's network: the address after
8166
+ * {@link endAddress}, with the same subnet mask. Throws `AddressError` when
8167
+ * this network is the last one in the address space.
8168
+ * @returns {Address4}
8169
+ * @example
8170
+ * new Address4('10.0.0.0/24').nextNetwork().networkForm(); // '10.0.1.0/24'
8171
+ */
8172
+ nextNetwork() {
8173
+ return _Address4.fromBigInt(common.offsetBigInt(this._endAddress(), 1, constants.BITS, "IPv4")).withSubnetMask(this.subnetMask);
8174
+ }
8175
+ withSubnetMask(subnetMask) {
8176
+ return new _Address4(`${this.correctForm()}/${subnetMask}`);
8177
+ }
8071
8178
  /**
8072
8179
  * Helper function getting end address.
8073
8180
  * @returns {bigint}
@@ -8125,31 +8232,32 @@ var require_ipv4 = __commonJS({
8125
8232
  * @returns {Address4}
8126
8233
  */
8127
8234
  static fromBigInt(bigInt) {
8128
- if (bigInt < 0n || bigInt > 0xffffffffn) {
8235
+ if (bigInt < BigInt(0) || bigInt > BigInt(4294967295)) {
8129
8236
  throw new address_error_1.AddressError("IPv4 BigInt must be in the range 0 to 2**32 - 1");
8130
8237
  }
8131
8238
  return _Address4.fromHex(bigInt.toString(16).padStart(8, "0"));
8132
8239
  }
8133
8240
  /**
8134
- * Convert a byte array to an Address4 object.
8241
+ * Convert a byte array to an Address4 object. Throws `AddressError` unless
8242
+ * given exactly 4 integers from 0 to 255. Signed bytes are rejected, so
8243
+ * this differs from `Address6.fromByteArray`, which folds them; the two
8244
+ * contracts converge on this stricter form in the next major version.
8135
8245
  *
8136
8246
  * To convert from a Node.js `Buffer`, spread it: `Address4.fromByteArray([...buf])`.
8137
8247
  * @param {Array<number>} bytes - an array of 4 bytes (0-255)
8138
8248
  * @returns {Address4}
8139
8249
  */
8140
8250
  static fromByteArray(bytes2) {
8141
- if (bytes2.length !== 4) {
8142
- throw new address_error_1.AddressError("IPv4 addresses require exactly 4 bytes");
8143
- }
8144
- for (let i2 = 0; i2 < bytes2.length; i2++) {
8145
- if (!Number.isInteger(bytes2[i2]) || bytes2[i2] < 0 || bytes2[i2] > 255) {
8146
- throw new address_error_1.AddressError("All bytes must be integers between 0 and 255");
8147
- }
8148
- }
8251
+ common.assertByteArray(bytes2, 4, "IPv4", 0);
8149
8252
  return this.fromUnsignedByteArray(bytes2);
8150
8253
  }
8151
8254
  /**
8152
- * Convert an unsigned byte array to an Address4 object
8255
+ * Convert an unsigned byte array to an Address4 object. Throws
8256
+ * `AddressError` unless given exactly 4 bytes, and rejects values outside
8257
+ * 0 to 255 when parsing the resulting address.
8258
+ *
8259
+ * To convert from a Node.js `Buffer`, spread it:
8260
+ * `Address4.fromUnsignedByteArray([...buf])`.
8153
8261
  * @param {Array<number>} bytes - an array of 4 unsigned bytes (0-255)
8154
8262
  * @returns {Address4}
8155
8263
  */
@@ -8179,7 +8287,8 @@ var require_ipv4 = __commonJS({
8179
8287
  return this.binaryZeroPad().slice(start, end);
8180
8288
  }
8181
8289
  /**
8182
- * Return the reversed ip6.arpa form of the address
8290
+ * Return the reversed in-addr.arpa form of the address, e.g.
8291
+ * `42.2.0.192.in-addr.arpa.` for `192.0.2.42`.
8183
8292
  * @param {Object} options
8184
8293
  * @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix
8185
8294
  * @returns {String}
@@ -8199,49 +8308,86 @@ var require_ipv4 = __commonJS({
8199
8308
  * @returns {boolean}
8200
8309
  */
8201
8310
  isMulticast() {
8202
- return this.isInSubnet(MULTICAST_V4);
8311
+ return this.isHostInSubnet(MULTICAST_V4);
8203
8312
  }
8204
8313
  /**
8205
8314
  * Returns true if the address is in one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private address ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`).
8206
8315
  * @returns {boolean}
8207
8316
  */
8208
8317
  isPrivate() {
8209
- return PRIVATE_V4.some((subnet) => this.isInSubnet(subnet));
8318
+ return PRIVATE_V4.some((subnet) => this.isHostInSubnet(subnet));
8210
8319
  }
8211
8320
  /**
8212
8321
  * Returns true if the address is in the loopback range `127.0.0.0/8` ([RFC 1122](https://datatracker.ietf.org/doc/html/rfc1122)).
8213
8322
  * @returns {boolean}
8214
8323
  */
8215
8324
  isLoopback() {
8216
- return this.isInSubnet(LOOPBACK_V4);
8325
+ return this.isHostInSubnet(LOOPBACK_V4);
8217
8326
  }
8218
8327
  /**
8219
8328
  * Returns true if the address is in the link-local range `169.254.0.0/16` ([RFC 3927](https://datatracker.ietf.org/doc/html/rfc3927)).
8220
8329
  * @returns {boolean}
8221
8330
  */
8222
8331
  isLinkLocal() {
8223
- return this.isInSubnet(LINK_LOCAL_V4);
8332
+ return this.isHostInSubnet(LINK_LOCAL_V4);
8224
8333
  }
8225
8334
  /**
8226
8335
  * Returns true if the address is the unspecified address `0.0.0.0`.
8227
8336
  * @returns {boolean}
8228
8337
  */
8229
8338
  isUnspecified() {
8230
- return this.isInSubnet(UNSPECIFIED_V4);
8339
+ return this.isHostInSubnet(UNSPECIFIED_V4);
8231
8340
  }
8232
8341
  /**
8233
8342
  * Returns true if the address is the limited broadcast address `255.255.255.255` ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)).
8234
8343
  * @returns {boolean}
8235
8344
  */
8236
8345
  isBroadcast() {
8237
- return this.isInSubnet(BROADCAST_V4);
8346
+ return this.isHostInSubnet(BROADCAST_V4);
8238
8347
  }
8239
8348
  /**
8240
8349
  * Returns true if the address is in the carrier-grade NAT range `100.64.0.0/10` ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)).
8241
8350
  * @returns {boolean}
8242
8351
  */
8243
8352
  isCGNAT() {
8244
- return this.isInSubnet(CGNAT_V4);
8353
+ return this.isHostInSubnet(CGNAT_V4);
8354
+ }
8355
+ /**
8356
+ * Returns true if the address is in one of the documentation ranges
8357
+ * `192.0.2.0/24`, `198.51.100.0/24`, or `203.0.113.0/24` ([RFC 5737](https://datatracker.ietf.org/doc/html/rfc5737)).
8358
+ * @returns {boolean}
8359
+ */
8360
+ isDocumentation() {
8361
+ return DOCUMENTATION_V4.some((subnet) => this.isHostInSubnet(subnet));
8362
+ }
8363
+ /**
8364
+ * Returns true if the address is in the benchmarking range `198.18.0.0/15` ([RFC 2544](https://datatracker.ietf.org/doc/html/rfc2544)).
8365
+ * @returns {boolean}
8366
+ */
8367
+ isBenchmarking() {
8368
+ return this.isHostInSubnet(BENCHMARKING_V4);
8369
+ }
8370
+ /**
8371
+ * Returns true if the address is in the reserved range `240.0.0.0/4` ([RFC 1112](https://datatracker.ietf.org/doc/html/rfc1112)),
8372
+ * which includes the limited broadcast address.
8373
+ * @returns {boolean}
8374
+ */
8375
+ isReserved() {
8376
+ return this.isHostInSubnet(RESERVED_V4);
8377
+ }
8378
+ /**
8379
+ * Returns true if the address is globally reachable: not multicast, and not
8380
+ * in any block the [IANA IPv4 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv4-special-registry/)
8381
+ * marks as not globally reachable. That covers everything the individual
8382
+ * classifiers name (private, loopback, link-local, CGNAT, unspecified,
8383
+ * broadcast, documentation, benchmarking, reserved) and the blocks they do
8384
+ * not, such as `0.0.0.0/8` and the IETF protocol assignments in
8385
+ * `192.0.0.0/24`. This is the single predicate to use where a request must
8386
+ * not reach an internal or special-purpose destination; see SECURITY.md.
8387
+ * @returns {boolean}
8388
+ */
8389
+ isGlobal() {
8390
+ return !this.isMulticast() && common.isGloballyReachable.call(this, SPECIAL_PURPOSE_V4);
8245
8391
  }
8246
8392
  /**
8247
8393
  * Returns a zero-padded base-2 string representation of the address
@@ -8254,12 +8400,17 @@ var require_ipv4 = __commonJS({
8254
8400
  return this._binaryZeroPad;
8255
8401
  }
8256
8402
  /**
8257
- * Groups an IPv4 address for inclusion at the end of an IPv6 address
8403
+ * Groups an IPv4 address for inclusion at the end of an IPv6 address.
8404
+ *
8405
+ * Returns an HTML fragment: each half of the address is wrapped in a
8406
+ * `<span>` carrying the group classes an address-inspector UI hovers on.
8407
+ * The address content is HTML-escaped; anything you concatenate around it
8408
+ * is your responsibility.
8258
8409
  * @returns {String}
8259
8410
  */
8260
8411
  groupForV6() {
8261
8412
  const segments = this.parsedAddress;
8262
- return this.address.replace(constants.RE_ADDRESS, `<span class="hover-group group-v4 group-6">${segments.slice(0, 2).join(".")}</span>.<span class="hover-group group-v4 group-7">${segments.slice(2, 4).join(".")}</span>`);
8413
+ return this.correctForm().replace(constants.RE_ADDRESS, `<span class="hover-group group-v4 group-6">${segments.slice(0, 2).join(".")}</span>.<span class="hover-group group-v4 group-7">${segments.slice(2, 4).join(".")}</span>`);
8263
8414
  }
8264
8415
  };
8265
8416
  exports2.Address4 = Address4;
@@ -8274,6 +8425,17 @@ var require_ipv4 = __commonJS({
8274
8425
  var UNSPECIFIED_V4 = new Address4("0.0.0.0/32");
8275
8426
  var BROADCAST_V4 = new Address4("255.255.255.255/32");
8276
8427
  var CGNAT_V4 = new Address4("100.64.0.0/10");
8428
+ var DOCUMENTATION_V4 = [
8429
+ new Address4("192.0.2.0/24"),
8430
+ new Address4("198.51.100.0/24"),
8431
+ new Address4("203.0.113.0/24")
8432
+ ];
8433
+ var BENCHMARKING_V4 = new Address4("198.18.0.0/15");
8434
+ var RESERVED_V4 = new Address4("240.0.0.0/4");
8435
+ var SPECIAL_PURPOSE_V4 = constants.SPECIAL_PURPOSE.map(([cidr, , reachable]) => ({
8436
+ subnet: new Address4(cidr),
8437
+ reachable
8438
+ }));
8277
8439
  }
8278
8440
  });
8279
8441
 
@@ -8282,7 +8444,7 @@ var require_constants4 = __commonJS({
8282
8444
  "node_modules/ip-address/dist/v6/constants.js"(exports2) {
8283
8445
  "use strict";
8284
8446
  Object.defineProperty(exports2, "__esModule", { value: true });
8285
- exports2.RE_URL_WITH_PORT = exports2.RE_URL = exports2.RE_ZONE_STRING = exports2.RE_SUBNET_STRING = exports2.RE_BAD_ADDRESS = exports2.RE_BAD_CHARACTERS = exports2.TYPES = exports2.SCOPES = exports2.GROUPS = exports2.BITS = void 0;
8447
+ exports2.SPECIAL_PURPOSE = exports2.RE_URL_WITH_PORT = exports2.RE_URL = exports2.RE_ZONE_STRING = exports2.RE_SUBNET_STRING = exports2.RE_BAD_ADDRESS = exports2.RE_BAD_CHARACTERS = exports2.TYPES = exports2.SCOPES = exports2.GROUPS = exports2.BITS = void 0;
8286
8448
  exports2.BITS = 128;
8287
8449
  exports2.GROUPS = 8;
8288
8450
  exports2.SCOPES = {
@@ -8316,11 +8478,18 @@ var require_constants4 = __commonJS({
8316
8478
  "ff05::1:3/128": "Multicast (All DHCP servers in this site)",
8317
8479
  "::/128": "Unspecified",
8318
8480
  "::1/128": "Loopback",
8481
+ "::ffff:0:0/96": "IPv4-mapped",
8319
8482
  "ff00::/8": "Multicast",
8320
8483
  "fe80::/10": "Link-local unicast",
8321
8484
  "fc00::/7": "Unique local",
8485
+ "2001::/32": "Teredo",
8486
+ "2001:2::/48": "Benchmarking",
8322
8487
  "2002::/16": "6to4",
8323
8488
  "2001:db8::/32": "Documentation",
8489
+ "3fff::/20": "Documentation",
8490
+ "100::/64": "Discard-only",
8491
+ "fec0::/10": "Site-local unicast (deprecated)",
8492
+ "::/96": "IPv4-compatible (deprecated)",
8324
8493
  "64:ff9b::/96": "NAT64 (well-known)",
8325
8494
  "64:ff9b:1::/48": "NAT64 (local-use)"
8326
8495
  };
@@ -8328,8 +8497,35 @@ var require_constants4 = __commonJS({
8328
8497
  exports2.RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi;
8329
8498
  exports2.RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/;
8330
8499
  exports2.RE_ZONE_STRING = /%.*$/;
8331
- exports2.RE_URL = /^\[{0,1}([0-9a-f:]+)\]{0,1}/;
8332
- exports2.RE_URL_WITH_PORT = /\[([0-9a-f:]+)\]:([0-9]{1,5})/;
8500
+ exports2.RE_URL = /^(?:\[([0-9a-f:.]+)\]|([0-9a-f:.]+))(?:[/?#].*)?$/i;
8501
+ exports2.RE_URL_WITH_PORT = /^\[([0-9a-f:.]+)\]:([0-9]{1,5})(?:[/?#].*)?$/i;
8502
+ exports2.SPECIAL_PURPOSE = [
8503
+ ["::1/128", "Loopback Address", false],
8504
+ ["::/128", "Unspecified Address", false],
8505
+ ["::ffff:0:0/96", "IPv4-mapped Address", false],
8506
+ ["64:ff9b::/96", "IPv4-IPv6 Translat.", true],
8507
+ ["64:ff9b:1::/48", "IPv4-IPv6 Translat.", false],
8508
+ ["100::/64", "Discard-Only Address Block", false],
8509
+ ["100:0:0:1::/64", "Dummy IPv6 Prefix", false],
8510
+ ["2001::/23", "IETF Protocol Assignments", false],
8511
+ ["2001::/32", "TEREDO", false],
8512
+ ["2001:1::1/128", "Port Control Protocol Anycast", true],
8513
+ ["2001:1::2/128", "Traversal Using Relays around NAT Anycast", true],
8514
+ ["2001:1::3/128", "DNS-SD Service Registration Protocol Anycast", true],
8515
+ ["2001:2::/48", "Benchmarking", false],
8516
+ ["2001:3::/32", "AMT", true],
8517
+ ["2001:4:112::/48", "AS112-v6", true],
8518
+ ["2001:10::/28", "Deprecated (previously ORCHID)", null],
8519
+ ["2001:20::/28", "ORCHIDv2", true],
8520
+ ["2001:30::/28", "Drone Remote ID Protocol Entity Tags (DETs) Prefix", true],
8521
+ ["2001:db8::/32", "Documentation", false],
8522
+ ["2002::/16", "6to4", false],
8523
+ ["2620:4f:8000::/48", "Direct Delegation AS112 Service", true],
8524
+ ["3fff::/20", "Documentation", false],
8525
+ ["5f00::/16", "Segment Routing (SRv6) SIDs", false],
8526
+ ["fc00::/7", "Unique-Local", false],
8527
+ ["fe80::/10", "Link-Local Unicast", false]
8528
+ ];
8333
8529
  }
8334
8530
  });
8335
8531
 
@@ -8551,6 +8747,7 @@ var require_ipv6 = __commonJS({
8551
8747
  this.v4 = false;
8552
8748
  this.zone = "";
8553
8749
  this.isInSubnet = common.isInSubnet;
8750
+ this.isHostInSubnet = common.isHostInSubnet;
8554
8751
  this.isCorrect = isCorrect6;
8555
8752
  if (optionalGroups === void 0) {
8556
8753
  this.groups = constants6.GROUPS;
@@ -8567,7 +8764,8 @@ var require_ipv6 = __commonJS({
8567
8764
  throw new address_error_1.AddressError("Invalid subnet mask.");
8568
8765
  }
8569
8766
  address = address.replace(constants6.RE_SUBNET_STRING, "");
8570
- } else if (/\//.test(address)) {
8767
+ }
8768
+ if (/\//.test(address)) {
8571
8769
  throw new address_error_1.AddressError("Invalid subnet mask.");
8572
8770
  }
8573
8771
  const zone = constants6.RE_ZONE_STRING.exec(address);
@@ -8575,6 +8773,10 @@ var require_ipv6 = __commonJS({
8575
8773
  this.zone = zone[0];
8576
8774
  address = address.replace(constants6.RE_ZONE_STRING, "");
8577
8775
  }
8776
+ const longest = this.groups * 5 + 5;
8777
+ if (address.length > longest) {
8778
+ throw new address_error_1.AddressError(`IPv6 addresses are at most ${longest} characters.`);
8779
+ }
8578
8780
  this.addressMinusSuffix = address;
8579
8781
  this.parsedAddress = this.parse(this.addressMinusSuffix);
8580
8782
  }
@@ -8589,7 +8791,7 @@ var require_ipv6 = __commonJS({
8589
8791
  try {
8590
8792
  new _Address6(address);
8591
8793
  return true;
8592
- } catch (e) {
8794
+ } catch {
8593
8795
  return false;
8594
8796
  }
8595
8797
  }
@@ -8604,7 +8806,7 @@ var require_ipv6 = __commonJS({
8604
8806
  * address.correctForm(); // '::e8:d4a5:1000'
8605
8807
  */
8606
8808
  static fromBigInt(bigInt) {
8607
- if (bigInt < 0n || bigInt > (1n << BigInt(constants6.BITS)) - 1n) {
8809
+ if (bigInt < BigInt(0) || bigInt > (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1)) {
8608
8810
  throw new address_error_1.AddressError("IPv6 BigInt must be in the range 0 to 2**128 - 1");
8609
8811
  }
8610
8812
  const hex3 = bigInt.toString(16).padStart(32, "0");
@@ -8625,46 +8827,43 @@ var require_ipv6 = __commonJS({
8625
8827
  * addressAndPort.port; // 8080
8626
8828
  */
8627
8829
  static fromURL(url2) {
8830
+ var _a4;
8628
8831
  let host;
8629
8832
  let port = null;
8630
8833
  let result;
8631
- if (url2.indexOf("[") !== -1 && url2.indexOf("]:") !== -1) {
8632
- result = constants6.RE_URL_WITH_PORT.exec(url2);
8834
+ let error51;
8835
+ const stripped = url2.replace(/^[a-z][a-z0-9+.-]*:\/\//i, "");
8836
+ if (stripped.indexOf("[") !== -1 && stripped.indexOf("]:") !== -1) {
8837
+ error51 = "failed to parse address with port";
8838
+ result = constants6.RE_URL_WITH_PORT.exec(stripped);
8633
8839
  if (result === null) {
8634
- return {
8635
- error: "failed to parse address with port",
8636
- address: null,
8637
- port: null
8638
- };
8840
+ return { error: error51, address: null, port: null };
8639
8841
  }
8640
8842
  host = result[1];
8641
8843
  port = result[2];
8642
- } else if (url2.indexOf("/") !== -1) {
8643
- url2 = url2.replace(/^[a-z0-9]+:\/\//, "");
8644
- result = constants6.RE_URL.exec(url2);
8844
+ } else {
8845
+ error51 = "failed to parse address from URL";
8846
+ result = constants6.RE_URL.exec(stripped);
8645
8847
  if (result === null) {
8646
- return {
8647
- error: "failed to parse address from URL",
8648
- address: null,
8649
- port: null
8650
- };
8848
+ return { error: error51, address: null, port: null };
8651
8849
  }
8652
- host = result[1];
8653
- } else {
8654
- host = url2;
8850
+ host = (_a4 = result[1]) !== null && _a4 !== void 0 ? _a4 : result[2];
8655
8851
  }
8656
8852
  if (port) {
8657
8853
  port = parseInt(port, 10);
8658
- if (port < 0 || port > 65536) {
8854
+ if (port < 0 || port > 65535) {
8659
8855
  port = null;
8660
8856
  }
8661
8857
  } else {
8662
8858
  port = null;
8663
8859
  }
8664
- return {
8665
- address: new _Address6(host),
8666
- port
8667
- };
8860
+ let address;
8861
+ try {
8862
+ address = new _Address6(host);
8863
+ } catch {
8864
+ return { error: error51, address: null, port: null };
8865
+ }
8866
+ return { address, port };
8668
8867
  }
8669
8868
  /**
8670
8869
  * Construct an `Address6` from an address and a hex subnet mask given as
@@ -8762,26 +8961,30 @@ var require_ipv6 = __commonJS({
8762
8961
  return new _Address6(`::ffff:${address4.correctForm()}/${mask6}`);
8763
8962
  }
8764
8963
  /**
8765
- * Return an address from ip6.arpa form
8964
+ * Return an address from ip6.arpa form. A full 32-nibble name gives a /128
8965
+ * address; a shorter name, as used for a delegated reverse zone, gives the
8966
+ * network it covers, with a subnet mask of four bits per nibble, so
8967
+ * `fromArpa(x.reverseForm())` round-trips {@link reverseForm} for any prefix.
8766
8968
  * @param {string} arpaFormAddress - an 'ip6.arpa' form address
8767
8969
  * @returns {Adress6}
8768
8970
  * @example
8769
8971
  * var address = Address6.fromArpa(e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.e.1.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.)
8770
8972
  * address.correctForm(); // '2001:0:ce49:7601:e866:efff:62c3:fffe'
8973
+ * Address6.fromArpa('8.b.d.0.1.0.0.2.ip6.arpa.').networkForm(); // '2001:db8::/32'
8771
8974
  */
8772
8975
  static fromArpa(arpaFormAddress) {
8773
- let address = arpaFormAddress.replace(/(\.ip6\.arpa)?\.$/, "");
8774
- const semicolonAmount = 7;
8775
- if (address.length !== 63) {
8976
+ const nibbles = arpaFormAddress.replace(/(\.ip6\.arpa)?\.?$/i, "");
8977
+ if (!/^[0-9a-f](\.[0-9a-f]){0,31}$/i.test(nibbles)) {
8776
8978
  throw new address_error_1.AddressError("Invalid 'ip6.arpa' form.");
8777
8979
  }
8778
- const parts = address.split(".").reverse();
8779
- for (let i2 = semicolonAmount; i2 > 0; i2--) {
8780
- const insertIndex = i2 * 4;
8781
- parts.splice(insertIndex, 0, ":");
8980
+ const reversed = nibbles.split(".").reverse();
8981
+ const subnetMask = reversed.length * 4;
8982
+ const hex3 = reversed.join("").padEnd(32, "0");
8983
+ const groups = [];
8984
+ for (let i2 = 0; i2 < constants6.GROUPS; i2++) {
8985
+ groups.push(hex3.slice(i2 * 4, (i2 + 1) * 4));
8782
8986
  }
8783
- address = parts.join("");
8784
- return new _Address6(address);
8987
+ return new _Address6(`${groups.join(":")}/${subnetMask}`);
8785
8988
  }
8786
8989
  /**
8787
8990
  * Return the Microsoft UNC transcription of the address
@@ -8845,22 +9048,53 @@ var require_ipv6 = __commonJS({
8845
9048
  return BigInt(`0b${this.mask() + "1".repeat(constants6.BITS - this.subnetMask)}`);
8846
9049
  }
8847
9050
  /**
8848
- * The last address in the range given by this address' subnet
8849
- * Often referred to as the Broadcast
9051
+ * The last address in the range given by this address's subnet. IPv6 has
9052
+ * no broadcast address, so this is an ordinary assignable address (in a
9053
+ * 64-bit-interface-identifier subnet it falls inside the reserved
9054
+ * subnet-anycast block of [RFC 2526](https://datatracker.ietf.org/doc/html/rfc2526)).
8850
9055
  * @returns {Address6}
8851
9056
  */
8852
9057
  endAddress() {
8853
9058
  return _Address6.fromBigInt(this._endAddress());
8854
9059
  }
8855
9060
  /**
8856
- * The last host address in the range given by this address's subnet ie
8857
- * the last address prior to the Broadcast Address
9061
+ * The address one before {@link endAddress}. This is the IPv6 counterpart
9062
+ * of the IPv4 method that skips the broadcast address; IPv6 has no broadcast,
9063
+ * so it drops exactly one address and does not model the 128 reserved
9064
+ * subnet-anycast identifiers of [RFC 2526](https://datatracker.ietf.org/doc/html/rfc2526).
8858
9065
  * @returns {Address6}
8859
9066
  */
8860
9067
  endAddressExclusive() {
8861
9068
  const adjust = BigInt("1");
8862
9069
  return _Address6.fromBigInt(this._endAddress() - adjust);
8863
9070
  }
9071
+ /**
9072
+ * Returns the address `n` addresses after this one (or before, when `n` is
9073
+ * negative), keeping this address's subnet mask. Throws `AddressError` when
9074
+ * the result would fall outside the IPv6 address space or `n` is not an
9075
+ * integer.
9076
+ * @param {number | bigint} n
9077
+ * @returns {Address6}
9078
+ * @example
9079
+ * new Address6('2001:db8::/64').offset(1).correctForm(); // '2001:db8::1'
9080
+ */
9081
+ offset(n2) {
9082
+ return _Address6.fromBigInt(common.offsetBigInt(this.bigInt(), n2, constants6.BITS, "IPv6")).withSubnetMask(this.subnetMask);
9083
+ }
9084
+ /**
9085
+ * Returns the network that follows this address's network: the address after
9086
+ * {@link endAddress}, with the same subnet mask. Throws `AddressError` when
9087
+ * this network is the last one in the address space.
9088
+ * @returns {Address6}
9089
+ * @example
9090
+ * new Address6('2001:db8::/64').nextNetwork().networkForm(); // '2001:db8:0:1::/64'
9091
+ */
9092
+ nextNetwork() {
9093
+ return _Address6.fromBigInt(common.offsetBigInt(this._endAddress(), 1, constants6.BITS, "IPv6")).withSubnetMask(this.subnetMask);
9094
+ }
9095
+ withSubnetMask(subnetMask) {
9096
+ return new _Address6(`${this.correctForm()}/${subnetMask}`);
9097
+ }
8864
9098
  /**
8865
9099
  * The hex form of the subnet mask, e.g. `ffff:ffff:ffff:ffff::` for a
8866
9100
  * `/64`. Returns an `Address6`; call `.correctForm()` for the string.
@@ -8917,7 +9151,7 @@ var require_ipv6 = __commonJS({
8917
9151
  getType() {
8918
9152
  for (let i2 = 0; i2 < TYPE_SUBNETS.length; i2++) {
8919
9153
  const entry = TYPE_SUBNETS[i2];
8920
- if (this.isInSubnet(entry[0])) {
9154
+ if (this.isHostInSubnet(entry[0])) {
8921
9155
  return entry[1];
8922
9156
  }
8923
9157
  }
@@ -9050,18 +9284,20 @@ var require_ipv6 = __commonJS({
9050
9284
  }
9051
9285
  const groups = address.split(":");
9052
9286
  const lastGroup = groups.slice(-1)[0];
9287
+ const v4Octets = lastGroup.split(".");
9288
+ if (v4Octets.length === constants4.GROUPS && v4Octets.every((octet) => /^\d{1,3}$/.test(octet))) {
9289
+ if (v4Octets.some((octet) => /^0\d/.test(octet))) {
9290
+ const highlighted = v4Octets.map(spanLeadingZeroes4).join(".");
9291
+ const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(":");
9292
+ const separator = groups.length > 1 ? ":" : "";
9293
+ throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`);
9294
+ }
9295
+ }
9053
9296
  const address4 = lastGroup.match(constants4.RE_ADDRESS);
9054
9297
  if (address4) {
9055
9298
  this.parsedAddress4 = address4[0];
9056
- this.address4 = new ipv4_1.Address4(this.parsedAddress4);
9057
- for (let i2 = 0; i2 < this.address4.groups; i2++) {
9058
- if (/^0[0-9]+/.test(this.address4.parsedAddress[i2])) {
9059
- const highlighted = this.address4.parsedAddress.map(spanLeadingZeroes4).join(".");
9060
- const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(":");
9061
- const separator = groups.length > 1 ? ":" : "";
9062
- throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`);
9063
- }
9064
- }
9299
+ const v4Suffix = this.subnetMask >= 96 ? `/${this.subnetMask - 96}` : "";
9300
+ this.address4 = new ipv4_1.Address4(`${this.parsedAddress4}${v4Suffix}`);
9065
9301
  this.v4 = true;
9066
9302
  groups[groups.length - 1] = this.address4.toGroup6();
9067
9303
  address = groups.join(":");
@@ -9145,7 +9381,11 @@ var require_ipv6 = __commonJS({
9145
9381
  return BigInt(`0x${this.parsedAddress.map(paddedHex).join("")}`);
9146
9382
  }
9147
9383
  /**
9148
- * Return the last two groups of this address as an IPv4 address string
9384
+ * Return the last two groups of this address as an IPv4 address string.
9385
+ * If this address carries a CIDR prefix that covers the trailing 32 bits
9386
+ * (i.e. `subnetMask >= 96`), the resulting `Address4` inherits the
9387
+ * corresponding v4 prefix (`subnetMask - 96`); otherwise it defaults to
9388
+ * `/32`.
9149
9389
  * @returns {Address4}
9150
9390
  * @example
9151
9391
  * var address = new Address6('2001:4860:4001::1825:bf11');
@@ -9153,7 +9393,16 @@ var require_ipv6 = __commonJS({
9153
9393
  */
9154
9394
  to4() {
9155
9395
  const binary = this.binaryZeroPad().split("");
9156
- return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join("")}`).toString(16).padStart(8, "0"));
9396
+ const hex3 = BigInt(`0b${binary.slice(96, 128).join("")}`).toString(16).padStart(8, "0");
9397
+ if (this.subnetMask >= 96) {
9398
+ const v4Mask = this.subnetMask - 96;
9399
+ const groups = [];
9400
+ for (let i2 = 0; i2 < 8; i2 += 2) {
9401
+ groups.push(parseInt(hex3.slice(i2, i2 + 2), 16));
9402
+ }
9403
+ return new ipv4_1.Address4(`${groups.join(".")}/${v4Mask}`);
9404
+ }
9405
+ return ipv4_1.Address4.fromHex(hex3);
9157
9406
  }
9158
9407
  /**
9159
9408
  * Return the v4-in-v6 form of the address
@@ -9167,7 +9416,7 @@ var require_ipv6 = __commonJS({
9167
9416
  if (!/:$/.test(correct)) {
9168
9417
  infix = ":";
9169
9418
  }
9170
- return correct + infix + address4.address;
9419
+ return correct + infix + address4.correctForm();
9171
9420
  }
9172
9421
  /**
9173
9422
  * Decodes the Teredo tunneling fields embedded in this address. Returns the
@@ -9257,7 +9506,14 @@ var require_ipv6 = __commonJS({
9257
9506
  bits = prefixBits.slice(0, 96) + v4Bits;
9258
9507
  } else {
9259
9508
  const beforeU = 64 - pl2;
9260
- bits = prefixBits.slice(0, pl2) + v4Bits.slice(0, beforeU) + "00000000" + v4Bits.slice(beforeU) + "0".repeat(128 - 72 - (32 - beforeU));
9509
+ bits = [
9510
+ prefixBits.slice(0, pl2),
9511
+ v4Bits.slice(0, beforeU),
9512
+ // Bits 64 to 71 are the reserved u octet and are always zero.
9513
+ "00000000",
9514
+ v4Bits.slice(beforeU),
9515
+ "0".repeat(128 - 72 - (32 - beforeU))
9516
+ ].join("");
9261
9517
  }
9262
9518
  const hex3 = BigInt(`0b${bits}`).toString(16).padStart(32, "0");
9263
9519
  const groups = [];
@@ -9280,7 +9536,7 @@ var require_ipv6 = __commonJS({
9280
9536
  if (pl2 !== 32 && pl2 !== 40 && pl2 !== 48 && pl2 !== 56 && pl2 !== 64 && pl2 !== 96) {
9281
9537
  throw new address_error_1.AddressError("NAT64 prefix length must be 32, 40, 48, 56, 64, or 96");
9282
9538
  }
9283
- if (!this.isInSubnet(prefix6)) {
9539
+ if (!this.isHostInSubnet(prefix6)) {
9284
9540
  return null;
9285
9541
  }
9286
9542
  const bits = this.binaryZeroPad();
@@ -9304,9 +9560,7 @@ var require_ipv6 = __commonJS({
9304
9560
  * @returns {Array}
9305
9561
  */
9306
9562
  toByteArray() {
9307
- const valueWithoutPadding = this.bigInt().toString(16);
9308
- const leadingPad = "0".repeat(valueWithoutPadding.length % 2);
9309
- const value = `${leadingPad}${valueWithoutPadding}`;
9563
+ const value = this.bigInt().toString(16).padStart(constants6.BITS / 4, "0");
9310
9564
  const bytes2 = [];
9311
9565
  for (let i2 = 0, length = value.length; i2 < length; i2 += 2) {
9312
9566
  bytes2.push(parseInt(value.substring(i2, i2 + 2), 16));
@@ -9325,19 +9579,28 @@ var require_ipv6 = __commonJS({
9325
9579
  /**
9326
9580
  * Convert a byte array to an Address6 object.
9327
9581
  *
9582
+ * Accepts unsigned bytes (0 to 255) or signed bytes (-128 to 127, as an
9583
+ * `Int8Array` or a Java `byte[]` holds them), folding signed values to their
9584
+ * unsigned equivalent. Throws `AddressError` unless given exactly 16
9585
+ * integers from -128 to 255.
9586
+ *
9328
9587
  * To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`.
9329
9588
  * @returns {Address6}
9330
9589
  */
9331
9590
  static fromByteArray(bytes2) {
9591
+ common.assertByteArray(bytes2, 16, "IPv6", -128);
9332
9592
  return this.fromUnsignedByteArray(bytes2.map(unsignByte));
9333
9593
  }
9334
9594
  /**
9335
9595
  * Convert an unsigned byte array to an Address6 object.
9336
9596
  *
9597
+ * Throws `AddressError` unless given exactly 16 integers from 0 to 255.
9598
+ *
9337
9599
  * To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`.
9338
9600
  * @returns {Address6}
9339
9601
  */
9340
9602
  static fromUnsignedByteArray(bytes2) {
9603
+ common.assertByteArray(bytes2, 16, "IPv6", 0);
9341
9604
  const BYTE_MAX = BigInt("256");
9342
9605
  let result = BigInt("0");
9343
9606
  let multiplier = BigInt("1");
@@ -9355,20 +9618,28 @@ var require_ipv6 = __commonJS({
9355
9618
  return this.addressMinusSuffix === this.canonicalForm();
9356
9619
  }
9357
9620
  /**
9358
- * Returns true if the address is a link local address, false otherwise
9621
+ * Returns true if the address is a link-local unicast address in `fe80::/10`
9622
+ * ([RFC 4291 §2.4](https://datatracker.ietf.org/doc/html/rfc4291#section-2.4))
9623
+ * or an IPv4-mapped / NAT64 address whose embedded IPv4 address is link-local
9624
+ * (`169.254.0.0/16`, e.g. `::ffff:169.254.169.254`), false otherwise.
9359
9625
  * @returns {boolean}
9360
9626
  */
9361
9627
  isLinkLocal() {
9362
- if (this.getBitsBase2(0, 64) === "1111111010000000000000000000000000000000000000000000000000000000") {
9363
- return true;
9628
+ const embedded = this.embeddedIPv4();
9629
+ if (embedded) {
9630
+ return embedded.isLinkLocal();
9364
9631
  }
9365
- return false;
9632
+ return this.isHostInSubnet(LINK_LOCAL_SUBNET);
9366
9633
  }
9367
9634
  /**
9368
9635
  * Returns true if the address is a multicast address, false otherwise
9369
9636
  * @returns {boolean}
9370
9637
  */
9371
9638
  isMulticast() {
9639
+ const embedded = this.embeddedIPv4();
9640
+ if (embedded) {
9641
+ return embedded.isMulticast();
9642
+ }
9372
9643
  const type = this.getType();
9373
9644
  return type === "Multicast" || type.startsWith("Multicast ");
9374
9645
  }
@@ -9391,27 +9662,54 @@ var require_ipv6 = __commonJS({
9391
9662
  * @returns {boolean}
9392
9663
  */
9393
9664
  isMapped4() {
9394
- return this.isInSubnet(IPV4_MAPPED_SUBNET);
9665
+ return this.isHostInSubnet(IPV4_MAPPED_SUBNET);
9666
+ }
9667
+ /**
9668
+ * If this address embeds a routable IPv4 address — i.e. it is IPv4-mapped
9669
+ * (`::ffff:0:0/96`) or sits in the NAT64 well-known prefix (`64:ff9b::/96`,
9670
+ * [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052)) — return that
9671
+ * embedded address as an {@link Address4}; otherwise return null.
9672
+ *
9673
+ * The special-property checks (`isLoopback`, `isLinkLocal`, `isMulticast`,
9674
+ * `isUnspecified`, `isPrivate`, `isCGNAT`, `isBroadcast`) call this first and
9675
+ * delegate to the embedded {@link Address4} when present, so a literal such as
9676
+ * `::ffff:127.0.0.1` is classified by what it actually reaches (loopback)
9677
+ * rather than by its IPv6 wrapper (which `getType()` reports as IPv4-mapped).
9678
+ * This matters wherever the checks back a trust-boundary decision (e.g. an
9679
+ * SSRF allow/deny filter): without normalization, `::ffff:10.0.0.1`,
9680
+ * `::ffff:169.254.169.254`, `64:ff9b::7f00:1`, etc. would all read as
9681
+ * non-internal.
9682
+ * @returns {Address4 | null}
9683
+ */
9684
+ embeddedIPv4() {
9685
+ if (this.isMapped4() || this.isHostInSubnet(NAT64_WELL_KNOWN_SUBNET)) {
9686
+ return this.to4();
9687
+ }
9688
+ return null;
9395
9689
  }
9396
9690
  /**
9397
9691
  * Returns true if the address is a Teredo address, false otherwise
9398
9692
  * @returns {boolean}
9399
9693
  */
9400
9694
  isTeredo() {
9401
- return this.isInSubnet(TEREDO_SUBNET);
9695
+ return this.isHostInSubnet(TEREDO_SUBNET);
9402
9696
  }
9403
9697
  /**
9404
9698
  * Returns true if the address is a 6to4 address, false otherwise
9405
9699
  * @returns {boolean}
9406
9700
  */
9407
9701
  is6to4() {
9408
- return this.isInSubnet(SIX_TO_FOUR_SUBNET);
9702
+ return this.isHostInSubnet(SIX_TO_FOUR_SUBNET);
9409
9703
  }
9410
9704
  /**
9411
9705
  * Returns true if the address is a loopback address, false otherwise
9412
9706
  * @returns {boolean}
9413
9707
  */
9414
9708
  isLoopback() {
9709
+ const embedded = this.embeddedIPv4();
9710
+ if (embedded) {
9711
+ return embedded.isLoopback();
9712
+ }
9415
9713
  return this.getType() === "Loopback";
9416
9714
  }
9417
9715
  /**
@@ -9419,13 +9717,72 @@ var require_ipv6 = __commonJS({
9419
9717
  * @returns {boolean}
9420
9718
  */
9421
9719
  isULA() {
9422
- return this.isInSubnet(ULA_SUBNET);
9720
+ return this.isHostInSubnet(ULA_SUBNET);
9721
+ }
9722
+ /**
9723
+ * Returns true if the address is private, i.e. a Unique Local Address in
9724
+ * `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)), an
9725
+ * address in the NAT64 local-use range `64:ff9b:1::/48`
9726
+ * ([RFC 8215](https://datatracker.ietf.org/doc/html/rfc8215)), or an
9727
+ * IPv4-mapped / NAT64 well-known address whose embedded IPv4 address is in
9728
+ * one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918)
9729
+ * private ranges (e.g. `::ffff:10.0.0.1`). This is the IPv6 counterpart to
9730
+ * {@link Address4.isPrivate}; use it instead of {@link isULA} when you need to
9731
+ * catch mapped RFC 1918 addresses as well as native ULAs.
9732
+ *
9733
+ * The local-use NAT64 range is reported private as a whole rather than by
9734
+ * its embedded IPv4 address: an operator may carve a prefix of any RFC 6052
9735
+ * length out of `64:ff9b:1::/48`, so the same bits decode to different IPv4
9736
+ * addresses under different deployments and no single decoding is correct.
9737
+ * Use {@link toAddress4Nat64} with the deployment's prefix to decode one.
9738
+ * @returns {boolean}
9739
+ */
9740
+ isPrivate() {
9741
+ const embedded = this.embeddedIPv4();
9742
+ if (embedded) {
9743
+ return embedded.isPrivate();
9744
+ }
9745
+ return this.isULA() || this.isHostInSubnet(NAT64_LOCAL_USE_SUBNET);
9746
+ }
9747
+ /**
9748
+ * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded
9749
+ * IPv4 address is in the carrier-grade NAT range `100.64.0.0/10`
9750
+ * ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)), false
9751
+ * otherwise. There is no native IPv6 CGNAT range, so this only ever returns
9752
+ * true for an embedded IPv4 address (e.g. `::ffff:100.64.0.1`).
9753
+ * @returns {boolean}
9754
+ */
9755
+ isCGNAT() {
9756
+ const embedded = this.embeddedIPv4();
9757
+ if (embedded) {
9758
+ return embedded.isCGNAT();
9759
+ }
9760
+ return false;
9761
+ }
9762
+ /**
9763
+ * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded
9764
+ * IPv4 address is the limited broadcast address `255.255.255.255`
9765
+ * ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)), false otherwise.
9766
+ * There is no IPv6 broadcast, so this only ever returns true for an embedded
9767
+ * IPv4 address (e.g. `::ffff:255.255.255.255`).
9768
+ * @returns {boolean}
9769
+ */
9770
+ isBroadcast() {
9771
+ const embedded = this.embeddedIPv4();
9772
+ if (embedded) {
9773
+ return embedded.isBroadcast();
9774
+ }
9775
+ return false;
9423
9776
  }
9424
9777
  /**
9425
9778
  * Returns true if the address is the unspecified address `::`.
9426
9779
  * @returns {boolean}
9427
9780
  */
9428
9781
  isUnspecified() {
9782
+ const embedded = this.embeddedIPv4();
9783
+ if (embedded) {
9784
+ return embedded.isUnspecified();
9785
+ }
9429
9786
  return this.getType() === "Unspecified";
9430
9787
  }
9431
9788
  /**
@@ -9433,7 +9790,48 @@ var require_ipv6 = __commonJS({
9433
9790
  * @returns {boolean}
9434
9791
  */
9435
9792
  isDocumentation() {
9436
- return this.isInSubnet(DOCUMENTATION_SUBNET);
9793
+ return DOCUMENTATION_SUBNETS.some((subnet) => this.isHostInSubnet(subnet));
9794
+ }
9795
+ /**
9796
+ * Returns true if the address is in the benchmarking range `2001:2::/48`
9797
+ * ([RFC 5180](https://datatracker.ietf.org/doc/html/rfc5180)) or is an
9798
+ * IPv4-mapped / NAT64 address whose embedded IPv4 address is in
9799
+ * `198.18.0.0/15`, false otherwise.
9800
+ * @returns {boolean}
9801
+ */
9802
+ isBenchmarking() {
9803
+ const embedded = this.embeddedIPv4();
9804
+ if (embedded) {
9805
+ return embedded.isBenchmarking();
9806
+ }
9807
+ return this.isHostInSubnet(BENCHMARKING_SUBNET);
9808
+ }
9809
+ /**
9810
+ * Returns true if the address is globally reachable: inside the global
9811
+ * unicast allocation `2000::/3` (the only range the [IANA IPv6 Address Space
9812
+ * Registry](https://www.iana.org/assignments/ipv6-address-space/) assigns
9813
+ * for global unicast; everything else is reserved, ULA, link-local, or
9814
+ * multicast) and not in any block the [IANA IPv6 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv6-special-registry/)
9815
+ * marks as not globally reachable. An IPv4-mapped or NAT64 well-known
9816
+ * address answers for its embedded IPv4 address, so `::ffff:10.0.0.1` and
9817
+ * `64:ff9b::7f00:1` are not global. Teredo (`2001::/32`) and 6to4
9818
+ * (`2002::/16`) are not global either: the registry lists them as N/A and a
9819
+ * packet to one needs a relay.
9820
+ *
9821
+ * This covers everything the individual classifiers name and the blocks they
9822
+ * do not: the discard-only prefix `100::/64`, the IETF protocol assignments
9823
+ * in `2001::/23`, the deprecated site-local `fec0::/10` and IPv4-compatible
9824
+ * `::/96` ranges, and unallocated space such as `4000::/3`. It is the single
9825
+ * predicate to use where a request must not reach an internal or
9826
+ * special-purpose destination; see SECURITY.md.
9827
+ * @returns {boolean}
9828
+ */
9829
+ isGlobal() {
9830
+ const embedded = this.embeddedIPv4();
9831
+ if (embedded) {
9832
+ return embedded.isGlobal();
9833
+ }
9834
+ return this.isHostInSubnet(GLOBAL_UNICAST_SUBNET) && common.isGloballyReachable.call(this, SPECIAL_PURPOSE_V6);
9437
9835
  }
9438
9836
  // #endregion
9439
9837
  // #region HTML
@@ -9485,7 +9883,12 @@ var require_ipv6 = __commonJS({
9485
9883
  return `<a href="${safeHref}">${safeForm}</a>`;
9486
9884
  }
9487
9885
  /**
9488
- * Groups an address
9886
+ * Groups an address.
9887
+ *
9888
+ * Returns an HTML fragment: each group is wrapped in a `<span>` carrying
9889
+ * the group classes an address-inspector UI hovers on. The address content
9890
+ * is HTML-escaped; anything you concatenate around it is your
9891
+ * responsibility.
9489
9892
  * @returns {String}
9490
9893
  */
9491
9894
  group() {
@@ -9576,8 +9979,17 @@ var require_ipv6 = __commonJS({
9576
9979
  var TEREDO_SUBNET = new Address6("2001::/32");
9577
9980
  var SIX_TO_FOUR_SUBNET = new Address6("2002::/16");
9578
9981
  var ULA_SUBNET = new Address6("fc00::/7");
9579
- var DOCUMENTATION_SUBNET = new Address6("2001:db8::/32");
9982
+ var LINK_LOCAL_SUBNET = new Address6("fe80::/10");
9983
+ var DOCUMENTATION_SUBNETS = [new Address6("2001:db8::/32"), new Address6("3fff::/20")];
9984
+ var BENCHMARKING_SUBNET = new Address6("2001:2::/48");
9985
+ var GLOBAL_UNICAST_SUBNET = new Address6("2000::/3");
9986
+ var SPECIAL_PURPOSE_V6 = constants6.SPECIAL_PURPOSE.map(([cidr, , reachable]) => ({
9987
+ subnet: new Address6(cidr),
9988
+ reachable
9989
+ }));
9580
9990
  var IPV4_MAPPED_SUBNET = new Address6("::ffff:0:0/96");
9991
+ var NAT64_WELL_KNOWN_SUBNET = new Address6("64:ff9b::/96");
9992
+ var NAT64_LOCAL_USE_SUBNET = new Address6("64:ff9b:1::/48");
9581
9993
  }
9582
9994
  });
9583
9995
 
@@ -35793,9 +36205,28 @@ var require_utils3 = __commonJS({
35793
36205
  "use strict";
35794
36206
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
35795
36207
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
36208
+ var isPort = RegExp.prototype.test.bind(/^\d*$/u);
35796
36209
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
35797
36210
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
35798
- var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
36211
+ var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
36212
+ var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
36213
+ var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
36214
+ var BYTE_HEX = new Array(256);
36215
+ {
36216
+ const HEX_DIGITS = "0123456789ABCDEF";
36217
+ for (let i2 = 0; i2 < 256; i2++) {
36218
+ BYTE_HEX[i2] = "%" + HEX_DIGITS[i2 >> 4] + HEX_DIGITS[i2 & 15];
36219
+ }
36220
+ }
36221
+ function percentEncodeNonAscii(cp) {
36222
+ if (cp < 2048) {
36223
+ return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
36224
+ }
36225
+ if (cp < 65536) {
36226
+ return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
36227
+ }
36228
+ return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
36229
+ }
35799
36230
  function stringArrayToHexStripped(input) {
35800
36231
  let acc = "";
35801
36232
  let code = 0;
@@ -35820,91 +36251,105 @@ var require_utils3 = __commonJS({
35820
36251
  }
35821
36252
  return acc;
35822
36253
  }
36254
+ var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
36255
+ var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
36256
+ var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
35823
36257
  var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
35824
- function consumeIsZone(buffer) {
35825
- buffer.length = 0;
35826
- return true;
35827
- }
35828
- function consumeHextets(buffer, address, output) {
35829
- if (buffer.length) {
35830
- const hex3 = stringArrayToHexStripped(buffer);
35831
- if (hex3 !== "") {
35832
- address.push(hex3);
35833
- } else {
35834
- output.error = true;
35835
- return false;
36258
+ function isZoneIdentifier(zone) {
36259
+ if (zone.length === 0) return false;
36260
+ for (let i2 = 0; i2 < zone.length; i2++) {
36261
+ if (isZoneCharacter(zone[i2])) continue;
36262
+ if (zone[i2] === "%" && i2 + 2 < zone.length && isHexPair(zone.slice(i2 + 1, i2 + 3))) {
36263
+ i2 += 2;
36264
+ continue;
35836
36265
  }
35837
- buffer.length = 0;
36266
+ return false;
35838
36267
  }
35839
36268
  return true;
35840
36269
  }
35841
- function getIPV6(input) {
35842
- let tokenCount = 0;
35843
- const output = { error: false, address: "", zone: "" };
35844
- const address = [];
35845
- const buffer = [];
35846
- let endipv6Encountered = false;
35847
- let endIpv6 = false;
35848
- let consume = consumeHextets;
35849
- for (let i2 = 0; i2 < input.length; i2++) {
35850
- const cursor = input[i2];
35851
- if (cursor === "[" || cursor === "]") {
35852
- continue;
35853
- }
35854
- if (cursor === ":") {
35855
- if (endipv6Encountered === true) {
35856
- endIpv6 = true;
35857
- }
35858
- if (!consume(buffer, address, output)) {
35859
- break;
36270
+ function compressIPv6ZeroRun(hextets) {
36271
+ let bestStart = -1;
36272
+ let bestLength = 0;
36273
+ let runStart = -1;
36274
+ let runLength = 0;
36275
+ for (let i2 = 0; i2 < hextets.length; i2++) {
36276
+ if (hextets[i2] === "0") {
36277
+ if (runStart === -1) runStart = i2;
36278
+ runLength++;
36279
+ if (runLength > bestLength) {
36280
+ bestLength = runLength;
36281
+ bestStart = runStart;
35860
36282
  }
35861
- if (++tokenCount > 7) {
35862
- output.error = true;
35863
- break;
35864
- }
35865
- if (i2 > 0 && input[i2 - 1] === ":") {
35866
- endipv6Encountered = true;
35867
- }
35868
- address.push(":");
35869
- continue;
35870
- } else if (cursor === "%") {
35871
- if (!consume(buffer, address, output)) {
35872
- break;
35873
- }
35874
- consume = consumeIsZone;
35875
36283
  } else {
35876
- buffer.push(cursor);
36284
+ runStart = -1;
36285
+ runLength = 0;
36286
+ }
36287
+ }
36288
+ if (bestLength < 2) return hextets.join(":");
36289
+ const head = hextets.slice(0, bestStart).join(":");
36290
+ const tail = hextets.slice(bestStart + bestLength).join(":");
36291
+ return head + "::" + tail;
36292
+ }
36293
+ function normalizeIPv6Address(input) {
36294
+ const compression = input.indexOf("::");
36295
+ if (compression !== -1 && input.indexOf("::", compression + 1) !== -1) return void 0;
36296
+ const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
36297
+ const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
36298
+ if (compression !== -1) {
36299
+ if (left.length === 1 && left[0] === "") left.length = 0;
36300
+ if (right.length === 1 && right[0] === "") right.length = 0;
36301
+ }
36302
+ const parts = left.concat(right);
36303
+ let hextetCount = 0;
36304
+ for (let i2 = 0; i2 < parts.length; i2++) {
36305
+ const part = parts[i2];
36306
+ if (part === "") return void 0;
36307
+ if (part.indexOf(".") !== -1) {
36308
+ if (i2 !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part)) return void 0;
36309
+ hextetCount += 2;
35877
36310
  continue;
35878
36311
  }
36312
+ if (!isHextet(part)) return void 0;
36313
+ parts[i2] = parseInt(part, 16).toString(16);
36314
+ hextetCount++;
35879
36315
  }
35880
- if (buffer.length) {
35881
- if (consume === consumeIsZone) {
35882
- output.zone = buffer.join("");
35883
- } else if (endIpv6) {
35884
- address.push(buffer.join(""));
35885
- } else {
35886
- address.push(stringArrayToHexStripped(buffer));
35887
- }
36316
+ if (compression === -1) {
36317
+ if (hextetCount !== 8) return void 0;
36318
+ return compressIPv6ZeroRun(parts);
35888
36319
  }
35889
- output.address = address.join("");
35890
- return output;
36320
+ if (hextetCount >= 8) return void 0;
36321
+ const expanded = parts.slice(0, left.length);
36322
+ for (let i2 = hextetCount; i2 < 8; i2++) expanded.push("0");
36323
+ for (let i2 = left.length; i2 < parts.length; i2++) expanded.push(parts[i2]);
36324
+ return compressIPv6ZeroRun(expanded);
35891
36325
  }
35892
36326
  function normalizeIPv6(host) {
35893
- if (findToken(host, ":") < 2) {
35894
- return { host, isIPV6: false };
35895
- }
35896
- const ipv63 = getIPV6(host);
35897
- if (!ipv63.error) {
35898
- let newHost = ipv63.address;
35899
- let escapedHost = ipv63.address;
35900
- if (ipv63.zone) {
35901
- newHost += "%" + ipv63.zone;
35902
- escapedHost += "%25" + ipv63.zone;
35903
- }
35904
- return { host: newHost, isIPV6: true, escapedHost };
35905
- } else {
35906
- return { host, isIPV6: false };
35907
- }
36327
+ const bracketed = host[0] === "[" && host[host.length - 1] === "]";
36328
+ const hasBracket = host[0] === "[" || host[host.length - 1] === "]";
36329
+ if (hasBracket && !bracketed) return { host, isIPV6: false, error: true };
36330
+ let input = bracketed ? host.slice(1, -1) : host;
36331
+ if (bracketed && isIPvFuture(input)) {
36332
+ input = input.toLowerCase();
36333
+ return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
36334
+ }
36335
+ if (findToken(input, ":") < 2) {
36336
+ return { host, isIPV6: false, error: bracketed };
36337
+ }
36338
+ let zoneIdentifier = "";
36339
+ const zoneSeparator = input.indexOf("%");
36340
+ if (zoneSeparator !== -1) {
36341
+ const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
36342
+ zoneIdentifier = input.slice(zoneSeparator + separatorLength);
36343
+ if (!isZoneIdentifier(zoneIdentifier)) return { host, isIPV6: false, error: true };
36344
+ input = input.slice(0, zoneSeparator);
36345
+ }
36346
+ const address = normalizeIPv6Address(input);
36347
+ if (address === void 0) return { host, isIPV6: false, error: true };
36348
+ return {
36349
+ host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
36350
+ escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
36351
+ isIPV6: true
36352
+ };
35908
36353
  }
35909
36354
  function findToken(str, token) {
35910
36355
  let ind = 0;
@@ -36023,7 +36468,8 @@ var require_utils3 = __commonJS({
36023
36468
  function normalizePathEncoding(input) {
36024
36469
  let output = "";
36025
36470
  for (let i2 = 0; i2 < input.length; i2++) {
36026
- if (input[i2] === "%" && i2 + 2 < input.length) {
36471
+ const ch = input[i2];
36472
+ if (ch === "%" && i2 + 2 < input.length) {
36027
36473
  const hex3 = input.slice(i2 + 1, i2 + 3);
36028
36474
  if (isHexPair(hex3)) {
36029
36475
  const normalizedHex = hex3.toUpperCase();
@@ -36037,10 +36483,152 @@ var require_utils3 = __commonJS({
36037
36483
  continue;
36038
36484
  }
36039
36485
  }
36040
- if (isPathCharacter(input[i2])) {
36041
- output += input[i2];
36486
+ if (isPathCharacter(ch)) {
36487
+ output += ch;
36488
+ } else {
36489
+ const code = input.charCodeAt(i2);
36490
+ if (code < 128) {
36491
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
36492
+ } else if (code < 55296 || code > 57343) {
36493
+ output += percentEncodeNonAscii(code);
36494
+ } else if (code <= 56319 && i2 + 1 < input.length) {
36495
+ const low = input.charCodeAt(i2 + 1);
36496
+ if (low >= 56320 && low <= 57343) {
36497
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
36498
+ i2++;
36499
+ } else {
36500
+ output += percentEncodeNonAscii(65533);
36501
+ }
36502
+ } else {
36503
+ output += percentEncodeNonAscii(65533);
36504
+ }
36505
+ }
36506
+ }
36507
+ return output;
36508
+ }
36509
+ function serializePathEncoding(input, pathNoScheme = false) {
36510
+ let output = "";
36511
+ let firstSegment = pathNoScheme && input[0] !== "/";
36512
+ for (let i2 = 0; i2 < input.length; i2++) {
36513
+ const ch = input[i2];
36514
+ if (ch === "%" && i2 + 2 < input.length) {
36515
+ const hex3 = input.slice(i2 + 1, i2 + 3);
36516
+ if (isHexPair(hex3)) {
36517
+ output += "%" + hex3.toUpperCase();
36518
+ i2 += 2;
36519
+ continue;
36520
+ }
36521
+ }
36522
+ if (ch === "/") {
36523
+ firstSegment = false;
36524
+ }
36525
+ if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) {
36526
+ output += ch;
36527
+ } else {
36528
+ const code = input.charCodeAt(i2);
36529
+ if (code < 128) {
36530
+ output += BYTE_HEX[code];
36531
+ } else if (code < 55296 || code > 57343) {
36532
+ output += percentEncodeNonAscii(code);
36533
+ } else if (code <= 56319 && i2 + 1 < input.length) {
36534
+ const low = input.charCodeAt(i2 + 1);
36535
+ if (low >= 56320 && low <= 57343) {
36536
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
36537
+ i2++;
36538
+ } else {
36539
+ output += percentEncodeNonAscii(65533);
36540
+ }
36541
+ } else {
36542
+ output += percentEncodeNonAscii(65533);
36543
+ }
36544
+ }
36545
+ }
36546
+ return output;
36547
+ }
36548
+ function encodeComponent(input, isAllowed) {
36549
+ let output = "";
36550
+ for (let i2 = 0; i2 < input.length; i2++) {
36551
+ const ch = input[i2];
36552
+ if (ch === "%" && i2 + 2 < input.length) {
36553
+ const hex3 = input.slice(i2 + 1, i2 + 3);
36554
+ if (isHexPair(hex3)) {
36555
+ output += "%" + hex3.toUpperCase();
36556
+ i2 += 2;
36557
+ continue;
36558
+ }
36559
+ }
36560
+ if (isAllowed(ch)) {
36561
+ output += ch;
36562
+ } else {
36563
+ const code = input.charCodeAt(i2);
36564
+ if (code < 128) {
36565
+ output += BYTE_HEX[code];
36566
+ } else if (code < 55296 || code > 57343) {
36567
+ output += percentEncodeNonAscii(code);
36568
+ } else if (code <= 56319 && i2 + 1 < input.length) {
36569
+ const low = input.charCodeAt(i2 + 1);
36570
+ if (low >= 56320 && low <= 57343) {
36571
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
36572
+ i2++;
36573
+ } else {
36574
+ output += percentEncodeNonAscii(65533);
36575
+ }
36576
+ } else {
36577
+ output += percentEncodeNonAscii(65533);
36578
+ }
36579
+ }
36580
+ }
36581
+ return output;
36582
+ }
36583
+ function encodeUserinfo(input) {
36584
+ return encodeComponent(input, isUserinfoCharacter);
36585
+ }
36586
+ function encodeQuery(input) {
36587
+ return encodeComponent(input, isQueryFragmentCharacter);
36588
+ }
36589
+ function encodeFragment(input) {
36590
+ return encodeComponent(input, isQueryFragmentCharacter);
36591
+ }
36592
+ function isEscapeSafe(cp) {
36593
+ return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
36594
+ }
36595
+ function normalizeQueryFragmentEncoding(input) {
36596
+ let output = "";
36597
+ for (let i2 = 0; i2 < input.length; i2++) {
36598
+ const ch = input[i2];
36599
+ if (ch === "%" && i2 + 2 < input.length) {
36600
+ const hex3 = input.slice(i2 + 1, i2 + 3);
36601
+ if (isHexPair(hex3)) {
36602
+ const normalizedHex = hex3.toUpperCase();
36603
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
36604
+ if (isUnreserved(decoded)) {
36605
+ output += decoded;
36606
+ } else {
36607
+ output += "%" + normalizedHex;
36608
+ }
36609
+ i2 += 2;
36610
+ continue;
36611
+ }
36612
+ }
36613
+ if (isQueryFragmentCharacter(ch)) {
36614
+ output += ch;
36042
36615
  } else {
36043
- output += escape(input[i2]);
36616
+ const code = input.charCodeAt(i2);
36617
+ if (code < 128) {
36618
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
36619
+ } else if (code < 55296 || code > 57343) {
36620
+ output += percentEncodeNonAscii(code);
36621
+ } else if (code <= 56319 && i2 + 1 < input.length) {
36622
+ const low = input.charCodeAt(i2 + 1);
36623
+ if (low >= 56320 && low <= 57343) {
36624
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
36625
+ i2++;
36626
+ } else {
36627
+ output += percentEncodeNonAscii(65533);
36628
+ }
36629
+ } else {
36630
+ output += percentEncodeNonAscii(65533);
36631
+ }
36044
36632
  }
36045
36633
  }
36046
36634
  return output;
@@ -36063,14 +36651,18 @@ var require_utils3 = __commonJS({
36063
36651
  function recomposeAuthority(component) {
36064
36652
  const uriTokens = [];
36065
36653
  if (component.userinfo !== void 0) {
36066
- uriTokens.push(component.userinfo);
36654
+ uriTokens.push(encodeUserinfo(component.userinfo));
36067
36655
  uriTokens.push("@");
36068
36656
  }
36069
36657
  if (component.host !== void 0) {
36070
- let host = unescape(component.host);
36658
+ let host = component.host;
36071
36659
  if (!isIPv4(host)) {
36072
- const ipV6res = normalizeIPv6(host);
36073
- if (ipV6res.isIPV6 === true) {
36660
+ let ipV6res = normalizeIPv6(host);
36661
+ if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
36662
+ host = normalizePercentEncoding(host, true);
36663
+ ipV6res = normalizeIPv6(host);
36664
+ }
36665
+ if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
36074
36666
  host = `[${ipV6res.escapedHost}]`;
36075
36667
  } else {
36076
36668
  host = reescapeHostDelimiters(host, false);
@@ -36079,8 +36671,12 @@ var require_utils3 = __commonJS({
36079
36671
  uriTokens.push(host);
36080
36672
  }
36081
36673
  if (typeof component.port === "number" || typeof component.port === "string") {
36674
+ const port = String(component.port);
36675
+ if (!isPort(port)) {
36676
+ throw new TypeError("URI port is malformed.");
36677
+ }
36082
36678
  uriTokens.push(":");
36083
- uriTokens.push(String(component.port));
36679
+ uriTokens.push(port);
36084
36680
  }
36085
36681
  return uriTokens.length ? uriTokens.join("") : void 0;
36086
36682
  }
@@ -36090,6 +36686,11 @@ var require_utils3 = __commonJS({
36090
36686
  reescapeHostDelimiters,
36091
36687
  normalizePercentEncoding,
36092
36688
  normalizePathEncoding,
36689
+ serializePathEncoding,
36690
+ normalizeQueryFragmentEncoding,
36691
+ encodeUserinfo,
36692
+ encodeQuery,
36693
+ encodeFragment,
36093
36694
  escapePreservingEscapes,
36094
36695
  removeDotSegments,
36095
36696
  isIPv4,
@@ -36105,7 +36706,7 @@ var require_schemes = __commonJS({
36105
36706
  "node_modules/fast-uri/lib/schemes.js"(exports2, module2) {
36106
36707
  "use strict";
36107
36708
  var { isUUID } = require_utils3();
36108
- var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
36709
+ var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
36109
36710
  var supportedSchemeNames = (
36110
36711
  /** @type {const} */
36111
36712
  [
@@ -36166,9 +36767,10 @@ var require_schemes = __commonJS({
36166
36767
  wsComponent.secure = void 0;
36167
36768
  }
36168
36769
  if (wsComponent.resourceName) {
36169
- const [path4, query] = wsComponent.resourceName.split("?");
36770
+ const queryIndex = wsComponent.resourceName.indexOf("?");
36771
+ const path4 = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
36170
36772
  wsComponent.path = path4 && path4 !== "/" ? path4 : void 0;
36171
- wsComponent.query = query;
36773
+ wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
36172
36774
  wsComponent.resourceName = void 0;
36173
36775
  }
36174
36776
  wsComponent.fragment = void 0;
@@ -36180,7 +36782,7 @@ var require_schemes = __commonJS({
36180
36782
  return urnComponent;
36181
36783
  }
36182
36784
  const matches = urnComponent.path.match(URN_REG);
36183
- if (matches) {
36785
+ if (matches && matches[0] === urnComponent.path) {
36184
36786
  const scheme = options2.scheme || urnComponent.scheme || "urn";
36185
36787
  urnComponent.nid = matches[1].toLowerCase();
36186
36788
  urnComponent.nss = matches[2];
@@ -36314,8 +36916,17 @@ var require_schemes = __commonJS({
36314
36916
  var require_fast_uri = __commonJS({
36315
36917
  "node_modules/fast-uri/index.js"(exports2, module2) {
36316
36918
  "use strict";
36317
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils3();
36919
+ var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils3();
36318
36920
  var { SCHEMES, getSchemeHandler } = require_schemes();
36921
+ var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
36922
+ var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
36923
+ function decodeValidScheme(scheme) {
36924
+ const decodedScheme = unescape(String(scheme));
36925
+ if (!VALID_SCHEME.test(decodedScheme)) {
36926
+ throw new TypeError(MALFORMED_SCHEME_ERROR);
36927
+ }
36928
+ return decodedScheme;
36929
+ }
36319
36930
  function normalize2(uri, options2) {
36320
36931
  if (typeof uri === "string") {
36321
36932
  uri = /** @type {T} */
@@ -36328,7 +36939,34 @@ var require_fast_uri = __commonJS({
36328
36939
  }
36329
36940
  function resolve3(baseURI, relativeURI, options2) {
36330
36941
  const schemelessOptions = options2 ? Object.assign({ scheme: "null" }, options2) : { scheme: "null" };
36331
- const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
36942
+ const {
36943
+ parsed: baseParsed,
36944
+ malformedAuthorityOrPort: baseMalformed,
36945
+ malformedPercentEncoding: baseMalformedPercentEncoding,
36946
+ malformedSchemeSpecific: baseMalformedSchemeSpecific,
36947
+ malformedHost: baseMalformedHost,
36948
+ malformedScheme: baseMalformedScheme
36949
+ } = parseWithStatus(baseURI, schemelessOptions);
36950
+ const {
36951
+ parsed: relativeParsed,
36952
+ malformedAuthorityOrPort: relativeMalformed,
36953
+ malformedPercentEncoding: relativeMalformedPercentEncoding,
36954
+ malformedSchemeSpecific: relativeMalformedSchemeSpecific,
36955
+ malformedHost: relativeMalformedHost,
36956
+ malformedScheme: relativeMalformedScheme
36957
+ } = parseWithStatus(relativeURI, schemelessOptions);
36958
+ if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
36959
+ throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
36960
+ }
36961
+ const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
36962
+ const resolvedSchemeHandler = getSchemeHandler(options2 && options2.scheme || resolved.scheme);
36963
+ const resolvedHost = resolved.host;
36964
+ const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
36965
+ canonicalizeHost(resolved, options2 || {}, resolvedSchemeHandler, resolvedHostIsIP);
36966
+ const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !new RegExp("\\P{ASCII}", "u").test(resolvedHost);
36967
+ if (resolved.error && !encodedASCIIHost) {
36968
+ throw new Error(resolved.error);
36969
+ }
36332
36970
  schemelessOptions.skipEscape = true;
36333
36971
  return serialize(resolved, schemelessOptions);
36334
36972
  }
@@ -36388,7 +37026,7 @@ var require_fast_uri = __commonJS({
36388
37026
  function equal(uriA, uriB, options2) {
36389
37027
  const normalizedA = normalizeComparableURI(uriA, options2);
36390
37028
  const normalizedB = normalizeComparableURI(uriB, options2);
36391
- return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA.toLowerCase() === normalizedB.toLowerCase();
37029
+ return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
36392
37030
  }
36393
37031
  function serialize(cmpts, opts) {
36394
37032
  const component = {
@@ -36409,19 +37047,22 @@ var require_fast_uri = __commonJS({
36409
37047
  };
36410
37048
  const options2 = Object.assign({}, opts);
36411
37049
  const uriTokens = [];
37050
+ if (component.scheme) {
37051
+ component.scheme = decodeValidScheme(component.scheme);
37052
+ }
36412
37053
  const schemeHandler = getSchemeHandler(options2.scheme || component.scheme);
36413
37054
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options2);
37055
+ const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
37056
+ const pathNoScheme = !options2.skipEscape && component.scheme === void 0 && !hasAuthority;
36414
37057
  if (component.path !== void 0) {
36415
37058
  if (!options2.skipEscape) {
36416
- component.path = escapePreservingEscapes(component.path);
36417
- if (component.scheme !== void 0) {
36418
- component.path = component.path.split("%3A").join(":");
36419
- }
37059
+ component.path = serializePathEncoding(component.path, pathNoScheme);
36420
37060
  } else {
36421
37061
  component.path = normalizePercentEncoding(component.path);
36422
37062
  }
36423
37063
  }
36424
37064
  if (options2.reference !== "suffix" && component.scheme) {
37065
+ component.scheme = decodeValidScheme(component.scheme);
36425
37066
  uriTokens.push(component.scheme, ":");
36426
37067
  }
36427
37068
  const authority = recomposeAuthority(component);
@@ -36439,20 +37080,25 @@ var require_fast_uri = __commonJS({
36439
37080
  if (!options2.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
36440
37081
  s = removeDotSegments(s);
36441
37082
  }
37083
+ if (pathNoScheme) {
37084
+ s = serializePathEncoding(s, true);
37085
+ }
36442
37086
  if (authority === void 0 && s[0] === "/" && s[1] === "/") {
36443
37087
  s = "/%2F" + s.slice(2);
36444
37088
  }
36445
37089
  uriTokens.push(s);
36446
37090
  }
36447
37091
  if (component.query !== void 0) {
36448
- uriTokens.push("?", component.query);
37092
+ uriTokens.push("?", encodeQuery(component.query));
36449
37093
  }
36450
37094
  if (component.fragment !== void 0) {
36451
- uriTokens.push("#", component.fragment);
37095
+ uriTokens.push("#", encodeFragment(component.fragment));
36452
37096
  }
36453
37097
  return uriTokens.join("");
36454
37098
  }
36455
37099
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
37100
+ var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
37101
+ var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
36456
37102
  function getParseError(parsed, matches) {
36457
37103
  if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
36458
37104
  return 'URI path must start with "/" when authority is present.';
@@ -36462,6 +37108,35 @@ var require_fast_uri = __commonJS({
36462
37108
  }
36463
37109
  return void 0;
36464
37110
  }
37111
+ function hasMalformedPercentEncoding(component) {
37112
+ if (component === void 0) return false;
37113
+ let percent = component.indexOf("%");
37114
+ while (percent !== -1) {
37115
+ if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
37116
+ return true;
37117
+ }
37118
+ percent = component.indexOf("%", percent + 3);
37119
+ }
37120
+ return false;
37121
+ }
37122
+ function isIPLiteral(host) {
37123
+ return host[0] === "[" && host[host.length - 1] === "]";
37124
+ }
37125
+ function hasMalformedComponentPercentEncoding(matches) {
37126
+ const host = matches[4];
37127
+ return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
37128
+ }
37129
+ function canonicalizeHost(parsed, options2, schemeHandler, isIP3) {
37130
+ if (!options2.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options2.domainHost || schemeHandler && schemeHandler.domainHost) && isIP3 === false && nonSimpleDomain(parsed.host)) {
37131
+ try {
37132
+ parsed.host = new URL("http://" + parsed.host).hostname;
37133
+ } catch (e) {
37134
+ parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
37135
+ return true;
37136
+ }
37137
+ }
37138
+ return false;
37139
+ }
36465
37140
  function parseWithStatus(uri, opts) {
36466
37141
  const options2 = Object.assign({}, opts);
36467
37142
  const parsed = {
@@ -36474,6 +37149,11 @@ var require_fast_uri = __commonJS({
36474
37149
  fragment: void 0
36475
37150
  };
36476
37151
  let malformedAuthorityOrPort = false;
37152
+ let malformedPercentEncoding = false;
37153
+ let malformedSchemeSpecific = false;
37154
+ let malformedHost = false;
37155
+ let malformedIPLiteral = false;
37156
+ let malformedScheme = false;
36477
37157
  let isIP3 = false;
36478
37158
  if (options2.reference === "suffix") {
36479
37159
  if (options2.scheme) {
@@ -36482,6 +37162,25 @@ var require_fast_uri = __commonJS({
36482
37162
  uri = "//" + uri;
36483
37163
  }
36484
37164
  }
37165
+ const authorityMatch = uri.match(AUTHORITY_PREFIX);
37166
+ if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
37167
+ parsed.error = "URI authority must not contain a literal backslash.";
37168
+ malformedAuthorityOrPort = true;
37169
+ }
37170
+ const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
37171
+ if (introducerMatch !== null) {
37172
+ const region = introducerMatch[1];
37173
+ const normalizedRegion = region.replace(/[\t\n\r]/g, "");
37174
+ if (normalizedRegion.length >= 2) {
37175
+ if (normalizedRegion.slice(0, 2) !== "//") {
37176
+ parsed.error = parsed.error || "URI authority must not contain a literal backslash.";
37177
+ malformedAuthorityOrPort = true;
37178
+ } else if (region.length !== normalizedRegion.length) {
37179
+ parsed.error = parsed.error || "URI authority introducer must not contain whitespace.";
37180
+ malformedAuthorityOrPort = true;
37181
+ }
37182
+ }
37183
+ }
36485
37184
  const matches = uri.match(URI_PARSE);
36486
37185
  if (matches) {
36487
37186
  parsed.scheme = matches[1];
@@ -36491,6 +37190,19 @@ var require_fast_uri = __commonJS({
36491
37190
  parsed.path = matches[6] || "";
36492
37191
  parsed.query = matches[7];
36493
37192
  parsed.fragment = matches[8];
37193
+ if (parsed.scheme !== void 0) {
37194
+ const decodedScheme = unescape(parsed.scheme);
37195
+ if (VALID_SCHEME.test(decodedScheme)) {
37196
+ parsed.scheme = decodedScheme.toLowerCase();
37197
+ } else {
37198
+ parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
37199
+ malformedScheme = true;
37200
+ }
37201
+ }
37202
+ malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
37203
+ if (malformedPercentEncoding) {
37204
+ parsed.error = parsed.error || "URI contains malformed percent-encoding.";
37205
+ }
36494
37206
  if (isNaN(parsed.port)) {
36495
37207
  parsed.port = matches[5];
36496
37208
  }
@@ -36502,9 +37214,16 @@ var require_fast_uri = __commonJS({
36502
37214
  if (parsed.host) {
36503
37215
  const ipv4result = isIPv4(parsed.host);
36504
37216
  if (ipv4result === false) {
37217
+ const bracketedIPLiteral = isIPLiteral(parsed.host);
37218
+ const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
36505
37219
  const ipv6result = normalizeIPv6(parsed.host);
36506
- parsed.host = ipv6result.host.toLowerCase();
36507
- isIP3 = ipv6result.isIPV6;
37220
+ isIP3 = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
37221
+ malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
37222
+ parsed.host = isIP3 ? ipv6result.host : ipv6result.host.toLowerCase();
37223
+ if (malformedIPLiteral) {
37224
+ parsed.error = parsed.error || "URI host is malformed.";
37225
+ malformedAuthorityOrPort = true;
37226
+ }
36508
37227
  } else {
36509
37228
  isIP3 = true;
36510
37229
  }
@@ -36522,42 +37241,36 @@ var require_fast_uri = __commonJS({
36522
37241
  parsed.error = parsed.error || "URI is not a " + options2.reference + " reference.";
36523
37242
  }
36524
37243
  const schemeHandler = getSchemeHandler(options2.scheme || parsed.scheme);
36525
- if (!options2.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
36526
- if (parsed.host && (options2.domainHost || schemeHandler && schemeHandler.domainHost) && isIP3 === false && nonSimpleDomain(parsed.host)) {
36527
- try {
36528
- parsed.host = new URL("http://" + parsed.host).hostname;
36529
- } catch (e) {
36530
- parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
36531
- }
36532
- }
37244
+ if (!malformedIPLiteral) {
37245
+ malformedHost = canonicalizeHost(parsed, options2, schemeHandler, isIP3);
36533
37246
  }
36534
37247
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
36535
37248
  if (uri.indexOf("%") !== -1) {
36536
- if (parsed.scheme !== void 0) {
36537
- parsed.scheme = unescape(parsed.scheme);
36538
- }
36539
- if (parsed.host !== void 0) {
36540
- parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP3);
37249
+ if (parsed.host !== void 0 && !malformedIPLiteral) {
37250
+ const host = isIP3 ? parsed.host : normalizePercentEncoding(parsed.host, true);
37251
+ parsed.host = reescapeHostDelimiters(host, isIP3);
36541
37252
  }
36542
37253
  }
36543
37254
  if (parsed.path) {
36544
37255
  parsed.path = normalizePathEncoding(parsed.path);
36545
37256
  }
37257
+ if (parsed.query) {
37258
+ parsed.query = normalizeQueryFragmentEncoding(parsed.query);
37259
+ }
36546
37260
  if (parsed.fragment) {
36547
- try {
36548
- parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
36549
- } catch {
36550
- parsed.error = parsed.error || "URI malformed";
36551
- }
37261
+ parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
36552
37262
  }
36553
37263
  }
36554
37264
  if (schemeHandler && schemeHandler.parse) {
36555
37265
  schemeHandler.parse(parsed, options2);
37266
+ if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) {
37267
+ malformedSchemeSpecific = true;
37268
+ }
36556
37269
  }
36557
37270
  } else {
36558
37271
  parsed.error = parsed.error || "URI can not be parsed.";
36559
37272
  }
36560
- return { parsed, malformedAuthorityOrPort };
37273
+ return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
36561
37274
  }
36562
37275
  function parse3(uri, opts) {
36563
37276
  return parseWithStatus(uri, opts).parsed;
@@ -36566,20 +37279,28 @@ var require_fast_uri = __commonJS({
36566
37279
  return normalizeStringWithStatus(uri, opts).normalized;
36567
37280
  }
36568
37281
  function normalizeStringWithStatus(uri, opts) {
36569
- const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
37282
+ const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
36570
37283
  return {
36571
- normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
36572
- malformedAuthorityOrPort
37284
+ normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
37285
+ malformedAuthorityOrPort,
37286
+ malformedPercentEncoding,
37287
+ malformedSchemeSpecific,
37288
+ malformedHost,
37289
+ malformedScheme
36573
37290
  };
36574
37291
  }
36575
37292
  function normalizeComparableURI(uri, opts) {
36576
- if (typeof uri === "string") {
36577
- const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
36578
- return malformedAuthorityOrPort ? void 0 : normalized;
37293
+ if (typeof uri !== "string" && typeof uri !== "object") {
37294
+ return void 0;
36579
37295
  }
36580
- if (typeof uri === "object") {
36581
- return serialize(uri, opts);
37296
+ let value;
37297
+ try {
37298
+ value = typeof uri === "string" ? uri : serialize(uri, opts);
37299
+ } catch {
37300
+ return void 0;
36582
37301
  }
37302
+ const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
37303
+ return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
36583
37304
  }
36584
37305
  var fastUri = {
36585
37306
  SCHEMES,