@sip-protocol/sdk 0.9.0 → 0.11.0

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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{TransportWebUSB-YQMAGJAJ.mjs → TransportWebUSB-2KITI5HD.mjs} +24 -12
  3. package/dist/browser.d.mts +4 -4
  4. package/dist/browser.d.ts +4 -4
  5. package/dist/browser.js +1363 -844
  6. package/dist/browser.mjs +13 -3
  7. package/dist/{chunk-64AYA5F5.mjs → chunk-7IUKXWDN.mjs} +229 -148
  8. package/dist/{chunk-4GRJ5MAW.mjs → chunk-KXETSSKP.mjs} +4 -0
  9. package/dist/{chunk-6EU6WQFK.mjs → chunk-L4RKPNIJ.mjs} +266 -239
  10. package/dist/{constants-LHAAUC2T.mjs → constants-DCJYTIU3.mjs} +5 -1
  11. package/dist/{dist-2OGQ7FED.mjs → dist-PYEXZNFD.mjs} +609 -221
  12. package/dist/{index-DeE1ZzA4.d.mts → index-Cwo3WhxX.d.mts} +128 -37
  13. package/dist/{index-DXh2IGkz.d.ts → index-X8qPQdp6.d.ts} +128 -37
  14. package/dist/index.d.mts +3 -3
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +1356 -837
  17. package/dist/index.mjs +13 -3
  18. package/dist/{interface-Bf7w1PLW.d.mts → interface-CQi0-WfS.d.mts} +2 -2
  19. package/dist/{interface-Bf7w1PLW.d.ts → interface-CQi0-WfS.d.ts} +2 -2
  20. package/dist/{noir-kzbLVTei.d.mts → noir-CwPIyBLj.d.mts} +1 -1
  21. package/dist/{noir-kzbLVTei.d.ts → noir-CwPIyBLj.d.ts} +1 -1
  22. package/dist/proofs/halo2.d.mts +1 -1
  23. package/dist/proofs/halo2.d.ts +1 -1
  24. package/dist/proofs/kimchi.d.mts +1 -1
  25. package/dist/proofs/kimchi.d.ts +1 -1
  26. package/dist/proofs/noir.d.mts +1 -1
  27. package/dist/proofs/noir.d.ts +1 -1
  28. package/dist/{solana-U3MEGU7W.mjs → solana-7QOA3HBZ.mjs} +6 -6
  29. package/package.json +32 -32
  30. package/src/adapters/gelato-relay.ts +386 -0
  31. package/src/adapters/index.ts +28 -0
  32. package/src/adapters/oneinch.ts +126 -0
  33. package/src/chains/ethereum/index.ts +2 -0
  34. package/src/chains/ethereum/privacy-adapter.ts +64 -5
  35. package/src/chains/ethereum/stealth.ts +89 -14
  36. package/src/chains/ethereum/types.ts +18 -2
  37. package/src/chains/near/constants.ts +13 -1
  38. package/src/chains/near/index.ts +2 -0
  39. package/src/chains/near/privacy-adapter.ts +8 -5
  40. package/src/chains/near/resolver.ts +24 -10
  41. package/src/chains/near/stealth.ts +9 -9
  42. package/src/chains/near/types.ts +20 -9
  43. package/src/chains/solana/constants.ts +13 -1
  44. package/src/chains/solana/ephemeral-keys.ts +3 -257
  45. package/src/chains/solana/index.ts +2 -3
  46. package/src/chains/solana/providers/helius-enhanced.ts +6 -6
  47. package/src/chains/solana/providers/webhook.ts +2 -2
  48. package/src/chains/solana/scan.ts +9 -8
  49. package/src/chains/solana/stealth-scanner.ts +3 -3
  50. package/src/chains/solana/transfer.ts +1 -1
  51. package/src/chains/solana/types.ts +18 -4
  52. package/src/cosmos/ibc-stealth.ts +6 -6
  53. package/src/index.ts +6 -0
  54. package/src/move/aptos.ts +15 -9
  55. package/src/move/sui.ts +15 -9
  56. package/src/nft/private-nft.ts +10 -6
  57. package/src/privacy-backends/shadowwire.ts +13 -0
  58. package/src/stealth/ed25519.ts +173 -12
  59. package/src/stealth/index.ts +47 -4
  60. package/src/stealth/secp256k1.ts +157 -9
  61. package/src/stealth.ts +7 -0
  62. package/src/wallet/ethereum/privacy-adapter.ts +1 -1
  63. package/src/wallet/hardware/ledger-privacy.ts +2 -2
  64. package/src/wallet/near/adapter.ts +2 -2
  65. package/src/wallet/near/meteor-wallet.ts +2 -2
  66. package/src/wallet/near/my-near-wallet.ts +2 -2
  67. package/src/wallet/near/wallet-selector.ts +2 -2
  68. package/src/wallet/solana/privacy-adapter.ts +9 -9
  69. package/dist/chunk-5EKF243P.mjs +0 -33809
  70. package/dist/chunk-YWGJ77A2.mjs +0 -33806
@@ -1374,16 +1374,35 @@ var require_util = __commonJS({
1374
1374
  }
1375
1375
  });
1376
1376
 
