You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					1298 lines
				
				33 KiB
			
		
		
			
		
	
	
					1298 lines
				
				33 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"use strict";
							 | 
						||
| 
								 | 
							
								const punycode = require("punycode");
							 | 
						||
| 
								 | 
							
								const tr46 = require("tr46");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const specialSchemes = {
							 | 
						||
| 
								 | 
							
								  ftp: 21,
							 | 
						||
| 
								 | 
							
								  file: null,
							 | 
						||
| 
								 | 
							
								  gopher: 70,
							 | 
						||
| 
								 | 
							
								  http: 80,
							 | 
						||
| 
								 | 
							
								  https: 443,
							 | 
						||
| 
								 | 
							
								  ws: 80,
							 | 
						||
| 
								 | 
							
								  wss: 443
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const failure = Symbol("failure");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function countSymbols(str) {
							 | 
						||
| 
								 | 
							
								  return punycode.ucs2.decode(str).length;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function at(input, idx) {
							 | 
						||
| 
								 | 
							
								  const c = input[idx];
							 | 
						||
| 
								 | 
							
								  return isNaN(c) ? undefined : String.fromCodePoint(c);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isASCIIDigit(c) {
							 | 
						||
| 
								 | 
							
								  return c >= 0x30 && c <= 0x39;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isASCIIAlpha(c) {
							 | 
						||
| 
								 | 
							
								  return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isASCIIAlphanumeric(c) {
							 | 
						||
| 
								 | 
							
								  return isASCIIAlpha(c) || isASCIIDigit(c);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isASCIIHex(c) {
							 | 
						||
| 
								 | 
							
								  return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isSingleDot(buffer) {
							 | 
						||
| 
								 | 
							
								  return buffer === "." || buffer.toLowerCase() === "%2e";
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isDoubleDot(buffer) {
							 | 
						||
| 
								 | 
							
								  buffer = buffer.toLowerCase();
							 | 
						||
| 
								 | 
							
								  return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e";
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isWindowsDriveLetterCodePoints(cp1, cp2) {
							 | 
						||
| 
								 | 
							
								  return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isWindowsDriveLetterString(string) {
							 | 
						||
| 
								 | 
							
								  return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isNormalizedWindowsDriveLetterString(string) {
							 | 
						||
| 
								 | 
							
								  return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":";
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function containsForbiddenHostCodePoint(string) {
							 | 
						||
| 
								 | 
							
								  return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function containsForbiddenHostCodePointExcludingPercent(string) {
							 | 
						||
| 
								 | 
							
								  return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isSpecialScheme(scheme) {
							 | 
						||
| 
								 | 
							
								  return specialSchemes[scheme] !== undefined;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isSpecial(url) {
							 | 
						||
| 
								 | 
							
								  return isSpecialScheme(url.scheme);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function defaultPort(scheme) {
							 | 
						||
| 
								 | 
							
								  return specialSchemes[scheme];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function percentEncode(c) {
							 | 
						||
| 
								 | 
							
								  let hex = c.toString(16).toUpperCase();
							 | 
						||
| 
								 | 
							
								  if (hex.length === 1) {
							 | 
						||
| 
								 | 
							
								    hex = "0" + hex;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return "%" + hex;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function utf8PercentEncode(c) {
							 | 
						||
| 
								 | 
							
								  const buf = new Buffer(c);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let str = "";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (let i = 0; i < buf.length; ++i) {
							 | 
						||
| 
								 | 
							
								    str += percentEncode(buf[i]);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return str;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function utf8PercentDecode(str) {
							 | 
						||
| 
								 | 
							
								  const input = new Buffer(str);
							 | 
						||
| 
								 | 
							
								  const output = [];
							 | 
						||
| 
								 | 
							
								  for (let i = 0; i < input.length; ++i) {
							 | 
						||
| 
								 | 
							
								    if (input[i] !== 37) {
							 | 
						||
| 
								 | 
							
								      output.push(input[i]);
							 | 
						||
| 
								 | 
							
								    } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) {
							 | 
						||
| 
								 | 
							
								      output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16));
							 | 
						||
| 
								 | 
							
								      i += 2;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      output.push(input[i]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return new Buffer(output).toString();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isC0ControlPercentEncode(c) {
							 | 
						||
| 
								 | 
							
								  return c <= 0x1F || c > 0x7E;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]);
							 | 
						||
| 
								 | 
							
								function isPathPercentEncode(c) {
							 | 
						||
| 
								 | 
							
								  return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const extraUserinfoPercentEncodeSet =
							 | 
						||
| 
								 | 
							
								  new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]);
							 | 
						||
| 
								 | 
							
								function isUserinfoPercentEncode(c) {
							 | 
						||
| 
								 | 
							
								  return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function percentEncodeChar(c, encodeSetPredicate) {
							 | 
						||
| 
								 | 
							
								  const cStr = String.fromCodePoint(c);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (encodeSetPredicate(c)) {
							 | 
						||
| 
								 | 
							
								    return utf8PercentEncode(cStr);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return cStr;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function parseIPv4Number(input) {
							 | 
						||
| 
								 | 
							
								  let R = 10;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") {
							 | 
						||
| 
								 | 
							
								    input = input.substring(2);
							 | 
						||
| 
								 | 
							
								    R = 16;
							 | 
						||
| 
								 | 
							
								  } else if (input.length >= 2 && input.charAt(0) === "0") {
							 | 
						||
| 
								 | 
							
								    input = input.substring(1);
							 | 
						||
| 
								 | 
							
								    R = 8;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (input === "") {
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/);
							 | 
						||
| 
								 | 
							
								  if (regex.test(input)) {
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return parseInt(input, R);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function parseIPv4(input) {
							 | 
						||
| 
								 | 
							
								  const parts = input.split(".");
							 | 
						||
| 
								 | 
							
								  if (parts[parts.length - 1] === "") {
							 | 
						||
| 
								 | 
							
								    if (parts.length > 1) {
							 | 
						||
| 
								 | 
							
								      parts.pop();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (parts.length > 4) {
							 | 
						||
| 
								 | 
							
								    return input;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const numbers = [];
							 | 
						||
| 
								 | 
							
								  for (const part of parts) {
							 | 
						||
| 
								 | 
							
								    if (part === "") {
							 | 
						||
| 
								 | 
							
								      return input;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    const n = parseIPv4Number(part);
							 | 
						||
| 
								 | 
							
								    if (n === failure) {
							 | 
						||
| 
								 | 
							
								      return input;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    numbers.push(n);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (let i = 0; i < numbers.length - 1; ++i) {
							 | 
						||
| 
								 | 
							
								    if (numbers[i] > 255) {
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) {
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let ipv4 = numbers.pop();
							 | 
						||
| 
								 | 
							
								  let counter = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (const n of numbers) {
							 | 
						||
| 
								 | 
							
								    ipv4 += n * Math.pow(256, 3 - counter);
							 | 
						||
| 
								 | 
							
								    ++counter;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return ipv4;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function serializeIPv4(address) {
							 | 
						||
| 
								 | 
							
								  let output = "";
							 | 
						||
| 
								 | 
							
								  let n = address;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (let i = 1; i <= 4; ++i) {
							 | 
						||
| 
								 | 
							
								    output = String(n % 256) + output;
							 | 
						||
| 
								 | 
							
								    if (i !== 4) {
							 | 
						||
| 
								 | 
							
								      output = "." + output;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    n = Math.floor(n / 256);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return output;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function parseIPv6(input) {
							 | 
						||
| 
								 | 
							
								  const address = [0, 0, 0, 0, 0, 0, 0, 0];
							 | 
						||
| 
								 | 
							
								  let pieceIndex = 0;
							 | 
						||
| 
								 | 
							
								  let compress = null;
							 | 
						||
| 
								 | 
							
								  let pointer = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  input = punycode.ucs2.decode(input);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (input[pointer] === 58) {
							 | 
						||
| 
								 | 
							
								    if (input[pointer + 1] !== 58) {
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pointer += 2;
							 | 
						||
| 
								 | 
							
								    ++pieceIndex;
							 | 
						||
| 
								 | 
							
								    compress = pieceIndex;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while (pointer < input.length) {
							 | 
						||
| 
								 | 
							
								    if (pieceIndex === 8) {
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (input[pointer] === 58) {
							 | 
						||
| 
								 | 
							
								      if (compress !== null) {
							 | 
						||
| 
								 | 
							
								        return failure;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      ++pointer;
							 | 
						||
| 
								 | 
							
								      ++pieceIndex;
							 | 
						||
| 
								 | 
							
								      compress = pieceIndex;
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    let value = 0;
							 | 
						||
| 
								 | 
							
								    let length = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (length < 4 && isASCIIHex(input[pointer])) {
							 | 
						||
| 
								 | 
							
								      value = value * 0x10 + parseInt(at(input, pointer), 16);
							 | 
						||
| 
								 | 
							
								      ++pointer;
							 | 
						||
| 
								 | 
							
								      ++length;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (input[pointer] === 46) {
							 | 
						||
| 
								 | 
							
								      if (length === 0) {
							 | 
						||
| 
								 | 
							
								        return failure;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      pointer -= length;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (pieceIndex > 6) {
							 | 
						||
| 
								 | 
							
								        return failure;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      let numbersSeen = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (input[pointer] !== undefined) {
							 | 
						||
| 
								 | 
							
								        let ipv4Piece = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (numbersSeen > 0) {
							 | 
						||
| 
								 | 
							
								          if (input[pointer] === 46 && numbersSeen < 4) {
							 | 
						||
| 
								 | 
							
								            ++pointer;
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								            return failure;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!isASCIIDigit(input[pointer])) {
							 | 
						||
| 
								 | 
							
								          return failure;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (isASCIIDigit(input[pointer])) {
							 | 
						||
| 
								 | 
							
								          const number = parseInt(at(input, pointer));
							 | 
						||
| 
								 | 
							
								          if (ipv4Piece === null) {
							 | 
						||
| 
								 | 
							
								            ipv4Piece = number;
							 | 
						||
| 
								 | 
							
								          } else if (ipv4Piece === 0) {
							 | 
						||
| 
								 | 
							
								            return failure;
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								            ipv4Piece = ipv4Piece * 10 + number;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								          if (ipv4Piece > 255) {
							 | 
						||
| 
								 | 
							
								            return failure;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								          ++pointer;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ++numbersSeen;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (numbersSeen === 2 || numbersSeen === 4) {
							 | 
						||
| 
								 | 
							
								          ++pieceIndex;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (numbersSeen !== 4) {
							 | 
						||
| 
								 | 
							
								        return failure;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      break;
							 | 
						||
| 
								 | 
							
								    } else if (input[pointer] === 58) {
							 | 
						||
| 
								 | 
							
								      ++pointer;
							 | 
						||
| 
								 | 
							
								      if (input[pointer] === undefined) {
							 | 
						||
| 
								 | 
							
								        return failure;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    } else if (input[pointer] !== undefined) {
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    address[pieceIndex] = value;
							 | 
						||
| 
								 | 
							
								    ++pieceIndex;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (compress !== null) {
							 | 
						||
| 
								 | 
							
								    let swaps = pieceIndex - compress;
							 | 
						||
| 
								 | 
							
								    pieceIndex = 7;
							 | 
						||
| 
								 | 
							
								    while (pieceIndex !== 0 && swaps > 0) {
							 | 
						||
| 
								 | 
							
								      const temp = address[compress + swaps - 1];
							 | 
						||
| 
								 | 
							
								      address[compress + swaps - 1] = address[pieceIndex];
							 | 
						||
| 
								 | 
							
								      address[pieceIndex] = temp;
							 | 
						||
| 
								 | 
							
								      --pieceIndex;
							 | 
						||
| 
								 | 
							
								      --swaps;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else if (compress === null && pieceIndex !== 8) {
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return address;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function serializeIPv6(address) {
							 | 
						||
| 
								 | 
							
								  let output = "";
							 | 
						||
| 
								 | 
							
								  const seqResult = findLongestZeroSequence(address);
							 | 
						||
| 
								 | 
							
								  const compress = seqResult.idx;
							 | 
						||
| 
								 | 
							
								  let ignore0 = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) {
							 | 
						||
| 
								 | 
							
								    if (ignore0 && address[pieceIndex] === 0) {
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								    } else if (ignore0) {
							 | 
						||
| 
								 | 
							
								      ignore0 = false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (compress === pieceIndex) {
							 | 
						||
| 
								 | 
							
								      const separator = pieceIndex === 0 ? "::" : ":";
							 | 
						||
| 
								 | 
							
								      output += separator;
							 | 
						||
| 
								 | 
							
								      ignore0 = true;
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    output += address[pieceIndex].toString(16);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (pieceIndex !== 7) {
							 | 
						||
| 
								 | 
							
								      output += ":";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return output;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function parseHost(input, isSpecialArg) {
							 | 
						||
| 
								 | 
							
								  if (input[0] === "[") {
							 | 
						||
| 
								 | 
							
								    if (input[input.length - 1] !== "]") {
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return parseIPv6(input.substring(1, input.length - 1));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!isSpecialArg) {
							 | 
						||
| 
								 | 
							
								    return parseOpaqueHost(input);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const domain = utf8PercentDecode(input);
							 | 
						||
| 
								 | 
							
								  const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false);
							 | 
						||
| 
								 | 
							
								  if (asciiDomain === null) {
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (containsForbiddenHostCodePoint(asciiDomain)) {
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const ipv4Host = parseIPv4(asciiDomain);
							 | 
						||
| 
								 | 
							
								  if (typeof ipv4Host === "number" || ipv4Host === failure) {
							 | 
						||
| 
								 | 
							
								    return ipv4Host;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return asciiDomain;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function parseOpaqueHost(input) {
							 | 
						||
| 
								 | 
							
								  if (containsForbiddenHostCodePointExcludingPercent(input)) {
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let output = "";
							 | 
						||
| 
								 | 
							
								  const decoded = punycode.ucs2.decode(input);
							 | 
						||
| 
								 | 
							
								  for (let i = 0; i < decoded.length; ++i) {
							 | 
						||
| 
								 | 
							
								    output += percentEncodeChar(decoded[i], isC0ControlPercentEncode);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return output;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function findLongestZeroSequence(arr) {
							 | 
						||
| 
								 | 
							
								  let maxIdx = null;
							 | 
						||
| 
								 | 
							
								  let maxLen = 1; // only find elements > 1
							 | 
						||
| 
								 | 
							
								  let currStart = null;
							 | 
						||
| 
								 | 
							
								  let currLen = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (let i = 0; i < arr.length; ++i) {
							 | 
						||
| 
								 | 
							
								    if (arr[i] !== 0) {
							 | 
						||
| 
								 | 
							
								      if (currLen > maxLen) {
							 | 
						||
| 
								 | 
							
								        maxIdx = currStart;
							 | 
						||
| 
								 | 
							
								        maxLen = currLen;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      currStart = null;
							 | 
						||
| 
								 | 
							
								      currLen = 0;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      if (currStart === null) {
							 | 
						||
| 
								 | 
							
								        currStart = i;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      ++currLen;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // if trailing zeros
							 | 
						||
| 
								 | 
							
								  if (currLen > maxLen) {
							 | 
						||
| 
								 | 
							
								    maxIdx = currStart;
							 | 
						||
| 
								 | 
							
								    maxLen = currLen;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    idx: maxIdx,
							 | 
						||
| 
								 | 
							
								    len: maxLen
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function serializeHost(host) {
							 | 
						||
| 
								 | 
							
								  if (typeof host === "number") {
							 | 
						||
| 
								 | 
							
								    return serializeIPv4(host);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // IPv6 serializer
							 | 
						||
| 
								 | 
							
								  if (host instanceof Array) {
							 | 
						||
| 
								 | 
							
								    return "[" + serializeIPv6(host) + "]";
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return host;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function trimControlChars(url) {
							 | 
						||
| 
								 | 
							
								  return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, "");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function trimTabAndNewline(url) {
							 | 
						||
| 
								 | 
							
								  return url.replace(/\u0009|\u000A|\u000D/g, "");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function shortenPath(url) {
							 | 
						||
| 
								 | 
							
								  const path = url.path;
							 | 
						||
| 
								 | 
							
								  if (path.length === 0) {
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) {
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  path.pop();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function includesCredentials(url) {
							 | 
						||
| 
								 | 
							
								  return url.username !== "" || url.password !== "";
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function cannotHaveAUsernamePasswordPort(url) {
							 | 
						||
| 
								 | 
							
								  return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file";
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isNormalizedWindowsDriveLetter(string) {
							 | 
						||
| 
								 | 
							
								  return /^[A-Za-z]:$/.test(string);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function URLStateMachine(input, base, encodingOverride, url, stateOverride) {
							 | 
						||
| 
								 | 
							
								  this.pointer = 0;
							 | 
						||
| 
								 | 
							
								  this.input = input;
							 | 
						||
| 
								 | 
							
								  this.base = base || null;
							 | 
						||
| 
								 | 
							
								  this.encodingOverride = encodingOverride || "utf-8";
							 | 
						||
| 
								 | 
							
								  this.stateOverride = stateOverride;
							 | 
						||
| 
								 | 
							
								  this.url = url;
							 | 
						||
| 
								 | 
							
								  this.failure = false;
							 | 
						||
| 
								 | 
							
								  this.parseError = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!this.url) {
							 | 
						||
| 
								 | 
							
								    this.url = {
							 | 
						||
| 
								 | 
							
								      scheme: "",
							 | 
						||
| 
								 | 
							
								      username: "",
							 | 
						||
| 
								 | 
							
								      password: "",
							 | 
						||
| 
								 | 
							
								      host: null,
							 | 
						||
| 
								 | 
							
								      port: null,
							 | 
						||
| 
								 | 
							
								      path: [],
							 | 
						||
| 
								 | 
							
								      query: null,
							 | 
						||
| 
								 | 
							
								      fragment: null,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      cannotBeABaseURL: false
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const res = trimControlChars(this.input);
							 | 
						||
| 
								 | 
							
								    if (res !== this.input) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.input = res;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const res = trimTabAndNewline(this.input);
							 | 
						||
| 
								 | 
							
								  if (res !== this.input) {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  this.input = res;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.state = stateOverride || "scheme start";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.buffer = "";
							 | 
						||
| 
								 | 
							
								  this.atFlag = false;
							 | 
						||
| 
								 | 
							
								  this.arrFlag = false;
							 | 
						||
| 
								 | 
							
								  this.passwordTokenSeenFlag = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.input = punycode.ucs2.decode(this.input);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (; this.pointer <= this.input.length; ++this.pointer) {
							 | 
						||
| 
								 | 
							
								    const c = this.input[this.pointer];
							 | 
						||
| 
								 | 
							
								    const cStr = isNaN(c) ? undefined : String.fromCodePoint(c);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // exec state machine
							 | 
						||
| 
								 | 
							
								    const ret = this["parse " + this.state](c, cStr);
							 | 
						||
| 
								 | 
							
								    if (!ret) {
							 | 
						||
| 
								 | 
							
								      break; // terminate algorithm
							 | 
						||
| 
								 | 
							
								    } else if (ret === failure) {
							 | 
						||
| 
								 | 
							
								      this.failure = true;
							 | 
						||
| 
								 | 
							
								      break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) {
							 | 
						||
| 
								 | 
							
								  if (isASCIIAlpha(c)) {
							 | 
						||
| 
								 | 
							
								    this.buffer += cStr.toLowerCase();
							 | 
						||
| 
								 | 
							
								    this.state = "scheme";
							 | 
						||
| 
								 | 
							
								  } else if (!this.stateOverride) {
							 | 
						||
| 
								 | 
							
								    this.state = "no scheme";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) {
							 | 
						||
| 
								 | 
							
								  if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) {
							 | 
						||
| 
								 | 
							
								    this.buffer += cStr.toLowerCase();
							 | 
						||
| 
								 | 
							
								  } else if (c === 58) {
							 | 
						||
| 
								 | 
							
								    if (this.stateOverride) {
							 | 
						||
| 
								 | 
							
								      if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) {
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) {
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") {
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) {
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.url.scheme = this.buffer;
							 | 
						||
| 
								 | 
							
								    this.buffer = "";
							 | 
						||
| 
								 | 
							
								    if (this.stateOverride) {
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (this.url.scheme === "file") {
							 | 
						||
| 
								 | 
							
								      if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) {
							 | 
						||
| 
								 | 
							
								        this.parseError = true;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      this.state = "file";
							 | 
						||
| 
								 | 
							
								    } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) {
							 | 
						||
| 
								 | 
							
								      this.state = "special relative or authority";
							 | 
						||
| 
								 | 
							
								    } else if (isSpecial(this.url)) {
							 | 
						||
| 
								 | 
							
								      this.state = "special authority slashes";
							 | 
						||
| 
								 | 
							
								    } else if (this.input[this.pointer + 1] === 47) {
							 | 
						||
| 
								 | 
							
								      this.state = "path or authority";
							 | 
						||
| 
								 | 
							
								      ++this.pointer;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      this.url.cannotBeABaseURL = true;
							 | 
						||
| 
								 | 
							
								      this.url.path.push("");
							 | 
						||
| 
								 | 
							
								      this.state = "cannot-be-a-base-URL path";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else if (!this.stateOverride) {
							 | 
						||
| 
								 | 
							
								    this.buffer = "";
							 | 
						||
| 
								 | 
							
								    this.state = "no scheme";
							 | 
						||
| 
								 | 
							
								    this.pointer = -1;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) {
							 | 
						||
| 
								 | 
							
								  if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) {
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  } else if (this.base.cannotBeABaseURL && c === 35) {
							 | 
						||
| 
								 | 
							
								    this.url.scheme = this.base.scheme;
							 | 
						||
| 
								 | 
							
								    this.url.path = this.base.path.slice();
							 | 
						||
| 
								 | 
							
								    this.url.query = this.base.query;
							 | 
						||
| 
								 | 
							
								    this.url.fragment = "";
							 | 
						||
| 
								 | 
							
								    this.url.cannotBeABaseURL = true;
							 | 
						||
| 
								 | 
							
								    this.state = "fragment";
							 | 
						||
| 
								 | 
							
								  } else if (this.base.scheme === "file") {
							 | 
						||
| 
								 | 
							
								    this.state = "file";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.state = "relative";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) {
							 | 
						||
| 
								 | 
							
								  if (c === 47 && this.input[this.pointer + 1] === 47) {
							 | 
						||
| 
								 | 
							
								    this.state = "special authority ignore slashes";
							 | 
						||
| 
								 | 
							
								    ++this.pointer;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								    this.state = "relative";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) {
							 | 
						||
| 
								 | 
							
								  if (c === 47) {
							 | 
						||
| 
								 | 
							
								    this.state = "authority";
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.state = "path";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse relative"] = function parseRelative(c) {
							 | 
						||
| 
								 | 
							
								  this.url.scheme = this.base.scheme;
							 | 
						||
| 
								 | 
							
								  if (isNaN(c)) {
							 | 
						||
| 
								 | 
							
								    this.url.username = this.base.username;
							 | 
						||
| 
								 | 
							
								    this.url.password = this.base.password;
							 | 
						||
| 
								 | 
							
								    this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								    this.url.port = this.base.port;
							 | 
						||
| 
								 | 
							
								    this.url.path = this.base.path.slice();
							 | 
						||
| 
								 | 
							
								    this.url.query = this.base.query;
							 | 
						||
| 
								 | 
							
								  } else if (c === 47) {
							 | 
						||
| 
								 | 
							
								    this.state = "relative slash";
							 | 
						||
| 
								 | 
							
								  } else if (c === 63) {
							 | 
						||
| 
								 | 
							
								    this.url.username = this.base.username;
							 | 
						||
| 
								 | 
							
								    this.url.password = this.base.password;
							 | 
						||
| 
								 | 
							
								    this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								    this.url.port = this.base.port;
							 | 
						||
| 
								 | 
							
								    this.url.path = this.base.path.slice();
							 | 
						||
| 
								 | 
							
								    this.url.query = "";
							 | 
						||
| 
								 | 
							
								    this.state = "query";
							 | 
						||
| 
								 | 
							
								  } else if (c === 35) {
							 | 
						||
| 
								 | 
							
								    this.url.username = this.base.username;
							 | 
						||
| 
								 | 
							
								    this.url.password = this.base.password;
							 | 
						||
| 
								 | 
							
								    this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								    this.url.port = this.base.port;
							 | 
						||
| 
								 | 
							
								    this.url.path = this.base.path.slice();
							 | 
						||
| 
								 | 
							
								    this.url.query = this.base.query;
							 | 
						||
| 
								 | 
							
								    this.url.fragment = "";
							 | 
						||
| 
								 | 
							
								    this.state = "fragment";
							 | 
						||
| 
								 | 
							
								  } else if (isSpecial(this.url) && c === 92) {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								    this.state = "relative slash";
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.url.username = this.base.username;
							 | 
						||
| 
								 | 
							
								    this.url.password = this.base.password;
							 | 
						||
| 
								 | 
							
								    this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								    this.url.port = this.base.port;
							 | 
						||
| 
								 | 
							
								    this.url.path = this.base.path.slice(0, this.base.path.length - 1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.state = "path";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) {
							 | 
						||
| 
								 | 
							
								  if (isSpecial(this.url) && (c === 47 || c === 92)) {
							 | 
						||
| 
								 | 
							
								    if (c === 92) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.state = "special authority ignore slashes";
							 | 
						||
| 
								 | 
							
								  } else if (c === 47) {
							 | 
						||
| 
								 | 
							
								    this.state = "authority";
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.url.username = this.base.username;
							 | 
						||
| 
								 | 
							
								    this.url.password = this.base.password;
							 | 
						||
| 
								 | 
							
								    this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								    this.url.port = this.base.port;
							 | 
						||
| 
								 | 
							
								    this.state = "path";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) {
							 | 
						||
| 
								 | 
							
								  if (c === 47 && this.input[this.pointer + 1] === 47) {
							 | 
						||
| 
								 | 
							
								    this.state = "special authority ignore slashes";
							 | 
						||
| 
								 | 
							
								    ++this.pointer;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								    this.state = "special authority ignore slashes";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) {
							 | 
						||
| 
								 | 
							
								  if (c !== 47 && c !== 92) {
							 | 
						||
| 
								 | 
							
								    this.state = "authority";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) {
							 | 
						||
| 
								 | 
							
								  if (c === 64) {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								    if (this.atFlag) {
							 | 
						||
| 
								 | 
							
								      this.buffer = "%40" + this.buffer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.atFlag = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars
							 | 
						||
| 
								 | 
							
								    const len = countSymbols(this.buffer);
							 | 
						||
| 
								 | 
							
								    for (let pointer = 0; pointer < len; ++pointer) {
							 | 
						||
| 
								 | 
							
								      const codePoint = this.buffer.codePointAt(pointer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (codePoint === 58 && !this.passwordTokenSeenFlag) {
							 | 
						||
| 
								 | 
							
								        this.passwordTokenSeenFlag = true;
							 | 
						||
| 
								 | 
							
								        continue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode);
							 | 
						||
| 
								 | 
							
								      if (this.passwordTokenSeenFlag) {
							 | 
						||
| 
								 | 
							
								        this.url.password += encodedCodePoints;
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        this.url.username += encodedCodePoints;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.buffer = "";
							 | 
						||
| 
								 | 
							
								  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
							 | 
						||
| 
								 | 
							
								             (isSpecial(this.url) && c === 92)) {
							 | 
						||
| 
								 | 
							
								    if (this.atFlag && this.buffer === "") {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.pointer -= countSymbols(this.buffer) + 1;
							 | 
						||
| 
								 | 
							
								    this.buffer = "";
							 | 
						||
| 
								 | 
							
								    this.state = "host";
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.buffer += cStr;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse hostname"] =
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) {
							 | 
						||
| 
								 | 
							
								  if (this.stateOverride && this.url.scheme === "file") {
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								    this.state = "file host";
							 | 
						||
| 
								 | 
							
								  } else if (c === 58 && !this.arrFlag) {
							 | 
						||
| 
								 | 
							
								    if (this.buffer === "") {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const host = parseHost(this.buffer, isSpecial(this.url));
							 | 
						||
| 
								 | 
							
								    if (host === failure) {
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.url.host = host;
							 | 
						||
| 
								 | 
							
								    this.buffer = "";
							 | 
						||
| 
								 | 
							
								    this.state = "port";
							 | 
						||
| 
								 | 
							
								    if (this.stateOverride === "hostname") {
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
							 | 
						||
| 
								 | 
							
								             (isSpecial(this.url) && c === 92)) {
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								    if (isSpecial(this.url) && this.buffer === "") {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    } else if (this.stateOverride && this.buffer === "" &&
							 | 
						||
| 
								 | 
							
								               (includesCredentials(this.url) || this.url.port !== null)) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const host = parseHost(this.buffer, isSpecial(this.url));
							 | 
						||
| 
								 | 
							
								    if (host === failure) {
							 | 
						||
| 
								 | 
							
								      return failure;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.url.host = host;
							 | 
						||
| 
								 | 
							
								    this.buffer = "";
							 | 
						||
| 
								 | 
							
								    this.state = "path start";
							 | 
						||
| 
								 | 
							
								    if (this.stateOverride) {
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    if (c === 91) {
							 | 
						||
| 
								 | 
							
								      this.arrFlag = true;
							 | 
						||
| 
								 | 
							
								    } else if (c === 93) {
							 | 
						||
| 
								 | 
							
								      this.arrFlag = false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.buffer += cStr;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) {
							 | 
						||
| 
								 | 
							
								  if (isASCIIDigit(c)) {
							 | 
						||
| 
								 | 
							
								    this.buffer += cStr;
							 | 
						||
| 
								 | 
							
								  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||
							 | 
						||
| 
								 | 
							
								             (isSpecial(this.url) && c === 92) ||
							 | 
						||
| 
								 | 
							
								             this.stateOverride) {
							 | 
						||
| 
								 | 
							
								    if (this.buffer !== "") {
							 | 
						||
| 
								 | 
							
								      const port = parseInt(this.buffer);
							 | 
						||
| 
								 | 
							
								      if (port > Math.pow(2, 16) - 1) {
							 | 
						||
| 
								 | 
							
								        this.parseError = true;
							 | 
						||
| 
								 | 
							
								        return failure;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      this.url.port = port === defaultPort(this.url.scheme) ? null : port;
							 | 
						||
| 
								 | 
							
								      this.buffer = "";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (this.stateOverride) {
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.state = "path start";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								    return failure;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse file"] = function parseFile(c) {
							 | 
						||
| 
								 | 
							
								  this.url.scheme = "file";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (c === 47 || c === 92) {
							 | 
						||
| 
								 | 
							
								    if (c === 92) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.state = "file slash";
							 | 
						||
| 
								 | 
							
								  } else if (this.base !== null && this.base.scheme === "file") {
							 | 
						||
| 
								 | 
							
								    if (isNaN(c)) {
							 | 
						||
| 
								 | 
							
								      this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								      this.url.path = this.base.path.slice();
							 | 
						||
| 
								 | 
							
								      this.url.query = this.base.query;
							 | 
						||
| 
								 | 
							
								    } else if (c === 63) {
							 | 
						||
| 
								 | 
							
								      this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								      this.url.path = this.base.path.slice();
							 | 
						||
| 
								 | 
							
								      this.url.query = "";
							 | 
						||
| 
								 | 
							
								      this.state = "query";
							 | 
						||
| 
								 | 
							
								    } else if (c === 35) {
							 | 
						||
| 
								 | 
							
								      this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								      this.url.path = this.base.path.slice();
							 | 
						||
| 
								 | 
							
								      this.url.query = this.base.query;
							 | 
						||
| 
								 | 
							
								      this.url.fragment = "";
							 | 
						||
| 
								 | 
							
								      this.state = "fragment";
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points
							 | 
						||
| 
								 | 
							
								          !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) ||
							 | 
						||
| 
								 | 
							
								          (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points
							 | 
						||
| 
								 | 
							
								           !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) {
							 | 
						||
| 
								 | 
							
								        this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								        this.url.path = this.base.path.slice();
							 | 
						||
| 
								 | 
							
								        shortenPath(this.url);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        this.parseError = true;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      this.state = "path";
							 | 
						||
| 
								 | 
							
								      --this.pointer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.state = "path";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) {
							 | 
						||
| 
								 | 
							
								  if (c === 47 || c === 92) {
							 | 
						||
| 
								 | 
							
								    if (c === 92) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.state = "file host";
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    if (this.base !== null && this.base.scheme === "file") {
							 | 
						||
| 
								 | 
							
								      if (isNormalizedWindowsDriveLetterString(this.base.path[0])) {
							 | 
						||
| 
								 | 
							
								        this.url.path.push(this.base.path[0]);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        this.url.host = this.base.host;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.state = "path";
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) {
							 | 
						||
| 
								 | 
							
								  if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) {
							 | 
						||
| 
								 | 
							
								    --this.pointer;
							 | 
						||
| 
								 | 
							
								    if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								      this.state = "path";
							 | 
						||
| 
								 | 
							
								    } else if (this.buffer === "") {
							 | 
						||
| 
								 | 
							
								      this.url.host = "";
							 | 
						||
| 
								 | 
							
								      if (this.stateOverride) {
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      this.state = "path start";
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      let host = parseHost(this.buffer, isSpecial(this.url));
							 | 
						||
| 
								 | 
							
								      if (host === failure) {
							 | 
						||
| 
								 | 
							
								        return failure;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (host === "localhost") {
							 | 
						||
| 
								 | 
							
								        host = "";
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      this.url.host = host;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (this.stateOverride) {
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      this.buffer = "";
							 | 
						||
| 
								 | 
							
								      this.state = "path start";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.buffer += cStr;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse path start"] = function parsePathStart(c) {
							 | 
						||
| 
								 | 
							
								  if (isSpecial(this.url)) {
							 | 
						||
| 
								 | 
							
								    if (c === 92) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.state = "path";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (c !== 47 && c !== 92) {
							 | 
						||
| 
								 | 
							
								      --this.pointer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else if (!this.stateOverride && c === 63) {
							 | 
						||
| 
								 | 
							
								    this.url.query = "";
							 | 
						||
| 
								 | 
							
								    this.state = "query";
							 | 
						||
| 
								 | 
							
								  } else if (!this.stateOverride && c === 35) {
							 | 
						||
| 
								 | 
							
								    this.url.fragment = "";
							 | 
						||
| 
								 | 
							
								    this.state = "fragment";
							 | 
						||
| 
								 | 
							
								  } else if (c !== undefined) {
							 | 
						||
| 
								 | 
							
								    this.state = "path";
							 | 
						||
| 
								 | 
							
								    if (c !== 47) {
							 | 
						||
| 
								 | 
							
								      --this.pointer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse path"] = function parsePath(c) {
							 | 
						||
| 
								 | 
							
								  if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) ||
							 | 
						||
| 
								 | 
							
								      (!this.stateOverride && (c === 63 || c === 35))) {
							 | 
						||
| 
								 | 
							
								    if (isSpecial(this.url) && c === 92) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (isDoubleDot(this.buffer)) {
							 | 
						||
| 
								 | 
							
								      shortenPath(this.url);
							 | 
						||
| 
								 | 
							
								      if (c !== 47 && !(isSpecial(this.url) && c === 92)) {
							 | 
						||
| 
								 | 
							
								        this.url.path.push("");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    } else if (isSingleDot(this.buffer) && c !== 47 &&
							 | 
						||
| 
								 | 
							
								               !(isSpecial(this.url) && c === 92)) {
							 | 
						||
| 
								 | 
							
								      this.url.path.push("");
							 | 
						||
| 
								 | 
							
								    } else if (!isSingleDot(this.buffer)) {
							 | 
						||
| 
								 | 
							
								      if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) {
							 | 
						||
| 
								 | 
							
								        if (this.url.host !== "" && this.url.host !== null) {
							 | 
						||
| 
								 | 
							
								          this.parseError = true;
							 | 
						||
| 
								 | 
							
								          this.url.host = "";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        this.buffer = this.buffer[0] + ":";
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      this.url.path.push(this.buffer);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.buffer = "";
							 | 
						||
| 
								 | 
							
								    if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) {
							 | 
						||
| 
								 | 
							
								      while (this.url.path.length > 1 && this.url.path[0] === "") {
							 | 
						||
| 
								 | 
							
								        this.parseError = true;
							 | 
						||
| 
								 | 
							
								        this.url.path.shift();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (c === 63) {
							 | 
						||
| 
								 | 
							
								      this.url.query = "";
							 | 
						||
| 
								 | 
							
								      this.state = "query";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (c === 35) {
							 | 
						||
| 
								 | 
							
								      this.url.fragment = "";
							 | 
						||
| 
								 | 
							
								      this.state = "fragment";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    // TODO: If c is not a URL code point and not "%", parse error.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (c === 37 &&
							 | 
						||
| 
								 | 
							
								      (!isASCIIHex(this.input[this.pointer + 1]) ||
							 | 
						||
| 
								 | 
							
								        !isASCIIHex(this.input[this.pointer + 2]))) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.buffer += percentEncodeChar(c, isPathPercentEncode);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) {
							 | 
						||
| 
								 | 
							
								  if (c === 63) {
							 | 
						||
| 
								 | 
							
								    this.url.query = "";
							 | 
						||
| 
								 | 
							
								    this.state = "query";
							 | 
						||
| 
								 | 
							
								  } else if (c === 35) {
							 | 
						||
| 
								 | 
							
								    this.url.fragment = "";
							 | 
						||
| 
								 | 
							
								    this.state = "fragment";
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    // TODO: Add: not a URL code point
							 | 
						||
| 
								 | 
							
								    if (!isNaN(c) && c !== 37) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (c === 37 &&
							 | 
						||
| 
								 | 
							
								        (!isASCIIHex(this.input[this.pointer + 1]) ||
							 | 
						||
| 
								 | 
							
								         !isASCIIHex(this.input[this.pointer + 2]))) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!isNaN(c)) {
							 | 
						||
| 
								 | 
							
								      this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) {
							 | 
						||
| 
								 | 
							
								  if (isNaN(c) || (!this.stateOverride && c === 35)) {
							 | 
						||
| 
								 | 
							
								    if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") {
							 | 
						||
| 
								 | 
							
								      this.encodingOverride = "utf-8";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead
							 | 
						||
| 
								 | 
							
								    for (let i = 0; i < buffer.length; ++i) {
							 | 
						||
| 
								 | 
							
								      if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 ||
							 | 
						||
| 
								 | 
							
								          buffer[i] === 0x3C || buffer[i] === 0x3E) {
							 | 
						||
| 
								 | 
							
								        this.url.query += percentEncode(buffer[i]);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        this.url.query += String.fromCodePoint(buffer[i]);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.buffer = "";
							 | 
						||
| 
								 | 
							
								    if (c === 35) {
							 | 
						||
| 
								 | 
							
								      this.url.fragment = "";
							 | 
						||
| 
								 | 
							
								      this.state = "fragment";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    // TODO: If c is not a URL code point and not "%", parse error.
							 | 
						||
| 
								 | 
							
								    if (c === 37 &&
							 | 
						||
| 
								 | 
							
								      (!isASCIIHex(this.input[this.pointer + 1]) ||
							 | 
						||
| 
								 | 
							
								        !isASCIIHex(this.input[this.pointer + 2]))) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.buffer += cStr;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								URLStateMachine.prototype["parse fragment"] = function parseFragment(c) {
							 | 
						||
| 
								 | 
							
								  if (isNaN(c)) { // do nothing
							 | 
						||
| 
								 | 
							
								  } else if (c === 0x0) {
							 | 
						||
| 
								 | 
							
								    this.parseError = true;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    // TODO: If c is not a URL code point and not "%", parse error.
							 | 
						||
| 
								 | 
							
								    if (c === 37 &&
							 | 
						||
| 
								 | 
							
								      (!isASCIIHex(this.input[this.pointer + 1]) ||
							 | 
						||
| 
								 | 
							
								        !isASCIIHex(this.input[this.pointer + 2]))) {
							 | 
						||
| 
								 | 
							
								      this.parseError = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function serializeURL(url, excludeFragment) {
							 | 
						||
| 
								 | 
							
								  let output = url.scheme + ":";
							 | 
						||
| 
								 | 
							
								  if (url.host !== null) {
							 | 
						||
| 
								 | 
							
								    output += "//";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (url.username !== "" || url.password !== "") {
							 | 
						||
| 
								 | 
							
								      output += url.username;
							 | 
						||
| 
								 | 
							
								      if (url.password !== "") {
							 | 
						||
| 
								 | 
							
								        output += ":" + url.password;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      output += "@";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    output += serializeHost(url.host);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (url.port !== null) {
							 | 
						||
| 
								 | 
							
								      output += ":" + url.port;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else if (url.host === null && url.scheme === "file") {
							 | 
						||
| 
								 | 
							
								    output += "//";
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (url.cannotBeABaseURL) {
							 | 
						||
| 
								 | 
							
								    output += url.path[0];
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    for (const string of url.path) {
							 | 
						||
| 
								 | 
							
								      output += "/" + string;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (url.query !== null) {
							 | 
						||
| 
								 | 
							
								    output += "?" + url.query;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!excludeFragment && url.fragment !== null) {
							 | 
						||
| 
								 | 
							
								    output += "#" + url.fragment;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return output;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function serializeOrigin(tuple) {
							 | 
						||
| 
								 | 
							
								  let result = tuple.scheme + "://";
							 | 
						||
| 
								 | 
							
								  result += serializeHost(tuple.host);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (tuple.port !== null) {
							 | 
						||
| 
								 | 
							
								    result += ":" + tuple.port;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.serializeURL = serializeURL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.serializeURLOrigin = function (url) {
							 | 
						||
| 
								 | 
							
								  // https://url.spec.whatwg.org/#concept-url-origin
							 | 
						||
| 
								 | 
							
								  switch (url.scheme) {
							 | 
						||
| 
								 | 
							
								    case "blob":
							 | 
						||
| 
								 | 
							
								      try {
							 | 
						||
| 
								 | 
							
								        return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0]));
							 | 
						||
| 
								 | 
							
								      } catch (e) {
							 | 
						||
| 
								 | 
							
								        // serializing an opaque origin returns "null"
							 | 
						||
| 
								 | 
							
								        return "null";
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    case "ftp":
							 | 
						||
| 
								 | 
							
								    case "gopher":
							 | 
						||
| 
								 | 
							
								    case "http":
							 | 
						||
| 
								 | 
							
								    case "https":
							 | 
						||
| 
								 | 
							
								    case "ws":
							 | 
						||
| 
								 | 
							
								    case "wss":
							 | 
						||
| 
								 | 
							
								      return serializeOrigin({
							 | 
						||
| 
								 | 
							
								        scheme: url.scheme,
							 | 
						||
| 
								 | 
							
								        host: url.host,
							 | 
						||
| 
								 | 
							
								        port: url.port
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    case "file":
							 | 
						||
| 
								 | 
							
								      // spec says "exercise to the reader", chrome says "file://"
							 | 
						||
| 
								 | 
							
								      return "file://";
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								      // serializing an opaque origin returns "null"
							 | 
						||
| 
								 | 
							
								      return "null";
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.basicURLParse = function (input, options) {
							 | 
						||
| 
								 | 
							
								  if (options === undefined) {
							 | 
						||
| 
								 | 
							
								    options = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride);
							 | 
						||
| 
								 | 
							
								  if (usm.failure) {
							 | 
						||
| 
								 | 
							
								    return "failure";
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return usm.url;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.setTheUsername = function (url, username) {
							 | 
						||
| 
								 | 
							
								  url.username = "";
							 | 
						||
| 
								 | 
							
								  const decoded = punycode.ucs2.decode(username);
							 | 
						||
| 
								 | 
							
								  for (let i = 0; i < decoded.length; ++i) {
							 | 
						||
| 
								 | 
							
								    url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.setThePassword = function (url, password) {
							 | 
						||
| 
								 | 
							
								  url.password = "";
							 | 
						||
| 
								 | 
							
								  const decoded = punycode.ucs2.decode(password);
							 | 
						||
| 
								 | 
							
								  for (let i = 0; i < decoded.length; ++i) {
							 | 
						||
| 
								 | 
							
								    url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.serializeHost = serializeHost;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.serializeInteger = function (integer) {
							 | 
						||
| 
								 | 
							
								  return String(integer);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.parseURL = function (input, options) {
							 | 
						||
| 
								 | 
							
								  if (options === undefined) {
							 | 
						||
| 
								 | 
							
								    options = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // We don't handle blobs, so this just delegates:
							 | 
						||
| 
								 | 
							
								  return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride });
							 | 
						||
| 
								 | 
							
								};
							 |