Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03.1k
1"use strict";2/* eslint-disable prefer-destructuring */3/* eslint-disable no-param-reassign */4var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {5 if (k2 === undefined) k2 = k;6 var desc = Object.getOwnPropertyDescriptor(m, k);7 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {8 desc = { enumerable: true, get: function() { return m[k]; } };9 }10 Object.defineProperty(o, k2, desc);11}) : (function(o, m, k, k2) {12 if (k2 === undefined) k2 = k;13 o[k2] = m[k];14}));15var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {16 Object.defineProperty(o, "default", { enumerable: true, value: v });17}) : function(o, v) {18 o["default"] = v;19});20var __importStar = (this && this.__importStar) || function (mod) {21 if (mod && mod.__esModule) return mod;22 var result = {};23 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);24 __setModuleDefault(result, mod);25 return result;26};27Object.defineProperty(exports, "__esModule", { value: true });28exports.Address6 = void 0;29const common = __importStar(require("./common"));30const constants4 = __importStar(require("./v4/constants"));31const constants6 = __importStar(require("./v6/constants"));32const helpers = __importStar(require("./v6/helpers"));33const ipv4_1 = require("./ipv4");34const regular_expressions_1 = require("./v6/regular-expressions");35const address_error_1 = require("./address-error");36const common_1 = require("./common");37const isCorrect6 = common.isCorrect(constants6.BITS);38function assert(condition) {39 if (!condition) {40 throw new Error('Assertion failed.');41 }42}43function addCommas(number) {44 const r = /(\d+)(\d{3})/;45 while (r.test(number)) {46 number = number.replace(r, '$1,$2');47 }48 return number;49}50function spanLeadingZeroes4(n) {51 n = n.replace(/^(0{1,})([1-9]+)$/, '<span class="parse-error">$1</span>$2');52 n = n.replace(/^(0{1,})(0)$/, '<span class="parse-error">$1</span>$2');53 return n;54}55/*56 * A helper function to compact an array57 */58function compact(address, slice) {59 const s1 = [];60 const s2 = [];61 let i;62 for (i = 0; i < address.length; i++) {63 if (i < slice[0]) {64 s1.push(address[i]);65 }66 else if (i > slice[1]) {67 s2.push(address[i]);68 }69 }70 return s1.concat(['compact']).concat(s2);71}72function paddedHex(octet) {73 return parseInt(octet, 16).toString(16).padStart(4, '0');74}75function unsignByte(b) {76 return b & 0xff;77}78/**79 * Represents an IPv6 address80 * @param {string} address - An IPv6 address string81 * @param {number} [groups=8] - How many octets to parse82 * @example83 * var address = new Address6('2001::/32');84 */85class Address6 {86 constructor(address, optionalGroups) {87 this.addressMinusSuffix = '';88 this.parsedSubnet = '';89 this.subnet = '/128';90 this.subnetMask = 128;91 this.v4 = false;92 this.zone = '';93 // #region Attributes94 /**95 * Returns true if the given address is in the subnet of the current address96 * @returns {boolean}97 */98 this.isInSubnet = common.isInSubnet;99 /**100 * Returns true if this address's host bits fall inside the given subnet,101 * ignoring this address's own subnet mask. See102 * {@link common.isHostInSubnet}.103 * @returns {boolean}104 */105 this.isHostInSubnet = common.isHostInSubnet;106 /**107 * Returns true if the address is correct, false otherwise108 * @returns {boolean}109 */110 this.isCorrect = isCorrect6;111 if (optionalGroups === undefined) {112 this.groups = constants6.GROUPS;113 }114 else {115 this.groups = optionalGroups;116 }117 this.address = address;118 const subnet = constants6.RE_SUBNET_STRING.exec(address);119 if (subnet) {120 this.parsedSubnet = subnet[0].replace('/', '');121 this.subnetMask = parseInt(this.parsedSubnet, 10);122 this.subnet = `/${this.subnetMask}`;123 if (Number.isNaN(this.subnetMask) ||124 this.subnetMask < 0 ||125 this.subnetMask > constants6.BITS) {126 throw new address_error_1.AddressError('Invalid subnet mask.');127 }128 address = address.replace(constants6.RE_SUBNET_STRING, '');129 }130 // RE_SUBNET_STRING anchors on the end of the address, so it strips only131 // the trailing suffix. A second one left behind (`::/0/1`) is malformed132 // and must be rejected rather than parsed as an address group.133 if (/\//.test(address)) {134 throw new address_error_1.AddressError('Invalid subnet mask.');135 }136 const zone = constants6.RE_ZONE_STRING.exec(address);137 if (zone) {138 this.zone = zone[0];139 address = address.replace(constants6.RE_ZONE_STRING, '');140 }141 this.addressMinusSuffix = address;142 this.parsedAddress = this.parse(this.addressMinusSuffix);143 }144 /**145 * Returns true if the given string is a valid IPv6 address (with optional146 * CIDR subnet and zone identifier), false otherwise. Host bits in the147 * subnet portion are allowed (e.g. `2001:db8::1/32` is valid); for strict148 * network-address validation compare `correctForm()` to149 * `startAddress().correctForm()`, or use `networkForm()`.150 */151 static isValid(address) {152 try {153 // eslint-disable-next-line no-new154 new Address6(address);155 return true;156 }157 catch {158 return false;159 }160 }161 /**162 * Convert a BigInt to a v6 address object. The value must be in the163 * range `[0, 2**128 - 1]`; otherwise `AddressError` is thrown.164 * @param {bigint} bigInt - a BigInt to convert165 * @returns {Address6}166 * @example167 * var bigInt = BigInt('1000000000000');168 * var address = Address6.fromBigInt(bigInt);169 * address.correctForm(); // '::e8:d4a5:1000'170 */171 static fromBigInt(bigInt) {172 if (bigInt < BigInt(0) || bigInt > (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1)) {173 throw new address_error_1.AddressError('IPv6 BigInt must be in the range 0 to 2**128 - 1');174 }175 const hex = bigInt.toString(16).padStart(32, '0');176 const groups = [];177 for (let i = 0; i < constants6.GROUPS; i++) {178 groups.push(hex.slice(i * 4, (i + 1) * 4));179 }180 return new Address6(groups.join(':'));181 }182 /**183 * Parse a URL (with optional bracketed host and port) into an address and184 * port. Returns either `{ address, port }` on success or185 * `{ error, address: null, port: null }` if the URL could not be parsed.186 * Ports are returned as numbers (or `null` if absent or out of range).187 * @example188 * var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/');189 * addressAndPort.address.correctForm(); // 'ffff::'190 * addressAndPort.port; // 8080191 */192 static fromURL(url) {193 var _a;194 let host;195 let port = null;196 let result;197 // Remove the protocol prefix, if any198 const stripped = url.replace(/^[a-z][a-z0-9+.-]*:\/\//i, '');199 // If we have brackets parse them and find a port200 if (stripped.indexOf('[') !== -1 && stripped.indexOf(']:') !== -1) {201 result = constants6.RE_URL_WITH_PORT.exec(stripped);202 if (result === null) {203 return {204 error: 'failed to parse address with port',205 address: null,206 port: null,207 };208 }209 host = result[1];210 port = result[2];211 }212 else {213 result = constants6.RE_URL.exec(stripped);214 if (result === null) {215 return {216 error: 'failed to parse address from URL',217 address: null,218 port: null,219 };220 }221 host = (_a = result[1]) !== null && _a !== void 0 ? _a : result[2];222 }223 // If there's a port convert it to an integer224 if (port) {225 port = parseInt(port, 10);226 // squelch out of range ports (valid ports are 0-65535)227 if (port < 0 || port > 65535) {228 port = null;229 }230 }231 else {232 // Standardize `undefined` to `null`233 port = null;234 }235 return {236 address: new Address6(host),237 port,238 };239 }240 /**241 * Construct an `Address6` from an address and a hex subnet mask given as242 * separate strings (e.g. as returned by Node's `os.networkInterfaces()`).243 * Throws `AddressError` if the mask is non-contiguous (e.g.244 * `ffff::ffff`).245 * @example246 * var address = Address6.fromAddressAndMask('fe80::1', 'ffff:ffff:ffff:ffff::');247 * address.subnetMask; // 64248 */249 static fromAddressAndMask(address, mask) {250 const bits = common.prefixLengthFromMask(new Address6(mask).bigInt(), constants6.BITS);251 return new Address6(`${address}/${bits}`);252 }253 /**254 * Construct an `Address6` from an address and a Cisco-style wildcard mask255 * given as separate strings (e.g. `::ffff:ffff:ffff:ffff` for a `/64`).256 * The wildcard mask is the bitwise inverse of the subnet mask. Throws257 * `AddressError` if the mask is non-contiguous.258 * @example259 * var address = Address6.fromAddressAndWildcardMask('fe80::1', '::ffff:ffff:ffff:ffff');260 * address.subnetMask; // 64261 */262 static fromAddressAndWildcardMask(address, wildcardMask) {263 const wildcard = new Address6(wildcardMask).bigInt();264 const allOnes = (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1);265 const mask = wildcard ^ allOnes;266 const bits = common.prefixLengthFromMask(mask, constants6.BITS);267 return new Address6(`${address}/${bits}`);268 }269 /**270 * Construct an `Address6` from a wildcard pattern with trailing `*`271 * groups. The number of trailing wildcards determines the prefix272 * length: each `*` represents 16 bits. `::` is expanded to zero groups273 * (not wildcards) before evaluating trailing wildcards.274 *275 * Only trailing whole-group wildcards are supported. Partial-group276 * wildcards (e.g. `2001:db8::0*`) and interior wildcards (e.g.277 * `*::1`) throw `AddressError`.278 * @example279 * Address6.fromWildcard('2001:db8:*:*:*:*:*:*').subnet; // '/32'280 * Address6.fromWildcard('2001:db8::*').subnet; // '/112'281 * Address6.fromWildcard('*:*:*:*:*:*:*:*').subnet; // '/0'282 */283 static fromWildcard(input) {284 if (input.includes('%') || input.includes('/')) {285 throw new address_error_1.AddressError('Wildcard pattern must not include a zone or CIDR suffix');286 }287 const halves = input.split('::');288 if (halves.length > 2) {289 throw new address_error_1.AddressError("Wildcard pattern cannot contain more than one '::'");290 }291 let groups;292 if (halves.length === 2) {293 const left = halves[0] === '' ? [] : halves[0].split(':');294 const right = halves[1] === '' ? [] : halves[1].split(':');295 const remaining = constants6.GROUPS - left.length - right.length;296 if (remaining < 1) {297 throw new address_error_1.AddressError("Wildcard pattern with '::' has too many groups");298 }299 groups = [...left, ...new Array(remaining).fill('0'), ...right];300 }301 else {302 groups = input.split(':');303 }304 if (groups.length !== constants6.GROUPS) {305 throw new address_error_1.AddressError('Wildcard pattern must have 8 groups');306 }307 let firstWildcard = -1;308 for (let i = 0; i < groups.length; i++) {309 if (groups[i] === '*') {310 if (firstWildcard === -1) {311 firstWildcard = i;312 }313 }314 else if (firstWildcard !== -1) {315 throw new address_error_1.AddressError('Wildcard `*` must only appear in trailing groups (e.g. `2001:db8:*:*:*:*:*:*`)');316 }317 }318 const trailing = firstWildcard === -1 ? 0 : groups.length - firstWildcard;319 const replaced = groups.map((g) => (g === '*' ? '0' : g));320 const subnetBits = constants6.BITS - trailing * 16;321 return new Address6(`${replaced.join(':')}/${subnetBits}`);322 }323 /**324 * Create an IPv6-mapped address given an IPv4 address325 * @param {string} address - An IPv4 address string326 * @returns {Address6}327 * @example328 * var address = Address6.fromAddress4('192.168.0.1');329 * address.correctForm(); // '::ffff:c0a8:1'330 * address.to4in6(); // '::ffff:192.168.0.1'331 */332 static fromAddress4(address) {333 const address4 = new ipv4_1.Address4(address);334 const mask6 = constants6.BITS - (constants4.BITS - address4.subnetMask);335 return new Address6(`::ffff:${address4.correctForm()}/${mask6}`);336 }337 /**338 * Return an address from ip6.arpa form339 * @param {string} arpaFormAddress - an 'ip6.arpa' form address340 * @returns {Adress6}341 * @example342 * 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.)343 * address.correctForm(); // '2001:0:ce49:7601:e866:efff:62c3:fffe'344 */345 static fromArpa(arpaFormAddress) {346 // remove ending ".ip6.arpa." or just "."347 let address = arpaFormAddress.replace(/(\.ip6\.arpa)?\.$/, '');348 const semicolonAmount = 7;349 // correct ip6.arpa form with ending removed will be 63 characters350 if (address.length !== 63) {351 throw new address_error_1.AddressError("Invalid 'ip6.arpa' form.");352 }353 const parts = address.split('.').reverse();354 for (let i = semicolonAmount; i > 0; i--) {355 const insertIndex = i * 4;356 parts.splice(insertIndex, 0, ':');357 }358 address = parts.join('');359 return new Address6(address);360 }361 /**362 * Return the Microsoft UNC transcription of the address363 * @returns {String} the Microsoft UNC transcription of the address364 */365 microsoftTranscription() {366 return `${this.correctForm().replace(/:/g, '-')}.ipv6-literal.net`;367 }368 /**369 * Return the first n bits of the address, defaulting to the subnet mask370 * @param {number} [mask=subnet] - the number of bits to mask371 * @returns {String} the first n bits of the address as a string372 */373 mask(mask = this.subnetMask) {374 return this.getBitsBase2(0, mask);375 }376 /**377 * Return the number of possible subnets of a given size in the address378 * @param {number} [subnetSize=128] - the subnet size379 * @returns {String}380 */381 // TODO: probably useful to have a numeric version of this too382 possibleSubnets(subnetSize = 128) {383 const availableBits = constants6.BITS - this.subnetMask;384 const subnetBits = Math.abs(subnetSize - constants6.BITS);385 const subnetPowers = availableBits - subnetBits;386 if (subnetPowers < 0) {387 return '0';388 }389 return addCommas((BigInt('2') ** BigInt(subnetPowers)).toString(10));390 }391 /**392 * Helper function getting start address.393 * @returns {bigint}394 */395 _startAddress() {396 return BigInt(`0b${this.mask() + '0'.repeat(constants6.BITS - this.subnetMask)}`);397 }398 /**399 * The first address in the range given by this address' subnet400 * Often referred to as the Network Address.401 * @returns {Address6}402 */403 startAddress() {404 return Address6.fromBigInt(this._startAddress());405 }406 /**407 * The first host address in the range given by this address's subnet ie408 * the first address after the Network Address409 * @returns {Address6}410 */411 startAddressExclusive() {412 const adjust = BigInt('1');413 return Address6.fromBigInt(this._startAddress() + adjust);414 }415 /**416 * Helper function getting end address.417 * @returns {bigint}418 */419 _endAddress() {420 return BigInt(`0b${this.mask() + '1'.repeat(constants6.BITS - this.subnetMask)}`);421 }422 /**423 * The last address in the range given by this address' subnet424 * Often referred to as the Broadcast425 * @returns {Address6}426 */427 endAddress() {428 return Address6.fromBigInt(this._endAddress());429 }430 /**431 * The last host address in the range given by this address's subnet ie432 * the last address prior to the Broadcast Address433 * @returns {Address6}434 */435 endAddressExclusive() {436 const adjust = BigInt('1');437 return Address6.fromBigInt(this._endAddress() - adjust);438 }439 /**440 * The hex form of the subnet mask, e.g. `ffff:ffff:ffff:ffff::` for a441 * `/64`. Returns an `Address6`; call `.correctForm()` for the string.442 * @returns {Address6}443 */444 subnetMaskAddress() {445 return Address6.fromBigInt(BigInt(`0b${'1'.repeat(this.subnetMask)}${'0'.repeat(constants6.BITS - this.subnetMask)}`));446 }447 /**448 * The Cisco-style wildcard mask, e.g. `::ffff:ffff:ffff:ffff` for a449 * `/64`. This is the bitwise inverse of `subnetMaskAddress()`. Returns450 * an `Address6`; call `.correctForm()` for the string.451 * @returns {Address6}452 */453 wildcardMask() {454 return Address6.fromBigInt(BigInt(`0b${'0'.repeat(this.subnetMask)}${'1'.repeat(constants6.BITS - this.subnetMask)}`));455 }456 /**457 * The network address in CIDR string form, e.g. `2001:db8::/32` for458 * `2001:db8::1/32`. For an address with no explicit subnet the prefix459 * is `/128`, e.g. `networkForm()` on `2001:db8::1` returns460 * `2001:db8::1/128`.461 * @returns {string}462 */463 networkForm() {464 return `${this.startAddress().correctForm()}/${this.subnetMask}`;465 }466 /**467 * Return the scope of the address. The 4-bit scope field468 * ([RFC 4291 §2.7](https://datatracker.ietf.org/doc/html/rfc4291#section-2.7))469 * is only defined for multicast addresses; for unicast addresses the scope470 * is derived from the address type per471 * [RFC 4007 §6](https://datatracker.ietf.org/doc/html/rfc4007#section-6).472 * @returns {String}473 */474 getScope() {475 const type = this.getType();476 if (type === 'Multicast' || type.startsWith('Multicast ')) {477 const scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)];478 return scope || 'Unknown';479 }480 // RFC 4291 §2.5.3: the loopback address is treated as having Link-Local481 // scope. (Multicast scope 1, "Interface-Local", is a different concept482 // used only for loopback transmission of multicast.)483 if (type === 'Link-local unicast' || type === 'Loopback') {484 return 'Link local';485 }486 // RFC 4007 §6: the unspecified address has no scope.487 if (type === 'Unspecified') {488 return 'Unknown';489 }490 return 'Global';491 }492 /**493 * Return the type of the address494 * @returns {String}495 */496 getType() {497 for (let i = 0; i < TYPE_SUBNETS.length; i++) {498 const entry = TYPE_SUBNETS[i];499 if (this.isHostInSubnet(entry[0])) {500 return entry[1];501 }502 }503 return 'Global unicast';504 }505 /**506 * Return the bits in the given range as a BigInt507 * @returns {bigint}508 */509 getBits(start, end) {510 return BigInt(`0b${this.getBitsBase2(start, end)}`);511 }512 /**513 * Return the bits in the given range as a base-2 string514 * @returns {String}515 */516 getBitsBase2(start, end) {517 return this.binaryZeroPad().slice(start, end);518 }519 /**520 * Return the bits in the given range as a base-16 string521 * @returns {String}522 */523 getBitsBase16(start, end) {524 const length = end - start;525 if (length % 4 !== 0) {526 throw new Error('Length of bits to retrieve must be divisible by four');527 }528 return this.getBits(start, end)529 .toString(16)530 .padStart(length / 4, '0');531 }532 /**533 * Return the bits that are set past the subnet mask length534 * @returns {String}535 */536 getBitsPastSubnet() {537 return this.getBitsBase2(this.subnetMask, constants6.BITS);538 }539 /**540 * Return the reversed ip6.arpa form of the address541 * @param {Object} options542 * @param {boolean} options.omitSuffix - omit the "ip6.arpa" suffix543 * @returns {String}544 */545 reverseForm(options) {546 if (!options) {547 options = {};548 }549 const characters = Math.floor(this.subnetMask / 4);550 const reversed = this.canonicalForm()551 .replace(/:/g, '')552 .split('')553 .slice(0, characters)554 .reverse()555 .join('.');556 if (characters > 0) {557 if (options.omitSuffix) {558 return reversed;559 }560 return `${reversed}.ip6.arpa.`;561 }562 if (options.omitSuffix) {563 return '';564 }565 return 'ip6.arpa.';566 }567 /**568 * Returns the address in correct form, per569 * [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952): leading zeros570 * stripped, the longest run of zero groups collapsed to `::`, and hex digits571 * lowercased (e.g. `2001:db8::1`). This is the recommended form for display.572 */573 correctForm() {574 let i;575 let groups = [];576 let zeroCounter = 0;577 const zeroes = [];578 for (i = 0; i < this.parsedAddress.length; i++) {579 const value = parseInt(this.parsedAddress[i], 16);580 if (value === 0) {581 zeroCounter++;582 }583 if (value !== 0 && zeroCounter > 0) {584 if (zeroCounter > 1) {585 zeroes.push([i - zeroCounter, i - 1]);586 }587 zeroCounter = 0;588 }589 }590 // Do we end with a string of zeroes?591 if (zeroCounter > 1) {592 zeroes.push([this.parsedAddress.length - zeroCounter, this.parsedAddress.length - 1]);593 }594 const zeroLengths = zeroes.map((n) => n[1] - n[0] + 1);595 if (zeroes.length > 0) {596 const index = zeroLengths.indexOf(Math.max(...zeroLengths));597 groups = compact(this.parsedAddress, zeroes[index]);598 }599 else {600 groups = this.parsedAddress;601 }602 for (i = 0; i < groups.length; i++) {603 if (groups[i] !== 'compact') {604 groups[i] = parseInt(groups[i], 16).toString(16);605 }606 }607 let correct = groups.join(':');608 correct = correct.replace(/^compact$/, '::');609 correct = correct.replace(/(^compact)|(compact$)/, ':');610 correct = correct.replace(/compact/, '');611 return correct;612 }613 /**614 * Return a zero-padded base-2 string representation of the address615 * @returns {String}616 * @example617 * var address = new Address6('2001:4860:4001:803::1011');618 * address.binaryZeroPad();619 * // '0010000000000001010010000110000001000000000000010000100000000011620 * // 0000000000000000000000000000000000000000000000000001000000010001'621 */622 binaryZeroPad() {623 if (this._binaryZeroPad === undefined) {624 this._binaryZeroPad = this.bigInt().toString(2).padStart(constants6.BITS, '0');625 }626 return this._binaryZeroPad;627 }628 /**629 * Parses a v4-in-v6 string (e.g. `::ffff:192.168.0.1`) by extracting the630 * trailing IPv4 address into `this.address4` / `this.parsedAddress4` and631 * returning the address with the v4 portion converted to two v6 groups.632 * Used internally by `parse()`.633 */634 // TODO: Improve the semantics of this helper function635 parse4in6(address) {636 if (address.indexOf('.') === -1) {637 return address;638 }639 const groups = address.split(':');640 const lastGroup = groups.slice(-1)[0];641 // RE_ADDRESS rejects octets with a leading zero, so a dotted-quad tail is642 // matched permissively first: that way this notation still gets its own643 // message with the offending octet highlighted, rather than falling644 // through as an unrecognized group.645 const v4Octets = lastGroup.split('.');646 if (v4Octets.length === constants4.GROUPS &&647 v4Octets.every((octet) => /^\d{1,3}$/.test(octet))) {648 if (v4Octets.some((octet) => /^0\d/.test(octet))) {649 // The prefix groups haven't been through the bad-character check650 // yet, so escape them before including in the error HTML.651 const highlighted = v4Octets.map(spanLeadingZeroes4).join('.');652 const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':');653 const separator = groups.length > 1 ? ':' : '';654 throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`);655 }656 }657 const address4 = lastGroup.match(constants4.RE_ADDRESS);658 if (address4) {659 this.parsedAddress4 = address4[0];660 const v4Suffix = this.subnetMask >= 96 ? `/${this.subnetMask - 96}` : '';661 this.address4 = new ipv4_1.Address4(`${this.parsedAddress4}${v4Suffix}`);662 this.v4 = true;663 groups[groups.length - 1] = this.address4.toGroup6();664 address = groups.join(':');665 }666 return address;667 }668 /**669 * Parses an IPv6 address string into its 8 hexadecimal groups (expanding670 * any `::` elision and any trailing v4-in-v6 portion) and stores the result671 * on `this.parsedAddress`. Called automatically by the constructor; you672 * typically don't need to call it directly. Throws `AddressError` if the673 * input is malformed.674 */675 // TODO: Make private?676 parse(address) {677 address = this.parse4in6(address);678 const badCharacters = address.match(constants6.RE_BAD_CHARACTERS);679 if (badCharacters) {680 throw new address_error_1.AddressError(`Bad character${badCharacters.length > 1 ? 's' : ''} detected in address: ${badCharacters.join('')}`, address.replace(constants6.RE_BAD_CHARACTERS, '<span class="parse-error">$1</span>'));681 }682 const badAddress = address.match(constants6.RE_BAD_ADDRESS);683 if (badAddress) {684 throw new address_error_1.AddressError(`Address failed regex: ${badAddress.join('')}`, address.replace(constants6.RE_BAD_ADDRESS, '<span class="parse-error">$1</span>'));685 }686 let groups = [];687 const halves = address.split('::');688 if (halves.length === 2) {689 let first = halves[0].split(':');690 let last = halves[1].split(':');691 if (first.length === 1 && first[0] === '') {692 first = [];693 }694 if (last.length === 1 && last[0] === '') {695 last = [];696 }697 const remaining = this.groups - (first.length + last.length);698 if (!remaining) {699 throw new address_error_1.AddressError('Error parsing groups');700 }701 this.elidedGroups = remaining;702 this.elisionBegin = first.length;703 this.elisionEnd = first.length + this.elidedGroups;704 groups = groups.concat(first);705 for (let i = 0; i < remaining; i++) {706 groups.push('0');707 }708 groups = groups.concat(last);709 }710 else if (halves.length === 1) {711 groups = address.split(':');712 this.elidedGroups = 0;713 }714 else {715 throw new address_error_1.AddressError('Too many :: groups found');716 }717 groups = groups.map((group) => parseInt(group, 16).toString(16));718 if (groups.length !== this.groups) {719 throw new address_error_1.AddressError('Incorrect number of groups found');720 }721 return groups;722 }723 /**724 * Returns the canonical (fully expanded) form of the address: all 8 groups,725 * each padded to 4 hex digits, with no `::` collapsing726 * (e.g. `2001:0db8:0000:0000:0000:0000:0000:0001`). Useful for sorting and727 * byte-exact comparison.728 */729 canonicalForm() {730 return this.parsedAddress.map(paddedHex).join(':');731 }732 /**733 * Return the decimal form of the address734 * @returns {String}735 */736 decimal() {737 return this.parsedAddress.map((n) => parseInt(n, 16).toString(10).padStart(5, '0')).join(':');738 }739 /**740 * Return the address as a BigInt741 * @returns {bigint}742 */743 bigInt() {744 return BigInt(`0x${this.parsedAddress.map(paddedHex).join('')}`);745 }746 /**747 * Return the last two groups of this address as an IPv4 address string.748 * If this address carries a CIDR prefix that covers the trailing 32 bits749 * (i.e. `subnetMask >= 96`), the resulting `Address4` inherits the750 * corresponding v4 prefix (`subnetMask - 96`); otherwise it defaults to751 * `/32`.752 * @returns {Address4}753 * @example754 * var address = new Address6('2001:4860:4001::1825:bf11');755 * address.to4().correctForm(); // '24.37.191.17'756 */757 to4() {758 const binary = this.binaryZeroPad().split('');759 const hex = BigInt(`0b${binary.slice(96, 128).join('')}`)760 .toString(16)761 .padStart(8, '0');762 if (this.subnetMask >= 96) {763 const v4Mask = this.subnetMask - 96;764 const groups = [];765 for (let i = 0; i < 8; i += 2) {766 groups.push(parseInt(hex.slice(i, i + 2), 16));767 }768 return new ipv4_1.Address4(`${groups.join('.')}/${v4Mask}`);769 }770 return ipv4_1.Address4.fromHex(hex);771 }772 /**773 * Return the v4-in-v6 form of the address774 * @returns {String}775 */776 to4in6() {777 const address4 = this.to4();778 const address6 = new Address6(this.parsedAddress.slice(0, 6).join(':'), 6);779 const correct = address6.correctForm();780 let infix = '';781 if (!/:$/.test(correct)) {782 infix = ':';783 }784 return correct + infix + address4.correctForm();785 }786 /**787 * Decodes the Teredo tunneling fields embedded in this address. Returns the788 * Teredo prefix, server IPv4, client IPv4, raw flag bits, cone-NAT flag,789 * UDP port, and Microsoft-format flag breakdown (reserved, universal/local,790 * group/individual, nonce). Only meaningful for addresses in `2001::/32`.791 */792 inspectTeredo() {793 /*794 - Bits 0 to 31 are set to the Teredo prefix (normally 2001:0000::/32).795 - Bits 32 to 63 embed the primary IPv4 address of the Teredo server that796 is used.797 - Bits 64 to 79 can be used to define some flags. Currently only the798 higher order bit is used; it is set to 1 if the Teredo client is799 located behind a cone NAT, 0 otherwise. For Microsoft's Windows Vista800 and Windows Server 2008 implementations, more bits are used. In those801 implementations, the format for these 16 bits is "CRAAAAUG AAAAAAAA",802 where "C" remains the "Cone" flag. The "R" bit is reserved for future803 use. The "U" bit is for the Universal/Local flag (set to 0). The "G" bit804 is Individual/Group flag (set to 0). The A bits are set to a 12-bit805 randomly generated number chosen by the Teredo client to introduce806 additional protection for the Teredo node against IPv6-based scanning807 attacks.808 - Bits 80 to 95 contains the obfuscated UDP port number. This is the809 port number that is mapped by the NAT to the Teredo client with all810 bits inverted.811 - Bits 96 to 127 contains the obfuscated IPv4 address. This is the812 public IPv4 address of the NAT with all bits inverted.813 */814 const prefix = this.getBitsBase16(0, 32);815 const bitsForUdpPort = this.getBits(80, 96);816 const udpPort = (bitsForUdpPort ^ BigInt('0xffff')).toString();817 const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64));818 const bitsForClient4 = this.getBits(96, 128);819 const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16).padStart(8, '0'));820 const flagsBase2 = this.getBitsBase2(64, 80);821 const coneNat = (0, common_1.testBit)(flagsBase2, 15);822 const reserved = (0, common_1.testBit)(flagsBase2, 14);823 const groupIndividual = (0, common_1.testBit)(flagsBase2, 8);824 const universalLocal = (0, common_1.testBit)(flagsBase2, 9);825 const nonce = BigInt(`0b${flagsBase2.slice(2, 6) + flagsBase2.slice(8, 16)}`).toString(10);826 return {827 prefix: `${prefix.slice(0, 4)}:${prefix.slice(4, 8)}`,828 server4: server4.address,829 client4: client4.address,830 flags: flagsBase2,831 coneNat,832 microsoft: {833 reserved,834 universalLocal,835 groupIndividual,836 nonce,837 },838 udpPort,839 };840 }841 /**842 * Decodes the 6to4 tunneling fields embedded in this address. Returns the843 * 6to4 prefix and the embedded IPv4 gateway address. Only meaningful for844 * addresses in `2002::/16`.845 */846 inspect6to4() {847 /*848 - Bits 0 to 15 are set to the 6to4 prefix (2002::/16).849 - Bits 16 to 48 embed the IPv4 address of the 6to4 gateway that is used.850 */851 const prefix = this.getBitsBase16(0, 16);852 const gateway = ipv4_1.Address4.fromHex(this.getBitsBase16(16, 48));853 return {854 prefix: prefix.slice(0, 4),855 gateway: gateway.address,856 };857 }858 /**859 * Return a v6 6to4 address from a v6 v4inv6 address860 * @returns {Address6}861 */862 to6to4() {863 if (!this.is4()) {864 return null;865 }866 const addr6to4 = [867 '2002',868 this.getBitsBase16(96, 112),869 this.getBitsBase16(112, 128),870 '',871 '/16',872 ].join(':');873 return new Address6(addr6to4);874 }875 /**876 * Embed an IPv4 address into a NAT64 IPv6 address using the encoding877 * defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052).878 * The default prefix is the well-known prefix `64:ff9b::/96`. The prefix879 * length must be one of 32, 40, 48, 56, 64, or 96; for prefixes shorter880 * than /64 the IPv4 octets are split around the reserved bits 64–71.881 * @example882 * Address6.fromAddress4Nat64('192.0.2.33').correctForm(); // '64:ff9b::c000:221'883 * Address6.fromAddress4Nat64('192.0.2.33', '2001:db8::/32').correctForm(); // '2001:db8:c000:221::'884 */885 static fromAddress4Nat64(address, prefix = '64:ff9b::/96') {886 const v4 = new ipv4_1.Address4(address);887 const prefix6 = new Address6(prefix);888 const pl = prefix6.subnetMask;889 if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {890 throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96');891 }892 const prefixBits = prefix6.binaryZeroPad();893 const v4Bits = v4.binaryZeroPad();894 let bits;895 if (pl === 96) {896 bits = prefixBits.slice(0, 96) + v4Bits;897 }898 else {899 const beforeU = 64 - pl;900 bits = [901 prefixBits.slice(0, pl),902 v4Bits.slice(0, beforeU),903 // Bits 64 to 71 are the reserved u octet and are always zero.904 '00000000',905 v4Bits.slice(beforeU),906 '0'.repeat(128 - 72 - (32 - beforeU)),907 ].join('');908 }909 const hex = BigInt(`0b${bits}`).toString(16).padStart(32, '0');910 const groups = [];911 for (let i = 0; i < 8; i++) {912 groups.push(hex.slice(i * 4, (i + 1) * 4));913 }914 return new Address6(groups.join(':'));915 }916 /**917 * Extract the embedded IPv4 address from a NAT64 IPv6 address using the918 * encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052).919 * The default prefix is the well-known prefix `64:ff9b::/96`. Returns920 * `null` if this address is not contained within the given prefix.921 * @example922 * new Address6('64:ff9b::c000:221').toAddress4Nat64()!.correctForm(); // '192.0.2.33'923 */924 toAddress4Nat64(prefix = '64:ff9b::/96') {925 const prefix6 = new Address6(prefix);926 const pl = prefix6.subnetMask;927 if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {928 throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96');929 }930 if (!this.isHostInSubnet(prefix6)) {931 return null;932 }933 const bits = this.binaryZeroPad();934 let v4Bits;935 if (pl === 96) {936 v4Bits = bits.slice(96, 128);937 }938 else {939 const beforeU = 64 - pl;940 v4Bits = bits.slice(pl, pl + beforeU) + bits.slice(72, 72 + (32 - beforeU));941 }942 const octets = [];943 for (let i = 0; i < 4; i++) {944 octets.push(parseInt(v4Bits.slice(i * 8, (i + 1) * 8), 2).toString());945 }946 return new ipv4_1.Address4(octets.join('.'));947 }948 /**949 * Return a byte array.950 *951 * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toByteArray())`.952 * @returns {Array}953 */954 toByteArray() {955 const value = this.bigInt()956 .toString(16)957 .padStart(constants6.BITS / 4, '0');958 const bytes = [];959 for (let i = 0, length = value.length; i < length; i += 2) {960 bytes.push(parseInt(value.substring(i, i + 2), 16));961 }962 return bytes;963 }964 /**965 * Return an unsigned byte array.966 *967 * To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toUnsignedByteArray())`.968 * @returns {Array}969 */970 toUnsignedByteArray() {971 // toByteArray() emits 0 to 255, so unsigning it is an identity mapping and972 // the two methods return equal arrays. 11.0.0 keeps one of them and makes973 // this a deprecated alias; test/common-test.ts fails at that version.974 return this.toByteArray().map(unsignByte);975 }976 /**977 * Convert a byte array to an Address6 object.978 *979 * Accepts unsigned bytes (0 to 255) or signed bytes (-128 to 127, as an980 * `Int8Array` or a Java `byte[]` holds them), folding signed values to their981 * unsigned equivalent. Throws `AddressError` unless given exactly 16982 * integers from -128 to 255.983 *984 * To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`.985 * @returns {Address6}986 */987 static fromByteArray(bytes) {988 // Address4.fromByteArray takes unsigned bytes only. 11.0.0 aligns this989 // method with it, at which point the -128 floor here, unsignByte, and the990 // mapping below all go; test/common-test.ts fails at that version.991 common.assertByteArray(bytes, 16, 'IPv6', -128);992 return this.fromUnsignedByteArray(bytes.map(unsignByte));993 }994 /**995 * Convert an unsigned byte array to an Address6 object.996 *997 * Throws `AddressError` unless given exactly 16 integers from 0 to 255.998 *999 * To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`.1000 * @returns {Address6}1001 */1002 static fromUnsignedByteArray(bytes) {1003 common.assertByteArray(bytes, 16, 'IPv6', 0);1004 const BYTE_MAX = BigInt('256');1005 let result = BigInt('0');1006 let multiplier = BigInt('1');1007 for (let i = bytes.length - 1; i >= 0; i--) {1008 result += multiplier * BigInt(bytes[i].toString(10));1009 multiplier *= BYTE_MAX;1010 }1011 return Address6.fromBigInt(result);1012 }1013 /**1014 * Returns true if the address is in the canonical form, false otherwise1015 * @returns {boolean}1016 */1017 isCanonical() {1018 return this.addressMinusSuffix === this.canonicalForm();1019 }1020 /**1021 * Returns true if the address is a link local address, false otherwise1022 * @returns {boolean}1023 */1024 isLinkLocal() {1025 const embedded = this.embeddedIPv4();1026 if (embedded) {1027 return embedded.isLinkLocal();1028 }1029 // Zeroes are required, i.e. we can't check isHostInSubnet with 'fe80::/10'1030 if (this.getBitsBase2(0, 64) ===1031 '1111111010000000000000000000000000000000000000000000000000000000') {1032 return true;1033 }1034 return false;1035 }1036 /**1037 * Returns true if the address is a multicast address, false otherwise1038 * @returns {boolean}1039 */1040 isMulticast() {1041 const embedded = this.embeddedIPv4();1042 if (embedded) {1043 return embedded.isMulticast();1044 }1045 const type = this.getType();1046 return type === 'Multicast' || type.startsWith('Multicast ');1047 }1048 /**1049 * Returns true if the address was written in v4-in-v6 dotted-quad notation1050 * (e.g. `::ffff:127.0.0.1`), false otherwise. This is a notation-level flag1051 * and does not reflect whether the address bits lie in the IPv4-mapped1052 * (`::ffff:0:0/96`) subnet — for that, see {@link isMapped4}.1053 * @returns {boolean}1054 */1055 is4() {1056 return this.v4;1057 }1058 /**1059 * Returns true if the address is an IPv4-mapped IPv6 address in1060 * `::ffff:0:0/96` ([RFC 4291 §2.5.5.2](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2)),1061 * false otherwise. Unlike {@link is4}, this checks the underlying address1062 * bits rather than the textual notation, so `::ffff:127.0.0.1` and1063 * `::ffff:7f00:1` both return true.1064 * @returns {boolean}1065 */1066 isMapped4() {1067 return this.isHostInSubnet(IPV4_MAPPED_SUBNET);1068 }1069 /**1070 * If this address embeds a routable IPv4 address — i.e. it is IPv4-mapped1071 * (`::ffff:0:0/96`) or sits in the NAT64 well-known prefix (`64:ff9b::/96`,1072 * [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052)) — return that1073 * embedded address as an {@link Address4}; otherwise return null.1074 *1075 * The special-property checks (`isLoopback`, `isLinkLocal`, `isMulticast`,1076 * `isUnspecified`, `isPrivate`, `isCGNAT`, `isBroadcast`) call this first and1077 * delegate to the embedded {@link Address4} when present, so a literal such as1078 * `::ffff:127.0.0.1` is classified by what it actually reaches (loopback)1079 * rather than by its IPv6 wrapper (which `getType()` reports as IPv4-mapped).1080 * This matters wherever the checks back a trust-boundary decision (e.g. an1081 * SSRF allow/deny filter): without normalization, `::ffff:10.0.0.1`,1082 * `::ffff:169.254.169.254`, `64:ff9b::7f00:1`, etc. would all read as1083 * non-internal.1084 * @returns {Address4 | null}1085 */1086 embeddedIPv4() {1087 if (this.isMapped4() || this.isHostInSubnet(NAT64_WELL_KNOWN_SUBNET)) {1088 return this.to4();1089 }1090 return null;1091 }1092 /**1093 * Returns true if the address is a Teredo address, false otherwise1094 * @returns {boolean}1095 */1096 isTeredo() {1097 return this.isHostInSubnet(TEREDO_SUBNET);1098 }1099 /**1100 * Returns true if the address is a 6to4 address, false otherwise1101 * @returns {boolean}1102 */1103 is6to4() {1104 return this.isHostInSubnet(SIX_TO_FOUR_SUBNET);1105 }1106 /**1107 * Returns true if the address is a loopback address, false otherwise1108 * @returns {boolean}1109 */1110 isLoopback() {1111 const embedded = this.embeddedIPv4();1112 if (embedded) {1113 return embedded.isLoopback();1114 }1115 return this.getType() === 'Loopback';1116 }1117 /**1118 * 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.1119 * @returns {boolean}1120 */1121 isULA() {1122 return this.isHostInSubnet(ULA_SUBNET);1123 }1124 /**1125 * Returns true if the address is private, i.e. a Unique Local Address in1126 * `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)) or an1127 * IPv4-mapped / NAT64 address whose embedded IPv4 address is in one of the1128 * [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private ranges1129 * (e.g. `::ffff:10.0.0.1`). This is the IPv6 counterpart to1130 * {@link Address4.isPrivate}; use it instead of {@link isULA} when you need to1131 * catch mapped RFC 1918 addresses as well as native ULAs.1132 * @returns {boolean}1133 */1134 isPrivate() {1135 const embedded = this.embeddedIPv4();1136 if (embedded) {1137 return embedded.isPrivate();1138 }1139 return this.isULA();1140 }1141 /**1142 * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded1143 * IPv4 address is in the carrier-grade NAT range `100.64.0.0/10`1144 * ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)), false1145 * otherwise. There is no native IPv6 CGNAT range, so this only ever returns1146 * true for an embedded IPv4 address (e.g. `::ffff:100.64.0.1`).1147 * @returns {boolean}1148 */1149 isCGNAT() {1150 const embedded = this.embeddedIPv4();1151 if (embedded) {1152 return embedded.isCGNAT();1153 }1154 return false;1155 }1156 /**1157 * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded1158 * IPv4 address is the limited broadcast address `255.255.255.255`1159 * ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)), false otherwise.1160 * There is no IPv6 broadcast, so this only ever returns true for an embedded1161 * IPv4 address (e.g. `::ffff:255.255.255.255`).1162 * @returns {boolean}1163 */1164 isBroadcast() {1165 const embedded = this.embeddedIPv4();1166 if (embedded) {1167 return embedded.isBroadcast();1168 }1169 return false;1170 }1171 /**1172 * Returns true if the address is the unspecified address `::`.1173 * @returns {boolean}1174 */1175 isUnspecified() {1176 const embedded = this.embeddedIPv4();1177 if (embedded) {1178 return embedded.isUnspecified();1179 }1180 return this.getType() === 'Unspecified';1181 }1182 /**1183 * Returns true if the address is in the documentation prefix `2001:db8::/32` ([RFC 3849](https://datatracker.ietf.org/doc/html/rfc3849)).1184 * @returns {boolean}1185 */1186 isDocumentation() {1187 return this.isHostInSubnet(DOCUMENTATION_SUBNET);1188 }1189 // #endregion1190 // #region HTML1191 /**1192 * Returns the address as an HTTP URL with the host bracketed, e.g.1193 * `http://[2001:db8::1]/`. If `optionalPort` is provided it is appended,1194 * e.g. `http://[2001:db8::1]:8080/`.1195 */1196 href(optionalPort) {1197 if (optionalPort === undefined) {1198 optionalPort = '';1199 }1200 else {