1377
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/common.js
1377
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/address-error.js
1378
+ var require_address_error = __commonJS({
1379
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/address-error.js"(exports) {
1380
+ "use strict";
1381
+ Object.defineProperty(exports, "__esModule", { value: true });
1382
+ exports.AddressError = void 0;
1383
+ var AddressError = class extends Error {
1384
+ constructor(message, parseMessage) {
1385
+ super(message);
1386
+ this.name = "AddressError";
1387
+ this.parseMessage = parseMessage;
1388
+ }
1389
+ };
1390
+ exports.AddressError = AddressError;
1391
+ }
1392
+ });
1393
+
1394
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/common.js
1378
1395
  var require_common = __commonJS({
1379
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/common.js"(exports) {
1396
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/common.js"(exports) {
1380
1397
  "use strict";
1381
1398
  Object.defineProperty(exports, "__esModule", { value: true });
1382
1399
  exports.isInSubnet = isInSubnet;
1383
1400
  exports.isCorrect = isCorrect;
1401
+ exports.prefixLengthFromMask = prefixLengthFromMask;
1384
1402
  exports.numberToPaddedHex = numberToPaddedHex;
1385
1403
  exports.stringToPaddedHex = stringToPaddedHex;
1386
1404
  exports.testBit = testBit;
1405
+ var address_error_1 = require_address_error();
1387
1406
  function isInSubnet(address) {
1388
1407
  if (this.subnetMask < address.subnetMask) {
1389
1408
  return false;
@@ -1404,6 +1423,20 @@ var require_common = __commonJS({
1404
1423
  return this.parsedSubnet === String(this.subnetMask);
1405
1424
  };
1406
1425
  }
1426
+ function prefixLengthFromMask(value, totalBits) {
1427
+ const binary = value.toString(2).padStart(totalBits, "0");
1428
+ if (binary.length > totalBits) {
1429
+ throw new address_error_1.AddressError("Invalid subnet mask.");
1430
+ }
1431
+ const firstZero = binary.indexOf("0");
1432
+ if (firstZero === -1) {
1433
+ return totalBits;
1434
+ }
1435
+ if (binary.slice(firstZero).includes("1")) {
1436
+ throw new address_error_1.AddressError("Invalid subnet mask.");
1437
+ }
1438
+ return firstZero;
1439
+ }
1407
1440
  function numberToPaddedHex(number) {
1408
1441
  return number.toString(16).padStart(2, "0");
1409
1442
  }
@@ -1421,9 +1454,9 @@ var require_common = __commonJS({
1421
1454
  }
1422
1455
  });
1423
1456
 
1424
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/v4/constants.js
1457
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/v4/constants.js
1425
1458
  var require_constants2 = __commonJS({
1426
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/v4/constants.js"(exports) {
1459
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/v4/constants.js"(exports) {
1427
1460
  "use strict";
1428
1461
  Object.defineProperty(exports, "__esModule", { value: true });
1429
1462
  exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0;
@@ -1434,26 +1467,9 @@ var require_constants2 = __commonJS({
1434
1467
  }
1435
1468
  });
1436
1469
 
1437
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/address-error.js
1438
- var require_address_error = __commonJS({
1439
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/address-error.js"(exports) {
1440
- "use strict";
1441
- Object.defineProperty(exports, "__esModule", { value: true });
1442
- exports.AddressError = void 0;
1443
- var AddressError = class extends Error {
1444
- constructor(message, parseMessage) {
1445
- super(message);
1446
- this.name = "AddressError";
1447
- this.parseMessage = parseMessage;
1448
- }
1449
- };
1450
- exports.AddressError = AddressError;
1451
- }
1452
- });
1453
-
1454
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/ipv4.js
1470
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/ipv4.js
1455
1471
  var require_ipv4 = __commonJS({
1456
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/ipv4.js"(exports) {
1472
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/ipv4.js"(exports) {
1457
1473
  "use strict";
1458
1474
  var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
1459
1475
  if (k2 === void 0) k2 = k;
@@ -1487,6 +1503,7 @@ var require_ipv4 = __commonJS({
1487
1503
  var common = __importStar(require_common());
1488
1504
  var constants = __importStar(require_constants2());
1489
1505
  var address_error_1 = require_address_error();
1506
+ var isCorrect4 = common.isCorrect(constants.BITS);
1490
1507
  var Address4 = class _Address4 {
1491
1508
  constructor(address) {
1492
1509
  this.groups = constants.GROUPS;
@@ -1495,7 +1512,7 @@ var require_ipv4 = __commonJS({
1495
1512
  this.subnet = "/32";
1496
1513
  this.subnetMask = 32;
1497
1514
  this.v4 = true;
1498
- this.isCorrect = common.isCorrect(constants.BITS);
1515
+ this.isCorrect = isCorrect4;
1499
1516
  this.isInSubnet = common.isInSubnet;
1500
1517
  this.address = address;
1501
1518
  const subnet = constants.RE_SUBNET_STRING.exec(address);
@@ -1511,6 +1528,13 @@ var require_ipv4 = __commonJS({
1511
1528
  this.addressMinusSuffix = address;
1512
1529
  this.parsedAddress = this.parse(address);
1513
1530
  }
1531
+ /**
1532
+ * Returns true if the given string is a valid IPv4 address (with optional
1533
+ * CIDR subnet), false otherwise. Host bits in the subnet portion are
1534
+ * allowed (e.g. `192.168.1.5/24` is valid); for strict network-address
1535
+ * validation compare `correctForm()` to `startAddress().correctForm()`,
1536
+ * or use `networkForm()`.
1537
+ */
1514
1538
  static isValid(address) {
1515
1539
  try {
1516
1540
  new _Address4(address);
@@ -1519,8 +1543,11 @@ var require_ipv4 = __commonJS({
1519
1543
  return false;
1520
1544
  }
1521
1545
  }
1522
- /*
1523
- * Parses a v4 address
1546
+ /**
1547
+ * Parses an IPv4 address string into its four octet groups and stores the
1548
+ * result on `this.parsedAddress`. Called automatically by the constructor;
1549
+ * you typically don't need to call it directly. Throws `AddressError` if
1550
+ * the input is not a valid IPv4 address.
1524
1551
  */
1525
1552
  parse(address) {
1526
1553
  const groups = address.split(".");
@@ -1530,45 +1557,108 @@ var require_ipv4 = __commonJS({
1530
1557
  return groups;
1531
1558
  }
1532
1559
  /**
1533
- * Returns the correct form of an address
1534
- * @memberof Address4
1535
- * @instance
1536
- * @returns {String}
1560
+ * Returns the address in correct form: octets joined with `.` and any
1561
+ * leading zeros stripped (e.g. `192.168.1.1`). For IPv4 this matches the
1562
+ * canonical dotted-decimal representation.
1537
1563
  */
1538
1564
  correctForm() {
1539
1565
  return this.parsedAddress.map((part) => parseInt(part, 10)).join(".");
1540
1566
  }
1541
1567
  /**
1542
- * Converts a hex string to an IPv4 address object
1543
- * @memberof Address4
1544
- * @static
1568
+ * Construct an `Address4` from an address and a dotted-decimal subnet
1569
+ * mask given as separate strings (e.g. as returned by Node's
1570
+ * `os.networkInterfaces()`). Throws `AddressError` if the mask is
1571
+ * non-contiguous (e.g. `255.0.255.0`).
1572
+ * @example
1573
+ * var address = Address4.fromAddressAndMask('192.168.1.1', '255.255.255.0');
1574
+ * address.subnetMask; // 24
1575
+ */
1576
+ static fromAddressAndMask(address, mask) {
1577
+ const bits = common.prefixLengthFromMask(new _Address4(mask).bigInt(), constants.BITS);
1578
+ return new _Address4(`${address}/${bits}`);
1579
+ }
1580
+ /**
1581
+ * Construct an `Address4` from an address and a Cisco-style wildcard mask
1582
+ * given as separate strings (e.g. `0.0.0.255` for a `/24`). The wildcard
1583
+ * mask is the bitwise inverse of the subnet mask. Throws `AddressError`
1584
+ * if the mask is non-contiguous (e.g. `0.255.0.255`).
1585
+ * @example
1586
+ * var address = Address4.fromAddressAndWildcardMask('10.0.0.1', '0.0.0.255');
1587
+ * address.subnetMask; // 24
1588
+ */
1589
+ static fromAddressAndWildcardMask(address, wildcardMask) {
1590
+ const wildcard = new _Address4(wildcardMask).bigInt();
1591
+ const allOnes = (BigInt(1) << BigInt(constants.BITS)) - BigInt(1);
1592
+ const mask = wildcard ^ allOnes;
1593
+ const bits = common.prefixLengthFromMask(mask, constants.BITS);
1594
+ return new _Address4(`${address}/${bits}`);
1595
+ }
1596
+ /**
1597
+ * Construct an `Address4` from a wildcard pattern with trailing `*`
1598
+ * octets. The number of trailing wildcards determines the prefix
1599
+ * length: each `*` represents 8 bits.
1600
+ *
1601
+ * Only trailing whole-octet wildcards are supported. Partial-octet
1602
+ * wildcards (e.g. `192.168.0.1*`) and interior wildcards (e.g.
1603
+ * `192.*.0.1`) throw `AddressError`.
1604
+ * @example
1605
+ * Address4.fromWildcard('192.168.0.*').subnet; // '/24'
1606
+ * Address4.fromWildcard('192.168.*.*').subnet; // '/16'
1607
+ * Address4.fromWildcard('*.*.*.*').subnet; // '/0'
1608
+ */
1609
+ static fromWildcard(input) {
1610
+ const groups = input.split(".");
1611
+ if (groups.length !== constants.GROUPS) {
1612
+ throw new address_error_1.AddressError("Wildcard pattern must have 4 octets");
1613
+ }
1614
+ let firstWildcard = -1;
1615
+ for (let i = 0; i < groups.length; i++) {
1616
+ if (groups[i] === "*") {
1617
+ if (firstWildcard === -1) {
1618
+ firstWildcard = i;
1619
+ }
1620
+ } else if (firstWildcard !== -1) {
1621
+ throw new address_error_1.AddressError("Wildcard `*` must only appear in trailing octets (e.g. `192.168.0.*`)");
1622
+ }
1623
+ }
1624
+ const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard;
1625
+ const replaced = groups.map((g) => g === "*" ? "0" : g);
1626
+ const subnetBits = constants.BITS - trailing * 8;
1627
+ return new _Address4(`${replaced.join(".")}/${subnetBits}`);
1628
+ }
1629
+ /**
1630
+ * Converts a hex string to an IPv4 address object. Accepts 8 hex digits
1631
+ * with optional `:` separators (e.g. `'7f000001'` or `'7f:00:00:01'`).
1632
+ * Throws `AddressError` for any other length or for non-hex characters.
1545
1633
  * @param {string} hex - a hex string to convert
1546
1634
  * @returns {Address4}
1547
1635
  */
1548
1636
  static fromHex(hex) {
1549
- const padded = hex.replace(/:/g, "").padStart(8, "0");
1637
+ const stripped = hex.replace(/:/g, "");
1638
+ if (!/^[0-9a-fA-F]{8}$/.test(stripped)) {
1639
+ throw new address_error_1.AddressError("IPv4 hex must be exactly 8 hex digits");
1640
+ }
1550
1641
  const groups = [];
1551
- let i;
1552
- for (i = 0; i < 8; i += 2) {
1553
- const h = padded.slice(i, i + 2);
1554
- groups.push(parseInt(h, 16));
1642
+ for (let i = 0; i < 8; i += 2) {
1643
+ groups.push(parseInt(stripped.slice(i, i + 2), 16));
1555
1644
  }
1556
1645
  return new _Address4(groups.join("."));
1557
1646
  }
1558
1647
  /**
1559
- * Converts an integer into a IPv4 address object
1560
- * @memberof Address4
1561
- * @static
1648
+ * Converts an integer into a IPv4 address object. The integer must be a
1649
+ * non-negative safe integer in the range `[0, 2**32 - 1]`; otherwise
1650
+ * `AddressError` is thrown.
1562
1651
  * @param {integer} integer - a number to convert
1563
1652
  * @returns {Address4}
1564
1653
  */
1565
1654
  static fromInteger(integer) {
1566
- return _Address4.fromHex(integer.toString(16));
1655
+ if (!Number.isInteger(integer) || integer < 0 || integer > 4294967295) {
1656
+ throw new address_error_1.AddressError("IPv4 integer must be in the range 0 to 2**32 - 1");
1657
+ }
1658
+ return _Address4.fromHex(integer.toString(16).padStart(8, "0"));
1567
1659
  }
1568
1660
  /**
1569
1661
  * Return an address from in-addr.arpa form
1570
- * @memberof Address4
1571
- * @static
1572
1662
  * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address
1573
1663
  * @returns {Adress4}
1574
1664
  * @example
@@ -1582,17 +1672,15 @@ var require_ipv4 = __commonJS({
1582
1672
  }
1583
1673
  /**
1584
1674
  * Converts an IPv4 address object to a hex string
1585
- * @memberof Address4
1586
- * @instance
1587
1675
  * @returns {String}
1588
1676
  */
1589
1677
  toHex() {
1590
1678
  return this.parsedAddress.map((part) => common.stringToPaddedHex(part)).join(":");
1591
1679
  }
1592
1680
  /**
1593
- * Converts an IPv4 address object to an array of bytes
1594
- * @memberof Address4
1595
- * @instance
1681
+ * Converts an IPv4 address object to an array of bytes.
1682
+ *
1683
+ * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toArray())`.
1596
1684
  * @returns {Array}
1597
1685
  */
1598
1686
  toArray() {
@@ -1600,8 +1688,6 @@ var require_ipv4 = __commonJS({
1600
1688
  }
1601
1689
  /**
1602
1690
  * Converts an IPv4 address object to an IPv6 address group
1603
- * @memberof Address4
1604
- * @instance
1605
1691
  * @returns {String}
1606
1692
  */
1607
1693
  toGroup6() {
@@ -1614,8 +1700,6 @@ var require_ipv4 = __commonJS({
1614
1700
  }
1615
1701
  /**
1616
1702
  * Returns the address as a `bigint`
1617
- * @memberof Address4
1618
- * @instance
1619
1703
  * @returns {bigint}
1620
1704
  */
1621
1705
  bigInt() {
@@ -1623,8 +1707,6 @@ var require_ipv4 = __commonJS({
1623
1707
  }
1624
1708
  /**
1625
1709
  * Helper function getting start address.
1626
- * @memberof Address4
1627
- * @instance
1628
1710
  * @returns {bigint}
1629
1711
  */
1630
1712
  _startAddress() {
@@ -1633,8 +1715,6 @@ var require_ipv4 = __commonJS({
1633
1715
  /**
1634
1716
  * The first address in the range given by this address' subnet.
1635
1717
  * Often referred to as the Network Address.
1636
- * @memberof Address4
1637
- * @instance
1638
1718
  * @returns {Address4}
1639
1719
  */
1640
1720
  startAddress() {
@@ -1643,8 +1723,6 @@ var require_ipv4 = __commonJS({
1643
1723
  /**
1644
1724
  * The first host address in the range given by this address's subnet ie
1645
1725
  * the first address after the Network Address
1646
- * @memberof Address4
1647
- * @instance
1648
1726
  * @returns {Address4}
1649
1727
  */
1650
1728
  startAddressExclusive() {
@@ -1653,8 +1731,6 @@ var require_ipv4 = __commonJS({
1653
1731
  }
1654
1732
  /**
1655
1733
  * Helper function getting end address.
1656
- * @memberof Address4
1657
- * @instance
1658
1734
  * @returns {bigint}
1659
1735
  */
1660
1736
  _endAddress() {
@@ -1663,8 +1739,6 @@ var require_ipv4 = __commonJS({
1663
1739
  /**
1664
1740
  * The last address in the range given by this address' subnet
1665
1741
  * Often referred to as the Broadcast
1666
- * @memberof Address4
1667
- * @instance
1668
1742
  * @returns {Address4}
1669
1743
  */
1670
1744
  endAddress() {
@@ -1673,8 +1747,6 @@ var require_ipv4 = __commonJS({
1673
1747
  /**
1674
1748
  * The last host address in the range given by this address's subnet ie
1675
1749
  * the last address prior to the Broadcast Address
1676
- * @memberof Address4
1677
- * @instance
1678
1750
  * @returns {Address4}
1679
1751
  */
1680
1752
  endAddressExclusive() {
@@ -1682,20 +1754,76 @@ var require_ipv4 = __commonJS({
1682
1754
  return _Address4.fromBigInt(this._endAddress() - adjust);
1683
1755
  }
1684
1756
  /**
1685
- * Converts a BigInt to a v4 address object
1686
- * @memberof Address4
1687
- * @static
1757
+ * The dotted-decimal form of the subnet mask, e.g. `255.255.240.0` for
1758
+ * a `/20`. Returns an `Address4`; call `.correctForm()` for the string.
1759
+ * @returns {Address4}
1760
+ */
1761
+ subnetMaskAddress() {
1762
+ return _Address4.fromBigInt(BigInt(`0b${"1".repeat(this.subnetMask)}${"0".repeat(constants.BITS - this.subnetMask)}`));
1763
+ }
1764
+ /**
1765
+ * The Cisco-style wildcard mask, e.g. `0.0.0.255` for a `/24`. This is
1766
+ * the bitwise inverse of `subnetMaskAddress()`. Returns an `Address4`;
1767
+ * call `.correctForm()` for the string.
1768
+ * @returns {Address4}
1769
+ */
1770
+ wildcardMask() {
1771
+ return _Address4.fromBigInt(BigInt(`0b${"0".repeat(this.subnetMask)}${"1".repeat(constants.BITS - this.subnetMask)}`));
1772
+ }
1773
+ /**
1774
+ * The network address in CIDR string form, e.g. `192.168.1.0/24` for
1775
+ * `192.168.1.5/24`. For an address with no explicit subnet the prefix is
1776
+ * `/32`, e.g. `networkForm()` on `192.168.1.5` returns `192.168.1.5/32`.
1777
+ * @returns {string}
1778
+ */
1779
+ networkForm() {
1780
+ return `${this.startAddress().correctForm()}/${this.subnetMask}`;
1781
+ }
1782
+ /**
1783
+ * Converts a BigInt to a v4 address object. The value must be in the
1784
+ * range `[0, 2**32 - 1]`; otherwise `AddressError` is thrown.
1688
1785
  * @param {bigint} bigInt - a BigInt to convert
1689
1786
  * @returns {Address4}
1690
1787
  */
1691
1788
  static fromBigInt(bigInt) {
1692
- return _Address4.fromHex(bigInt.toString(16));
1789
+ if (bigInt < 0n || bigInt > 0xffffffffn) {
1790
+ throw new address_error_1.AddressError("IPv4 BigInt must be in the range 0 to 2**32 - 1");
1791
+ }
1792
+ return _Address4.fromHex(bigInt.toString(16).padStart(8, "0"));
1793
+ }
1794
+ /**
1795
+ * Convert a byte array to an Address4 object.
1796
+ *
1797
+ * To convert from a Node.js `Buffer`, spread it: `Address4.fromByteArray([...buf])`.
1798
+ * @param {Array<number>} bytes - an array of 4 bytes (0-255)
1799
+ * @returns {Address4}
1800
+ */
1801
+ static fromByteArray(bytes) {
1802
+ if (bytes.length !== 4) {
1803
+ throw new address_error_1.AddressError("IPv4 addresses require exactly 4 bytes");
1804
+ }
1805
+ for (let i = 0; i < bytes.length; i++) {
1806
+ if (!Number.isInteger(bytes[i]) || bytes[i] < 0 || bytes[i] > 255) {
1807
+ throw new address_error_1.AddressError("All bytes must be integers between 0 and 255");
1808
+ }
1809
+ }
1810
+ return this.fromUnsignedByteArray(bytes);
1811
+ }
1812
+ /**
1813
+ * Convert an unsigned byte array to an Address4 object
1814
+ * @param {Array<number>} bytes - an array of 4 unsigned bytes (0-255)
1815
+ * @returns {Address4}
1816
+ */
1817
+ static fromUnsignedByteArray(bytes) {
1818
+ if (bytes.length !== 4) {
1819
+ throw new address_error_1.AddressError("IPv4 addresses require exactly 4 bytes");
1820
+ }
1821
+ const address = bytes.join(".");
1822
+ return new _Address4(address);
1693
1823
  }
1694
1824
  /**
1695
1825
  * Returns the first n bits of the address, defaulting to the
1696
1826
  * subnet mask
1697
- * @memberof Address4
1698
- * @instance
1699
1827
  * @returns {String}
1700
1828
  */
1701
1829
  mask(mask) {
@@ -1706,8 +1834,6 @@ var require_ipv4 = __commonJS({
1706
1834
  }
1707
1835
  /**
1708
1836
  * Returns the bits in the given range as a base-2 string
1709
- * @memberof Address4
1710
- * @instance
1711
1837
  * @returns {string}
1712
1838
  */
1713
1839
  getBitsBase2(start, end) {
@@ -1715,10 +1841,8 @@ var require_ipv4 = __commonJS({
1715
1841
  }
1716
1842
  /**
1717
1843
  * Return the reversed ip6.arpa form of the address
1718
- * @memberof Address4
1719
1844
  * @param {Object} options
1720
1845
  * @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix
1721
- * @instance
1722
1846
  * @returns {String}
1723
1847
  */
1724
1848
  reverseForm(options) {
@@ -1733,21 +1857,62 @@ var require_ipv4 = __commonJS({
1733
1857
  }
1734
1858
  /**
1735
1859
  * Returns true if the given address is a multicast address
1736
- * @memberof Address4
1737
- * @instance
1738
1860
  * @returns {boolean}
1739
1861
  */
1740
1862
  isMulticast() {
1741
- return this.isInSubnet(new _Address4("224.0.0.0/4"));
1863
+ return this.isInSubnet(MULTICAST_V4);
1864
+ }
1865
+ /**
1866
+ * 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`).
1867
+ * @returns {boolean}
1868
+ */
1869
+ isPrivate() {
1870
+ return PRIVATE_V4.some((subnet) => this.isInSubnet(subnet));
1871
+ }
1872
+ /**
1873
+ * Returns true if the address is in the loopback range `127.0.0.0/8` ([RFC 1122](https://datatracker.ietf.org/doc/html/rfc1122)).
1874
+ * @returns {boolean}
1875
+ */
1876
+ isLoopback() {
1877
+ return this.isInSubnet(LOOPBACK_V4);
1878
+ }
1879
+ /**
1880
+ * 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)).
1881
+ * @returns {boolean}
1882
+ */
1883
+ isLinkLocal() {
1884
+ return this.isInSubnet(LINK_LOCAL_V4);
1885
+ }
1886
+ /**
1887
+ * Returns true if the address is the unspecified address `0.0.0.0`.
1888
+ * @returns {boolean}
1889
+ */
1890
+ isUnspecified() {
1891
+ return this.isInSubnet(UNSPECIFIED_V4);
1892
+ }
1893
+ /**
1894
+ * Returns true if the address is the limited broadcast address `255.255.255.255` ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)).
1895
+ * @returns {boolean}
1896
+ */
1897
+ isBroadcast() {
1898
+ return this.isInSubnet(BROADCAST_V4);
1899
+ }
1900
+ /**
1901
+ * 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)).
1902
+ * @returns {boolean}
1903
+ */
1904
+ isCGNAT() {
1905
+ return this.isInSubnet(CGNAT_V4);
1742
1906
  }
1743
1907
  /**
1744
1908
  * Returns a zero-padded base-2 string representation of the address
1745
- * @memberof Address4
1746
- * @instance
1747
1909
  * @returns {string}
1748
1910
  */
1749
1911
  binaryZeroPad() {
1750
- return this.bigInt().toString(2).padStart(constants.BITS, "0");
1912
+ if (this._binaryZeroPad === void 0) {
1913
+ this._binaryZeroPad = this.bigInt().toString(2).padStart(constants.BITS, "0");
1914
+ }
1915
+ return this._binaryZeroPad;
1751
1916
  }
1752
1917
  /**
1753
1918
  * Groups an IPv4 address for inclusion at the end of an IPv6 address
@@ -1759,12 +1924,23 @@ var require_ipv4 = __commonJS({
1759
1924
  }
1760
1925
  };
1761
1926
  exports.Address4 = Address4;
1927
+ var MULTICAST_V4 = new Address4("224.0.0.0/4");
1928
+ var PRIVATE_V4 = [
1929
+ new Address4("10.0.0.0/8"),
1930
+ new Address4("172.16.0.0/12"),
1931
+ new Address4("192.168.0.0/16")
1932
+ ];
1933
+ var LOOPBACK_V4 = new Address4("127.0.0.0/8");
1934
+ var LINK_LOCAL_V4 = new Address4("169.254.0.0/16");
1935
+ var UNSPECIFIED_V4 = new Address4("0.0.0.0/32");
1936
+ var BROADCAST_V4 = new Address4("255.255.255.255/32");
1937
+ var CGNAT_V4 = new Address4("100.64.0.0/10");
1762
1938
  }
1763
1939
  });
1764
1940
 
1765
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/v6/constants.js
1941
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/v6/constants.js
1766
1942
  var require_constants3 = __commonJS({
1767
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/v6/constants.js"(exports) {
1943
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/v6/constants.js"(exports) {
1768
1944
  "use strict";
1769
1945
  Object.defineProperty(exports, "__esModule", { value: true });
1770
1946
  exports.RE_URL_WITH_PORT = exports.RE_URL = exports.RE_ZONE_STRING = exports.RE_SUBNET_STRING = exports.RE_BAD_ADDRESS = exports.RE_BAD_CHARACTERS = exports.TYPES = exports.SCOPES = exports.GROUPS = exports.BITS = void 0;
@@ -1802,7 +1978,12 @@ var require_constants3 = __commonJS({
1802
1978
  "::/128": "Unspecified",
1803
1979
  "::1/128": "Loopback",
1804
1980
  "ff00::/8": "Multicast",
1805
- "fe80::/10": "Link-local unicast"
1981
+ "fe80::/10": "Link-local unicast",
1982
+ "fc00::/7": "Unique local",
1983
+ "2002::/16": "6to4",
1984
+ "2001:db8::/32": "Documentation",
1985
+ "64:ff9b::/96": "NAT64 (well-known)",
1986
+ "64:ff9b:1::/48": "NAT64 (local-use)"
1806
1987
  };
1807
1988
  exports.RE_BAD_CHARACTERS = /([^0-9a-f:/%])/gi;
1808
1989
  exports.RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi;
@@ -1813,24 +1994,28 @@ var require_constants3 = __commonJS({
1813
1994
  }
1814
1995
  });
1815
1996
 
1816
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/v6/helpers.js
1997
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/v6/helpers.js
1817
1998
  var require_helpers = __commonJS({
1818
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/v6/helpers.js"(exports) {
1999
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/v6/helpers.js"(exports) {
1819
2000
  "use strict";
1820
2001
  Object.defineProperty(exports, "__esModule", { value: true });
2002
+ exports.escapeHtml = escapeHtml;
1821
2003
  exports.spanAllZeroes = spanAllZeroes;
1822
2004
  exports.spanAll = spanAll;
1823
2005
  exports.spanLeadingZeroes = spanLeadingZeroes;
1824
2006
  exports.simpleGroup = simpleGroup;
2007
+ function escapeHtml(s) {
2008
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
2009
+ }
1825
2010
  function spanAllZeroes(s) {
1826
- return s.replace(/(0+)/g, '<span class="zero">$1</span>');
2011
+ return escapeHtml(s).replace(/(0+)/g, '<span class="zero">$1</span>');
1827
2012
  }
1828
2013
  function spanAll(s, offset = 0) {
1829
2014
  const letters = s.split("");
1830
- return letters.map((n, i) => `<span class="digit value-${n} position-${i + offset}">${spanAllZeroes(n)}</span>`).join("");
2015
+ return letters.map((n, i) => `<span class="digit value-${escapeHtml(n)} position-${i + offset}">${spanAllZeroes(n)}</span>`).join("");
1831
2016
  }
1832
2017
  function spanLeadingZeroesSimple(group) {
1833
- return group.replace(/^(0+)/, '<span class="zero">$1</span>');
2018
+ return escapeHtml(group).replace(/^(0+)/, '<span class="zero">$1</span>');
1834
2019
  }
1835
2020
  function spanLeadingZeroes(address) {
1836
2021
  const groups = address.split(":");
@@ -1848,9 +2033,9 @@ var require_helpers = __commonJS({
1848
2033
  }
1849
2034
  });
1850
2035
 
1851
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/v6/regular-expressions.js
2036
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/v6/regular-expressions.js
1852
2037
  var require_regular_expressions = __commonJS({
1853
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/v6/regular-expressions.js"(exports) {
2038
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/v6/regular-expressions.js"(exports) {
1854
2039
  "use strict";
1855
2040
  var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
1856
2041
  if (k2 === void 0) k2 = k;
@@ -1940,9 +2125,9 @@ var require_regular_expressions = __commonJS({
1940
2125
  }
1941
2126
  });
1942
2127
 
1943
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/ipv6.js
2128
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/ipv6.js
1944
2129
  var require_ipv6 = __commonJS({
1945
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/ipv6.js"(exports) {
2130
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/ipv6.js"(exports) {
1946
2131
  "use strict";
1947
2132
  var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
1948
2133
  if (k2 === void 0) k2 = k;
@@ -1981,6 +2166,7 @@ var require_ipv6 = __commonJS({
1981
2166
  var regular_expressions_1 = require_regular_expressions();
1982
2167
  var address_error_1 = require_address_error();
1983
2168
  var common_1 = require_common();
2169
+ var isCorrect6 = common.isCorrect(constants6.BITS);
1984
2170
  function assert(condition) {
1985
2171
  if (!condition) {
1986
2172
  throw new Error("Assertion failed.");
@@ -2026,7 +2212,7 @@ var require_ipv6 = __commonJS({
2026
2212
  this.v4 = false;
2027
2213
  this.zone = "";
2028
2214
  this.isInSubnet = common.isInSubnet;
2029
- this.isCorrect = common.isCorrect(constants6.BITS);
2215
+ this.isCorrect = isCorrect6;
2030
2216
  if (optionalGroups === void 0) {
2031
2217
  this.groups = constants6.GROUPS;
2032
2218
  } else {
@@ -2053,6 +2239,13 @@ var require_ipv6 = __commonJS({
2053
2239
  this.addressMinusSuffix = address;
2054
2240
  this.parsedAddress = this.parse(this.addressMinusSuffix);
2055
2241
  }
2242
+ /**
2243
+ * Returns true if the given string is a valid IPv6 address (with optional
2244
+ * CIDR subnet and zone identifier), false otherwise. Host bits in the
2245
+ * subnet portion are allowed (e.g. `2001:db8::1/32` is valid); for strict
2246
+ * network-address validation compare `correctForm()` to
2247
+ * `startAddress().correctForm()`, or use `networkForm()`.
2248
+ */
2056
2249
  static isValid(address) {
2057
2250
  try {
2058
2251
  new _Address6(address);
@@ -2062,9 +2255,8 @@ var require_ipv6 = __commonJS({
2062
2255
  }
2063
2256
  }
2064
2257
  /**
2065
- * Convert a BigInt to a v6 address object
2066
- * @memberof Address6
2067
- * @static
2258
+ * Convert a BigInt to a v6 address object. The value must be in the
2259
+ * range `[0, 2**128 - 1]`; otherwise `AddressError` is thrown.
2068
2260
  * @param {bigint} bigInt - a BigInt to convert
2069
2261
  * @returns {Address6}
2070
2262
  * @example
@@ -2073,19 +2265,21 @@ var require_ipv6 = __commonJS({
2073
2265
  * address.correctForm(); // '::e8:d4a5:1000'
2074
2266
  */
2075
2267
  static fromBigInt(bigInt) {
2268
+ if (bigInt < 0n || bigInt > (1n << BigInt(constants6.BITS)) - 1n) {
2269
+ throw new address_error_1.AddressError("IPv6 BigInt must be in the range 0 to 2**128 - 1");
2270
+ }
2076
2271
  const hex = bigInt.toString(16).padStart(32, "0");
2077
2272
  const groups = [];
2078
- let i;
2079
- for (i = 0; i < constants6.GROUPS; i++) {
2273
+ for (let i = 0; i < constants6.GROUPS; i++) {
2080
2274
  groups.push(hex.slice(i * 4, (i + 1) * 4));
2081
2275
  }
2082
2276
  return new _Address6(groups.join(":"));
2083
2277
  }
2084
2278
  /**
2085
- * Convert a URL (with optional port number) to an address object
2086
- * @memberof Address6
2087
- * @static
2088
- * @param {string} url - a URL with optional port number
2279
+ * Parse a URL (with optional bracketed host and port) into an address and
2280
+ * port. Returns either `{ address, port }` on success or
2281
+ * `{ error, address: null, port: null }` if the URL could not be parsed.
2282
+ * Ports are returned as numbers (or `null` if absent or out of range).
2089
2283
  * @example
2090
2284
  * var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/');
2091
2285
  * addressAndPort.address.correctForm(); // 'ffff::'
@@ -2133,10 +2327,89 @@ var require_ipv6 = __commonJS({
2133
2327
  port
2134
2328
  };
2135
2329
  }
2330
+ /**
2331
+ * Construct an `Address6` from an address and a hex subnet mask given as
2332
+ * separate strings (e.g. as returned by Node's `os.networkInterfaces()`).
2333
+ * Throws `AddressError` if the mask is non-contiguous (e.g.
2334
+ * `ffff::ffff`).
2335
+ * @example
2336
+ * var address = Address6.fromAddressAndMask('fe80::1', 'ffff:ffff:ffff:ffff::');
2337
+ * address.subnetMask; // 64
2338
+ */
2339
+ static fromAddressAndMask(address, mask) {
2340
+ const bits = common.prefixLengthFromMask(new _Address6(mask).bigInt(), constants6.BITS);
2341
+ return new _Address6(`${address}/${bits}`);
2342
+ }
2343
+ /**
2344
+ * Construct an `Address6` from an address and a Cisco-style wildcard mask
2345
+ * given as separate strings (e.g. `::ffff:ffff:ffff:ffff` for a `/64`).
2346
+ * The wildcard mask is the bitwise inverse of the subnet mask. Throws
2347
+ * `AddressError` if the mask is non-contiguous.
2348
+ * @example
2349
+ * var address = Address6.fromAddressAndWildcardMask('fe80::1', '::ffff:ffff:ffff:ffff');
2350
+ * address.subnetMask; // 64
2351
+ */
2352
+ static fromAddressAndWildcardMask(address, wildcardMask) {
2353
+ const wildcard = new _Address6(wildcardMask).bigInt();
2354
+ const allOnes = (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1);
2355
+ const mask = wildcard ^ allOnes;
2356
+ const bits = common.prefixLengthFromMask(mask, constants6.BITS);
2357
+ return new _Address6(`${address}/${bits}`);
2358
+ }
2359
+ /**
2360
+ * Construct an `Address6` from a wildcard pattern with trailing `*`
2361
+ * groups. The number of trailing wildcards determines the prefix
2362
+ * length: each `*` represents 16 bits. `::` is expanded to zero groups
2363
+ * (not wildcards) before evaluating trailing wildcards.
2364
+ *
2365
+ * Only trailing whole-group wildcards are supported. Partial-group
2366
+ * wildcards (e.g. `2001:db8::0*`) and interior wildcards (e.g.
2367
+ * `*::1`) throw `AddressError`.
2368
+ * @example
2369
+ * Address6.fromWildcard('2001:db8:*:*:*:*:*:*').subnet; // '/32'
2370
+ * Address6.fromWildcard('2001:db8::*').subnet; // '/112'
2371
+ * Address6.fromWildcard('*:*:*:*:*:*:*:*').subnet; // '/0'
2372
+ */
2373
+ static fromWildcard(input) {
2374
+ if (input.includes("%") || input.includes("/")) {
2375
+ throw new address_error_1.AddressError("Wildcard pattern must not include a zone or CIDR suffix");
2376
+ }
2377
+ const halves = input.split("::");
2378
+ if (halves.length > 2) {
2379
+ throw new address_error_1.AddressError("Wildcard pattern cannot contain more than one '::'");
2380
+ }
2381
+ let groups;
2382
+ if (halves.length === 2) {
2383
+ const left = halves[0] === "" ? [] : halves[0].split(":");
2384
+ const right = halves[1] === "" ? [] : halves[1].split(":");
2385
+ const remaining = constants6.GROUPS - left.length - right.length;
2386
+ if (remaining < 1) {
2387
+ throw new address_error_1.AddressError("Wildcard pattern with '::' has too many groups");
2388
+ }
2389
+ groups = [...left, ...new Array(remaining).fill("0"), ...right];
2390
+ } else {
2391
+ groups = input.split(":");
2392
+ }
2393
+ if (groups.length !== constants6.GROUPS) {
2394
+ throw new address_error_1.AddressError("Wildcard pattern must have 8 groups");
2395
+ }
2396
+ let firstWildcard = -1;
2397
+ for (let i = 0; i < groups.length; i++) {
2398
+ if (groups[i] === "*") {
2399
+ if (firstWildcard === -1) {
2400
+ firstWildcard = i;
2401
+ }
2402
+ } else if (firstWildcard !== -1) {
2403
+ throw new address_error_1.AddressError("Wildcard `*` must only appear in trailing groups (e.g. `2001:db8:*:*:*:*:*:*`)");
2404
+ }
2405
+ }
2406
+ const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard;
2407
+ const replaced = groups.map((g) => g === "*" ? "0" : g);
2408
+ const subnetBits = constants6.BITS - trailing * 16;
2409
+ return new _Address6(`${replaced.join(":")}/${subnetBits}`);
2410
+ }
2136
2411
  /**
2137
2412
  * Create an IPv6-mapped address given an IPv4 address
2138
- * @memberof Address6
2139
- * @static
2140
2413
  * @param {string} address - An IPv4 address string
2141
2414
  * @returns {Address6}
2142
2415
  * @example
@@ -2151,8 +2424,6 @@ var require_ipv6 = __commonJS({
2151
2424
  }
2152
2425
  /**
2153
2426
  * Return an address from ip6.arpa form
2154
- * @memberof Address6
2155
- * @static
2156
2427
  * @param {string} arpaFormAddress - an 'ip6.arpa' form address
2157
2428
  * @returns {Adress6}
2158
2429
  * @example
@@ -2175,8 +2446,6 @@ var require_ipv6 = __commonJS({
2175
2446
  }
2176
2447
  /**
2177
2448
  * Return the Microsoft UNC transcription of the address
2178
- * @memberof Address6
2179
- * @instance
2180
2449
  * @returns {String} the Microsoft UNC transcription of the address
2181
2450
  */
2182
2451
  microsoftTranscription() {
@@ -2184,8 +2453,6 @@ var require_ipv6 = __commonJS({
2184
2453
  }
2185
2454
  /**
2186
2455
  * Return the first n bits of the address, defaulting to the subnet mask
2187
- * @memberof Address6
2188
- * @instance
2189
2456
  * @param {number} [mask=subnet] - the number of bits to mask
2190
2457
  * @returns {String} the first n bits of the address as a string
2191
2458
  */
@@ -2194,8 +2461,6 @@ var require_ipv6 = __commonJS({
2194
2461
  }
2195
2462
  /**
2196
2463
  * Return the number of possible subnets of a given size in the address
2197
- * @memberof Address6
2198
- * @instance
2199
2464
  * @param {number} [subnetSize=128] - the subnet size
2200
2465
  * @returns {String}
2201
2466
  */
@@ -2211,8 +2476,6 @@ var require_ipv6 = __commonJS({
2211
2476
  }
2212
2477
  /**
2213
2478
  * Helper function getting start address.
2214
- * @memberof Address6
2215
- * @instance
2216
2479
  * @returns {bigint}
2217
2480
  */
2218
2481
  _startAddress() {
@@ -2221,8 +2484,6 @@ var require_ipv6 = __commonJS({
2221
2484
  /**
2222
2485
  * The first address in the range given by this address' subnet
2223
2486
  * Often referred to as the Network Address.
2224
- * @memberof Address6
2225
- * @instance
2226
2487
  * @returns {Address6}
2227
2488
  */
2228
2489
  startAddress() {
@@ -2231,8 +2492,6 @@ var require_ipv6 = __commonJS({
2231
2492
  /**
2232
2493
  * The first host address in the range given by this address's subnet ie
2233
2494
  * the first address after the Network Address
2234
- * @memberof Address6
2235
- * @instance
2236
2495
  * @returns {Address6}
2237
2496
  */
2238
2497
  startAddressExclusive() {
@@ -2241,8 +2500,6 @@ var require_ipv6 = __commonJS({
2241
2500
  }
2242
2501
  /**
2243
2502
  * Helper function getting end address.
2244
- * @memberof Address6
2245
- * @instance
2246
2503
  * @returns {bigint}
2247
2504
  */
2248
2505
  _endAddress() {
@@ -2251,8 +2508,6 @@ var require_ipv6 = __commonJS({
2251
2508
  /**
2252
2509
  * The last address in the range given by this address' subnet
2253
2510
  * Often referred to as the Broadcast
2254
- * @memberof Address6
2255
- * @instance
2256
2511
  * @returns {Address6}
2257
2512
  */
2258
2513
  endAddress() {
@@ -2261,8 +2516,6 @@ var require_ipv6 = __commonJS({
2261
2516
  /**
2262
2517
  * The last host address in the range given by this address's subnet ie
2263
2518
  * the last address prior to the Broadcast Address
2264
- * @memberof Address6
2265
- * @instance
2266
2519
  * @returns {Address6}
2267
2520
  */
2268
2521
  endAddressExclusive() {
@@ -2270,36 +2523,69 @@ var require_ipv6 = __commonJS({
2270
2523
  return _Address6.fromBigInt(this._endAddress() - adjust);
2271
2524
  }
2272
2525
  /**
2273
- * Return the scope of the address
2274
- * @memberof Address6
2275
- * @instance
2526
+ * The hex form of the subnet mask, e.g. `ffff:ffff:ffff:ffff::` for a
2527
+ * `/64`. Returns an `Address6`; call `.correctForm()` for the string.
2528
+ * @returns {Address6}
2529
+ */
2530
+ subnetMaskAddress() {
2531
+ return _Address6.fromBigInt(BigInt(`0b${"1".repeat(this.subnetMask)}${"0".repeat(constants6.BITS - this.subnetMask)}`));
2532
+ }
2533
+ /**
2534
+ * The Cisco-style wildcard mask, e.g. `::ffff:ffff:ffff:ffff` for a
2535
+ * `/64`. This is the bitwise inverse of `subnetMaskAddress()`. Returns
2536
+ * an `Address6`; call `.correctForm()` for the string.
2537
+ * @returns {Address6}
2538
+ */
2539
+ wildcardMask() {
2540
+ return _Address6.fromBigInt(BigInt(`0b${"0".repeat(this.subnetMask)}${"1".repeat(constants6.BITS - this.subnetMask)}`));
2541
+ }
2542
+ /**
2543
+ * The network address in CIDR string form, e.g. `2001:db8::/32` for
2544
+ * `2001:db8::1/32`. For an address with no explicit subnet the prefix
2545
+ * is `/128`, e.g. `networkForm()` on `2001:db8::1` returns
2546
+ * `2001:db8::1/128`.
2547
+ * @returns {string}
2548
+ */
2549
+ networkForm() {
2550
+ return `${this.startAddress().correctForm()}/${this.subnetMask}`;
2551
+ }
2552
+ /**
2553
+ * Return the scope of the address. The 4-bit scope field
2554
+ * ([RFC 4291 §2.7](https://datatracker.ietf.org/doc/html/rfc4291#section-2.7))
2555
+ * is only defined for multicast addresses; for unicast addresses the scope
2556
+ * is derived from the address type per
2557
+ * [RFC 4007 §6](https://datatracker.ietf.org/doc/html/rfc4007#section-6).
2276
2558
  * @returns {String}
2277
2559
  */
2278
2560
  getScope() {
2279
- let scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)];
2280
- if (this.getType() === "Global unicast" && scope !== "Link local") {
2281
- scope = "Global";
2561
+ const type = this.getType();
2562
+ if (type === "Multicast" || type.startsWith("Multicast ")) {
2563
+ const scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)];
2564
+ return scope || "Unknown";
2565
+ }
2566
+ if (type === "Link-local unicast" || type === "Loopback") {
2567
+ return "Link local";
2282
2568
  }
2283
- return scope || "Unknown";
2569
+ if (type === "Unspecified") {
2570
+ return "Unknown";
2571
+ }
2572
+ return "Global";
2284
2573
  }
2285
2574
  /**
2286
2575
  * Return the type of the address
2287
- * @memberof Address6
2288
- * @instance
2289
2576
  * @returns {String}
2290
2577
  */
2291
2578
  getType() {
2292
- for (const subnet of Object.keys(constants6.TYPES)) {
2293
- if (this.isInSubnet(new _Address6(subnet))) {
2294
- return constants6.TYPES[subnet];
2579
+ for (let i = 0; i < TYPE_SUBNETS.length; i++) {
2580
+ const entry = TYPE_SUBNETS[i];
2581
+ if (this.isInSubnet(entry[0])) {
2582
+ return entry[1];
2295
2583
  }
2296
2584
  }
2297
2585
  return "Global unicast";
2298
2586
  }
2299
2587
  /**
2300
2588
  * Return the bits in the given range as a BigInt
2301
- * @memberof Address6
2302
- * @instance
2303
2589
  * @returns {bigint}
2304
2590
  */
2305
2591
  getBits(start, end) {
@@ -2307,8 +2593,6 @@ var require_ipv6 = __commonJS({
2307
2593
  }
2308
2594
  /**
2309
2595
  * Return the bits in the given range as a base-2 string
2310
- * @memberof Address6
2311
- * @instance
2312
2596
  * @returns {String}
2313
2597
  */
2314
2598
  getBitsBase2(start, end) {
@@ -2316,8 +2600,6 @@ var require_ipv6 = __commonJS({
2316
2600
  }
2317
2601
  /**
2318
2602
  * Return the bits in the given range as a base-16 string
2319
- * @memberof Address6
2320
- * @instance
2321
2603
  * @returns {String}
2322
2604
  */
2323
2605
  getBitsBase16(start, end) {
@@ -2329,8 +2611,6 @@ var require_ipv6 = __commonJS({
2329
2611
  }
2330
2612
  /**
2331
2613
  * Return the bits that are set past the subnet mask length
2332
- * @memberof Address6
2333
- * @instance
2334
2614
  * @returns {String}
2335
2615
  */
2336
2616
  getBitsPastSubnet() {
@@ -2338,10 +2618,8 @@ var require_ipv6 = __commonJS({
2338
2618
  }
2339
2619
  /**
2340
2620
  * Return the reversed ip6.arpa form of the address
2341
- * @memberof Address6
2342
2621
  * @param {Object} options
2343
2622
  * @param {boolean} options.omitSuffix - omit the "ip6.arpa" suffix
2344
- * @instance
2345
2623
  * @returns {String}
2346
2624
  */
2347
2625
  reverseForm(options) {
@@ -2362,10 +2640,10 @@ var require_ipv6 = __commonJS({
2362
2640
  return "ip6.arpa.";
2363
2641
  }
2364
2642
  /**
2365
- * Return the correct form of the address
2366
- * @memberof Address6
2367
- * @instance
2368
- * @returns {String}
2643
+ * Returns the address in correct form, per
2644
+ * [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952): leading zeros
2645
+ * stripped, the longest run of zero groups collapsed to `::`, and hex digits
2646
+ * lowercased (e.g. `2001:db8::1`). This is the recommended form for display.
2369
2647
  */
2370
2648
  correctForm() {
2371
2649
  let i;
@@ -2407,8 +2685,6 @@ var require_ipv6 = __commonJS({
2407
2685
  }
2408
2686
  /**
2409
2687
  * Return a zero-padded base-2 string representation of the address
2410
- * @memberof Address6
2411
- * @instance
2412
2688
  * @returns {String}
2413
2689
  * @example
2414
2690
  * var address = new Address6('2001:4860:4001:803::1011');
@@ -2417,10 +2693,22 @@ var require_ipv6 = __commonJS({
2417
2693
  * // 0000000000000000000000000000000000000000000000000001000000010001'
2418
2694
  */
2419
2695
  binaryZeroPad() {
2420
- return this.bigInt().toString(2).padStart(constants6.BITS, "0");
2696
+ if (this._binaryZeroPad === void 0) {
2697
+ this._binaryZeroPad = this.bigInt().toString(2).padStart(constants6.BITS, "0");
2698
+ }
2699
+ return this._binaryZeroPad;
2421
2700
  }
2701
+ /**
2702
+ * Parses a v4-in-v6 string (e.g. `::ffff:192.168.0.1`) by extracting the
2703
+ * trailing IPv4 address into `this.address4` / `this.parsedAddress4` and
2704
+ * returning the address with the v4 portion converted to two v6 groups.
2705
+ * Used internally by `parse()`.
2706
+ */
2422
2707
  // TODO: Improve the semantics of this helper function
2423
2708
  parse4in6(address) {
2709
+ if (address.indexOf(".") === -1) {
2710
+ return address;
2711
+ }
2424
2712
  const groups = address.split(":");
2425
2713
  const lastGroup = groups.slice(-1)[0];
2426
2714
  const address4 = lastGroup.match(constants4.RE_ADDRESS);
@@ -2429,7 +2717,10 @@ var require_ipv6 = __commonJS({
2429
2717
  this.address4 = new ipv4_1.Address4(this.parsedAddress4);
2430
2718
  for (let i = 0; i < this.address4.groups; i++) {
2431
2719
  if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) {
2432
- throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", address.replace(constants4.RE_ADDRESS, this.address4.parsedAddress.map(spanLeadingZeroes4).join(".")));
2720
+ const highlighted = this.address4.parsedAddress.map(spanLeadingZeroes4).join(".");
2721
+ const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(":");
2722
+ const separator = groups.length > 1 ? ":" : "";
2723
+ throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`);
2433
2724
  }
2434
2725
  }
2435
2726
  this.v4 = true;
@@ -2438,6 +2729,13 @@ var require_ipv6 = __commonJS({
2438
2729
  }
2439
2730
  return address;
2440
2731
  }
2732
+ /**
2733
+ * Parses an IPv6 address string into its 8 hexadecimal groups (expanding
2734
+ * any `::` elision and any trailing v4-in-v6 portion) and stores the result
2735
+ * on `this.parsedAddress`. Called automatically by the constructor; you
2736
+ * typically don't need to call it directly. Throws `AddressError` if the
2737
+ * input is malformed.
2738
+ */
2441
2739
  // TODO: Make private?
2442
2740
  parse(address) {
2443
2741
  address = this.parse4in6(address);
@@ -2485,18 +2783,16 @@ var require_ipv6 = __commonJS({
2485
2783
  return groups;
2486
2784
  }
2487
2785
  /**
2488
- * Return the canonical form of the address
2489
- * @memberof Address6
2490
- * @instance
2491
- * @returns {String}
2786
+ * Returns the canonical (fully expanded) form of the address: all 8 groups,
2787
+ * each padded to 4 hex digits, with no `::` collapsing
2788
+ * (e.g. `2001:0db8:0000:0000:0000:0000:0000:0001`). Useful for sorting and
2789
+ * byte-exact comparison.
2492
2790
  */
2493
2791
  canonicalForm() {
2494
2792
  return this.parsedAddress.map(paddedHex).join(":");
2495
2793
  }
2496
2794
  /**
2497
2795
  * Return the decimal form of the address
2498
- * @memberof Address6
2499
- * @instance
2500
2796
  * @returns {String}
2501
2797
  */
2502
2798
  decimal() {
@@ -2504,8 +2800,6 @@ var require_ipv6 = __commonJS({
2504
2800
  }
2505
2801
  /**
2506
2802
  * Return the address as a BigInt
2507
- * @memberof Address6
2508
- * @instance
2509
2803
  * @returns {bigint}
2510
2804
  */
2511
2805
  bigInt() {
@@ -2513,8 +2807,6 @@ var require_ipv6 = __commonJS({
2513
2807
  }
2514
2808
  /**
2515
2809
  * Return the last two groups of this address as an IPv4 address string
2516
- * @memberof Address6
2517
- * @instance
2518
2810
  * @returns {Address4}
2519
2811
  * @example
2520
2812
  * var address = new Address6('2001:4860:4001::1825:bf11');
@@ -2522,12 +2814,10 @@ var require_ipv6 = __commonJS({
2522
2814
  */
2523
2815
  to4() {
2524
2816
  const binary = this.binaryZeroPad().split("");
2525
- return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join("")}`).toString(16));
2817
+ return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join("")}`).toString(16).padStart(8, "0"));
2526
2818
  }
2527
2819
  /**
2528
2820
  * Return the v4-in-v6 form of the address
2529
- * @memberof Address6
2530
- * @instance
2531
2821
  * @returns {String}
2532
2822
  */
2533
2823
  to4in6() {
@@ -2541,10 +2831,10 @@ var require_ipv6 = __commonJS({
2541
2831
  return correct + infix + address4.address;
2542
2832
  }
2543
2833
  /**
2544
- * Return an object containing the Teredo properties of the address
2545
- * @memberof Address6
2546
- * @instance
2547
- * @returns {Object}
2834
+ * Decodes the Teredo tunneling fields embedded in this address. Returns the
2835
+ * Teredo prefix, server IPv4, client IPv4, raw flag bits, cone-NAT flag,
2836
+ * UDP port, and Microsoft-format flag breakdown (reserved, universal/local,
2837
+ * group/individual, nonce). Only meaningful for addresses in `2001::/32`.
2548
2838
  */
2549
2839
  inspectTeredo() {
2550
2840
  const prefix = this.getBitsBase16(0, 32);
@@ -2552,7 +2842,7 @@ var require_ipv6 = __commonJS({
2552
2842
  const udpPort = (bitsForUdpPort ^ BigInt("0xffff")).toString();
2553
2843
  const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64));
2554
2844
  const bitsForClient4 = this.getBits(96, 128);
2555
- const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt("0xffffffff")).toString(16));
2845
+ const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt("0xffffffff")).toString(16).padStart(8, "0"));
2556
2846
  const flagsBase2 = this.getBitsBase2(64, 80);
2557
2847
  const coneNat = (0, common_1.testBit)(flagsBase2, 15);
2558
2848
  const reserved = (0, common_1.testBit)(flagsBase2, 14);
@@ -2575,10 +2865,9 @@ var require_ipv6 = __commonJS({
2575
2865
  };
2576
2866
  }
2577
2867
  /**
2578
- * Return an object containing the 6to4 properties of the address
2579
- * @memberof Address6
2580
- * @instance
2581
- * @returns {Object}
2868
+ * Decodes the 6to4 tunneling fields embedded in this address. Returns the
2869
+ * 6to4 prefix and the embedded IPv4 gateway address. Only meaningful for
2870
+ * addresses in `2002::/16`.
2582
2871
  */
2583
2872
  inspect6to4() {
2584
2873
  const prefix = this.getBitsBase16(0, 16);
@@ -2590,8 +2879,6 @@ var require_ipv6 = __commonJS({
2590
2879
  }
2591
2880
  /**
2592
2881
  * Return a v6 6to4 address from a v6 v4inv6 address
2593
- * @memberof Address6
2594
- * @instance
2595
2882
  * @returns {Address6}
2596
2883
  */
2597
2884
  to6to4() {
@@ -2608,9 +2895,73 @@ var require_ipv6 = __commonJS({
2608
2895
  return new _Address6(addr6to4);
2609
2896
  }
2610
2897
  /**
2611
- * Return a byte array
2612
- * @memberof Address6
2613
- * @instance
2898
+ * Embed an IPv4 address into a NAT64 IPv6 address using the encoding
2899
+ * defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052).
2900
+ * The default prefix is the well-known prefix `64:ff9b::/96`. The prefix
2901
+ * length must be one of 32, 40, 48, 56, 64, or 96; for prefixes shorter
2902
+ * than /64 the IPv4 octets are split around the reserved bits 64–71.
2903
+ * @example
2904
+ * Address6.fromAddress4Nat64('192.0.2.33').correctForm(); // '64:ff9b::c000:221'
2905
+ * Address6.fromAddress4Nat64('192.0.2.33', '2001:db8::/32').correctForm(); // '2001:db8:c000:221::'
2906
+ */
2907
+ static fromAddress4Nat64(address, prefix = "64:ff9b::/96") {
2908
+ const v4 = new ipv4_1.Address4(address);
2909
+ const prefix6 = new _Address6(prefix);
2910
+ const pl = prefix6.subnetMask;
2911
+ if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {
2912
+ throw new address_error_1.AddressError("NAT64 prefix length must be 32, 40, 48, 56, 64, or 96");
2913
+ }
2914
+ const prefixBits = prefix6.binaryZeroPad();
2915
+ const v4Bits = v4.binaryZeroPad();
2916
+ let bits;
2917
+ if (pl === 96) {
2918
+ bits = prefixBits.slice(0, 96) + v4Bits;
2919
+ } else {
2920
+ const beforeU = 64 - pl;
2921
+ bits = prefixBits.slice(0, pl) + v4Bits.slice(0, beforeU) + "00000000" + v4Bits.slice(beforeU) + "0".repeat(128 - 72 - (32 - beforeU));
2922
+ }
2923
+ const hex = BigInt(`0b${bits}`).toString(16).padStart(32, "0");
2924
+ const groups = [];
2925
+ for (let i = 0; i < 8; i++) {
2926
+ groups.push(hex.slice(i * 4, (i + 1) * 4));
2927
+ }
2928
+ return new _Address6(groups.join(":"));
2929
+ }
2930
+ /**
2931
+ * Extract the embedded IPv4 address from a NAT64 IPv6 address using the
2932
+ * encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052).
2933
+ * The default prefix is the well-known prefix `64:ff9b::/96`. Returns
2934
+ * `null` if this address is not contained within the given prefix.
2935
+ * @example
2936
+ * new Address6('64:ff9b::c000:221').toAddress4Nat64()!.correctForm(); // '192.0.2.33'
2937
+ */
2938
+ toAddress4Nat64(prefix = "64:ff9b::/96") {
2939
+ const prefix6 = new _Address6(prefix);
2940
+ const pl = prefix6.subnetMask;
2941
+ if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {
2942
+ throw new address_error_1.AddressError("NAT64 prefix length must be 32, 40, 48, 56, 64, or 96");
2943
+ }
2944
+ if (!this.isInSubnet(prefix6)) {
2945
+ return null;
2946
+ }
2947
+ const bits = this.binaryZeroPad();
2948
+ let v4Bits;
2949
+ if (pl === 96) {
2950
+ v4Bits = bits.slice(96, 128);
2951
+ } else {
2952
+ const beforeU = 64 - pl;
2953
+ v4Bits = bits.slice(pl, pl + beforeU) + bits.slice(72, 72 + (32 - beforeU));
2954
+ }
2955
+ const octets = [];
2956
+ for (let i = 0; i < 4; i++) {
2957
+ octets.push(parseInt(v4Bits.slice(i * 8, (i + 1) * 8), 2).toString());
2958
+ }
2959
+ return new ipv4_1.Address4(octets.join("."));
2960
+ }
2961
+ /**
2962
+ * Return a byte array.
2963
+ *
2964
+ * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toByteArray())`.
2614
2965
  * @returns {Array}
2615
2966
  */
2616
2967
  toByteArray() {
@@ -2624,27 +2975,27 @@ var require_ipv6 = __commonJS({
2624
2975
  return bytes;
2625
2976
  }
2626
2977
  /**
2627
- * Return an unsigned byte array
2628
- * @memberof Address6
2629
- * @instance
2978
+ * Return an unsigned byte array.
2979
+ *
2980
+ * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toUnsignedByteArray())`.
2630
2981
  * @returns {Array}
2631
2982
  */
2632
2983
  toUnsignedByteArray() {
2633
2984
  return this.toByteArray().map(unsignByte);
2634
2985
  }
2635
2986
  /**
2636
- * Convert a byte array to an Address6 object
2637
- * @memberof Address6
2638
- * @static
2987
+ * Convert a byte array to an Address6 object.
2988
+ *
2989
+ * To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`.
2639
2990
  * @returns {Address6}
2640
2991
  */
2641
2992
  static fromByteArray(bytes) {
2642
2993
  return this.fromUnsignedByteArray(bytes.map(unsignByte));
2643
2994
  }
2644
2995
  /**
2645
- * Convert an unsigned byte array to an Address6 object
2646
- * @memberof Address6
2647
- * @static
2996
+ * Convert an unsigned byte array to an Address6 object.
2997
+ *
2998
+ * To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`.
2648
2999
  * @returns {Address6}
2649
3000
  */
2650
3001
  static fromUnsignedByteArray(bytes) {
@@ -2659,8 +3010,6 @@ var require_ipv6 = __commonJS({
2659
3010
  }
2660
3011
  /**
2661
3012
  * Returns true if the address is in the canonical form, false otherwise
2662
- * @memberof Address6
2663
- * @instance
2664
3013
  * @returns {boolean}
2665
3014
  */
2666
3015
  isCanonical() {
@@ -2668,8 +3017,6 @@ var require_ipv6 = __commonJS({
2668
3017
  }
2669
3018
  /**
2670
3019
  * Returns true if the address is a link local address, false otherwise
2671
- * @memberof Address6
2672
- * @instance
2673
3020
  * @returns {boolean}
2674
3021
  */
2675
3022
  isLinkLocal() {
@@ -2680,53 +3027,81 @@ var require_ipv6 = __commonJS({
2680
3027
  }
2681
3028
  /**
2682
3029
  * Returns true if the address is a multicast address, false otherwise
2683
- * @memberof Address6
2684
- * @instance
2685
3030
  * @returns {boolean}
2686
3031
  */
2687
3032
  isMulticast() {
2688
- return this.getType() === "Multicast";
3033
+ const type = this.getType();
3034
+ return type === "Multicast" || type.startsWith("Multicast ");
2689
3035
  }
2690
3036
  /**
2691
- * Returns true if the address is a v4-in-v6 address, false otherwise
2692
- * @memberof Address6
2693
- * @instance
3037
+ * Returns true if the address was written in v4-in-v6 dotted-quad notation
3038
+ * (e.g. `::ffff:127.0.0.1`), false otherwise. This is a notation-level flag
3039
+ * and does not reflect whether the address bits lie in the IPv4-mapped
3040
+ * (`::ffff:0:0/96`) subnet — for that, see {@link isMapped4}.
2694
3041
  * @returns {boolean}
2695
3042
  */
2696
3043
  is4() {
2697
3044
  return this.v4;
2698
3045
  }
3046
+ /**
3047
+ * Returns true if the address is an IPv4-mapped IPv6 address in
3048
+ * `::ffff:0:0/96` ([RFC 4291 §2.5.5.2](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2)),
3049
+ * false otherwise. Unlike {@link is4}, this checks the underlying address
3050
+ * bits rather than the textual notation, so `::ffff:127.0.0.1` and
3051
+ * `::ffff:7f00:1` both return true.
3052
+ * @returns {boolean}
3053
+ */
3054
+ isMapped4() {
3055
+ return this.isInSubnet(IPV4_MAPPED_SUBNET);
3056
+ }
2699
3057
  /**
2700
3058
  * Returns true if the address is a Teredo address, false otherwise
2701
- * @memberof Address6
2702
- * @instance
2703
3059
  * @returns {boolean}
2704
3060
  */
2705
3061
  isTeredo() {
2706
- return this.isInSubnet(new _Address6("2001::/32"));
3062
+ return this.isInSubnet(TEREDO_SUBNET);
2707
3063
  }
2708
3064
  /**
2709
3065
  * Returns true if the address is a 6to4 address, false otherwise
2710
- * @memberof Address6
2711
- * @instance
2712
3066
  * @returns {boolean}
2713
3067
  */
2714
3068
  is6to4() {
2715
- return this.isInSubnet(new _Address6("2002::/16"));
3069
+ return this.isInSubnet(SIX_TO_FOUR_SUBNET);
2716
3070
  }
2717
3071
  /**
2718
3072
  * Returns true if the address is a loopback address, false otherwise
2719
- * @memberof Address6
2720
- * @instance
2721
3073
  * @returns {boolean}
2722
3074
  */
2723
3075
  isLoopback() {
2724
3076
  return this.getType() === "Loopback";
2725
3077
  }
3078
+ /**
3079
+ * Returns true if the address is a Unique Local Address in `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)). ULAs are the IPv6 equivalent of IPv4 [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private addresses.
3080
+ * @returns {boolean}
3081
+ */
3082
+ isULA() {
3083
+ return this.isInSubnet(ULA_SUBNET);
3084
+ }
3085
+ /**
3086
+ * Returns true if the address is the unspecified address `::`.
3087
+ * @returns {boolean}
3088
+ */
3089
+ isUnspecified() {
3090
+ return this.getType() === "Unspecified";
3091
+ }
3092
+ /**
3093
+ * Returns true if the address is in the documentation prefix `2001:db8::/32` ([RFC 3849](https://datatracker.ietf.org/doc/html/rfc3849)).
3094
+ * @returns {boolean}
3095
+ */
3096
+ isDocumentation() {
3097
+ return this.isInSubnet(DOCUMENTATION_SUBNET);
3098
+ }
2726
3099
  // #endregion
2727
3100
  // #region HTML
2728
3101
  /**
2729
- * @returns {String} the address in link form with a default port of 80
3102
+ * Returns the address as an HTTP URL with the host bracketed, e.g.
3103
+ * `http://[2001:db8::1]/`. If `optionalPort` is provided it is appended,
3104
+ * e.g. `http://[2001:db8::1]:8080/`.
2730
3105
  */
2731
3106
  href(optionalPort) {
2732
3107
  if (optionalPort === void 0) {
@@ -2737,7 +3112,12 @@ var require_ipv6 = __commonJS({
2737
3112
  return `http://[${this.correctForm()}]${optionalPort}/`;
2738
3113
  }
2739
3114
  /**
2740
- * @returns {String} a link suitable for conveying the address via a URL hash
3115
+ * Returns an HTML `<a>` element whose `href` encodes the address in a URL
3116
+ * hash fragment (default prefix `/#address=`). Useful for linking between
3117
+ * pages of an address-inspector UI.
3118
+ * @param options.className - CSS class for the rendered `<a>` element
3119
+ * @param options.prefix - hash prefix prepended to the address (default `/#address=`)
3120
+ * @param options.v4 - when true, render the address in v4-in-v6 form
2741
3121
  */
2742
3122
  link(options) {
2743
3123
  if (!options) {
@@ -2757,10 +3137,13 @@ var require_ipv6 = __commonJS({
2757
3137
  formFunction = this.to4in6;
2758
3138
  }
2759
3139
  const form = formFunction.call(this);
3140
+ const safeHref = helpers.escapeHtml(`${options.prefix}${form}`);
3141
+ const safeForm = helpers.escapeHtml(form);
2760
3142
  if (options.className) {
2761
- return `<a href="${options.prefix}${form}" class="${options.className}">${form}</a>`;
3143
+ const safeClass = helpers.escapeHtml(options.className);
3144
+ return `<a href="${safeHref}" class="${safeClass}">${safeForm}</a>`;
2762
3145
  }
2763
- return `<a href="${options.prefix}${form}">${form}</a>`;
3146
+ return `<a href="${safeHref}">${safeForm}</a>`;
2764
3147
  }
2765
3148
  /**
2766
3149
  * Groups an address
@@ -2768,12 +3151,12 @@ var require_ipv6 = __commonJS({
2768
3151
  */
2769
3152
  group() {
2770
3153
  if (this.elidedGroups === 0) {
2771
- return helpers.simpleGroup(this.address).join(":");
3154
+ return helpers.simpleGroup(this.addressMinusSuffix).join(":");
2772
3155
  }
2773
3156
  assert(typeof this.elidedGroups === "number");
2774
3157
  assert(typeof this.elisionBegin === "number");
2775
3158
  const output = [];
2776
- const [left, right] = this.address.split("::");
3159
+ const [left, right] = this.addressMinusSuffix.split("::");
2777
3160
  if (left.length) {
2778
3161
  output.push(...helpers.simpleGroup(left));
2779
3162
  } else {
@@ -2801,8 +3184,6 @@ var require_ipv6 = __commonJS({
2801
3184
  /**
2802
3185
  * Generate a regular expression string that can be used to find or validate
2803
3186
  * all variations of this address
2804
- * @memberof Address6
2805
- * @instance
2806
3187
  * @param {boolean} substringSearch
2807
3188
  * @returns {string}
2808
3189
  */
@@ -2841,8 +3222,6 @@ var require_ipv6 = __commonJS({
2841
3222
  /**
2842
3223
  * Generate a regular expression that can be used to find or validate all
2843
3224
  * variations of this address.
2844
- * @memberof Address6
2845
- * @instance
2846
3225
  * @param {boolean} substringSearch
2847
3226
  * @returns {RegExp}
2848
3227
  */
@@ -2851,12 +3230,21 @@ var require_ipv6 = __commonJS({
2851
3230
  }
2852
3231
  };
2853
3232
  exports.Address6 = Address6;
3233
+ var TYPE_SUBNETS = Object.keys(constants6.TYPES).map((subnet) => [
3234
+ new Address6(subnet),
3235
+ constants6.TYPES[subnet]
3236
+ ]);
3237
+ var TEREDO_SUBNET = new Address6("2001::/32");
3238
+ var SIX_TO_FOUR_SUBNET = new Address6("2002::/16");
3239
+ var ULA_SUBNET = new Address6("fc00::/7");
3240
+ var DOCUMENTATION_SUBNET = new Address6("2001:db8::/32");
3241
+ var IPV4_MAPPED_SUBNET = new Address6("::ffff:0:0/96");
2854
3242
  }
2855
3243
  });
2856
3244
 
2857
- // ../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/ip-address.js
3245
+ // ../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/ip-address.js
2858
3246
  var require_ip_address = __commonJS({
2859
- "../../node_modules/.pnpm/ip-address@10.0.1/node_modules/ip-address/dist/ip-address.js"(exports) {
3247
+ "../../node_modules/.pnpm/ip-address@10.2.0/node_modules/ip-address/dist/ip-address.js"(exports) {
2860
3248
  "use strict";
2861
3249
  var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
2862
3250
  if (k2 === void 0) k2 = k;