11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst {
41cb0ef41Sopenharmony_ci  Array,
51cb0ef41Sopenharmony_ci  ArrayIsArray,
61cb0ef41Sopenharmony_ci  ArrayPrototypeJoin,
71cb0ef41Sopenharmony_ci  ArrayPrototypeMap,
81cb0ef41Sopenharmony_ci  ArrayPrototypePush,
91cb0ef41Sopenharmony_ci  ArrayPrototypeReduce,
101cb0ef41Sopenharmony_ci  ArrayPrototypeSlice,
111cb0ef41Sopenharmony_ci  Int8Array,
121cb0ef41Sopenharmony_ci  IteratorPrototype,
131cb0ef41Sopenharmony_ci  Number,
141cb0ef41Sopenharmony_ci  ObjectCreate,
151cb0ef41Sopenharmony_ci  ObjectDefineProperties,
161cb0ef41Sopenharmony_ci  ObjectDefineProperty,
171cb0ef41Sopenharmony_ci  ObjectGetOwnPropertySymbols,
181cb0ef41Sopenharmony_ci  ObjectGetPrototypeOf,
191cb0ef41Sopenharmony_ci  ObjectKeys,
201cb0ef41Sopenharmony_ci  ObjectPrototypeHasOwnProperty,
211cb0ef41Sopenharmony_ci  ReflectGetOwnPropertyDescriptor,
221cb0ef41Sopenharmony_ci  ReflectOwnKeys,
231cb0ef41Sopenharmony_ci  RegExpPrototypeSymbolReplace,
241cb0ef41Sopenharmony_ci  SafeMap,
251cb0ef41Sopenharmony_ci  SafeSet,
261cb0ef41Sopenharmony_ci  SafeWeakMap,
271cb0ef41Sopenharmony_ci  StringPrototypeCharAt,
281cb0ef41Sopenharmony_ci  StringPrototypeCharCodeAt,
291cb0ef41Sopenharmony_ci  StringPrototypeCodePointAt,
301cb0ef41Sopenharmony_ci  StringPrototypeIncludes,
311cb0ef41Sopenharmony_ci  StringPrototypeIndexOf,
321cb0ef41Sopenharmony_ci  StringPrototypeSlice,
331cb0ef41Sopenharmony_ci  StringPrototypeSplit,
341cb0ef41Sopenharmony_ci  StringPrototypeStartsWith,
351cb0ef41Sopenharmony_ci  Symbol,
361cb0ef41Sopenharmony_ci  SymbolIterator,
371cb0ef41Sopenharmony_ci  SymbolToStringTag,
381cb0ef41Sopenharmony_ci  decodeURIComponent,
391cb0ef41Sopenharmony_ci} = primordials;
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciconst { inspect } = require('internal/util/inspect');
421cb0ef41Sopenharmony_ciconst {
431cb0ef41Sopenharmony_ci  encodeStr,
441cb0ef41Sopenharmony_ci  hexTable,
451cb0ef41Sopenharmony_ci  isHexTable,
461cb0ef41Sopenharmony_ci} = require('internal/querystring');
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ciconst {
491cb0ef41Sopenharmony_ci  getConstructorOf,
501cb0ef41Sopenharmony_ci  removeColors,
511cb0ef41Sopenharmony_ci  toUSVString,
521cb0ef41Sopenharmony_ci  kEnumerableProperty,
531cb0ef41Sopenharmony_ci  SideEffectFreeRegExpPrototypeSymbolReplace,
541cb0ef41Sopenharmony_ci} = require('internal/util');
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ciconst {
571cb0ef41Sopenharmony_ci  codes: {
581cb0ef41Sopenharmony_ci    ERR_ARG_NOT_ITERABLE,
591cb0ef41Sopenharmony_ci    ERR_INVALID_ARG_TYPE,
601cb0ef41Sopenharmony_ci    ERR_INVALID_ARG_VALUE,
611cb0ef41Sopenharmony_ci    ERR_INVALID_FILE_URL_HOST,
621cb0ef41Sopenharmony_ci    ERR_INVALID_FILE_URL_PATH,
631cb0ef41Sopenharmony_ci    ERR_INVALID_THIS,
641cb0ef41Sopenharmony_ci    ERR_INVALID_TUPLE,
651cb0ef41Sopenharmony_ci    ERR_INVALID_URL,
661cb0ef41Sopenharmony_ci    ERR_INVALID_URL_SCHEME,
671cb0ef41Sopenharmony_ci    ERR_MISSING_ARGS,
681cb0ef41Sopenharmony_ci    ERR_NO_CRYPTO,
691cb0ef41Sopenharmony_ci  },
701cb0ef41Sopenharmony_ci} = require('internal/errors');
711cb0ef41Sopenharmony_ciconst {
721cb0ef41Sopenharmony_ci  CHAR_AMPERSAND,
731cb0ef41Sopenharmony_ci  CHAR_BACKWARD_SLASH,
741cb0ef41Sopenharmony_ci  CHAR_EQUAL,
751cb0ef41Sopenharmony_ci  CHAR_FORWARD_SLASH,
761cb0ef41Sopenharmony_ci  CHAR_LOWERCASE_A,
771cb0ef41Sopenharmony_ci  CHAR_LOWERCASE_Z,
781cb0ef41Sopenharmony_ci  CHAR_PERCENT,
791cb0ef41Sopenharmony_ci  CHAR_PLUS,
801cb0ef41Sopenharmony_ci} = require('internal/constants');
811cb0ef41Sopenharmony_ciconst path = require('path');
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ciconst {
841cb0ef41Sopenharmony_ci  validateFunction,
851cb0ef41Sopenharmony_ci} = require('internal/validators');
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ciconst querystring = require('querystring');
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ciconst { platform } = process;
901cb0ef41Sopenharmony_ciconst isWindows = platform === 'win32';
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ciconst bindingUrl = internalBinding('url');
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ciconst {
951cb0ef41Sopenharmony_ci  storeDataObject,
961cb0ef41Sopenharmony_ci  revokeDataObject,
971cb0ef41Sopenharmony_ci} = internalBinding('blob');
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ciconst FORWARD_SLASH = /\//g;
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ciconst context = Symbol('context');
1021cb0ef41Sopenharmony_ciconst searchParams = Symbol('query');
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci/**
1051cb0ef41Sopenharmony_ci * We cannot use private fields without a breaking change, so a WeakMap is the alternative.
1061cb0ef41Sopenharmony_ci * @type {WeakMap<URL,URLSearchParams>}
1071cb0ef41Sopenharmony_ci */
1081cb0ef41Sopenharmony_ciconst internalSearchParams = new SafeWeakMap();
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci// `unsafeProtocol`, `hostlessProtocol` and `slashedProtocol` is
1111cb0ef41Sopenharmony_ci// deliberately moved to `internal/url` rather than `url`.
1121cb0ef41Sopenharmony_ci// Workers does not bootstrap URL module. Therefore, `SafeSet`
1131cb0ef41Sopenharmony_ci// is not initialized on bootstrap. This case breaks the
1141cb0ef41Sopenharmony_ci// test-require-delete-array-iterator test.
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci// Protocols that can allow "unsafe" and "unwise" chars.
1171cb0ef41Sopenharmony_ciconst unsafeProtocol = new SafeSet([
1181cb0ef41Sopenharmony_ci  'javascript',
1191cb0ef41Sopenharmony_ci  'javascript:',
1201cb0ef41Sopenharmony_ci]);
1211cb0ef41Sopenharmony_ci// Protocols that never have a hostname.
1221cb0ef41Sopenharmony_ciconst hostlessProtocol = new SafeSet([
1231cb0ef41Sopenharmony_ci  'javascript',
1241cb0ef41Sopenharmony_ci  'javascript:',
1251cb0ef41Sopenharmony_ci]);
1261cb0ef41Sopenharmony_ci// Protocols that always contain a // bit.
1271cb0ef41Sopenharmony_ciconst slashedProtocol = new SafeSet([
1281cb0ef41Sopenharmony_ci  'http',
1291cb0ef41Sopenharmony_ci  'http:',
1301cb0ef41Sopenharmony_ci  'https',
1311cb0ef41Sopenharmony_ci  'https:',
1321cb0ef41Sopenharmony_ci  'ftp',
1331cb0ef41Sopenharmony_ci  'ftp:',
1341cb0ef41Sopenharmony_ci  'gopher',
1351cb0ef41Sopenharmony_ci  'gopher:',
1361cb0ef41Sopenharmony_ci  'file',
1371cb0ef41Sopenharmony_ci  'file:',
1381cb0ef41Sopenharmony_ci  'ws',
1391cb0ef41Sopenharmony_ci  'ws:',
1401cb0ef41Sopenharmony_ci  'wss',
1411cb0ef41Sopenharmony_ci  'wss:',
1421cb0ef41Sopenharmony_ci]);
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ciconst updateActions = {
1451cb0ef41Sopenharmony_ci  kProtocol: 0,
1461cb0ef41Sopenharmony_ci  kHost: 1,
1471cb0ef41Sopenharmony_ci  kHostname: 2,
1481cb0ef41Sopenharmony_ci  kPort: 3,
1491cb0ef41Sopenharmony_ci  kUsername: 4,
1501cb0ef41Sopenharmony_ci  kPassword: 5,
1511cb0ef41Sopenharmony_ci  kPathname: 6,
1521cb0ef41Sopenharmony_ci  kSearch: 7,
1531cb0ef41Sopenharmony_ci  kHash: 8,
1541cb0ef41Sopenharmony_ci  kHref: 9,
1551cb0ef41Sopenharmony_ci};
1561cb0ef41Sopenharmony_cilet blob;
1571cb0ef41Sopenharmony_cilet cryptoRandom;
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_cifunction lazyBlob() {
1601cb0ef41Sopenharmony_ci  blob ??= require('internal/blob');
1611cb0ef41Sopenharmony_ci  return blob;
1621cb0ef41Sopenharmony_ci}
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_cifunction lazyCryptoRandom() {
1651cb0ef41Sopenharmony_ci  try {
1661cb0ef41Sopenharmony_ci    cryptoRandom ??= require('internal/crypto/random');
1671cb0ef41Sopenharmony_ci  } catch {
1681cb0ef41Sopenharmony_ci    // If Node.js built without crypto support, we'll fall
1691cb0ef41Sopenharmony_ci    // through here and handle it later.
1701cb0ef41Sopenharmony_ci  }
1711cb0ef41Sopenharmony_ci  return cryptoRandom;
1721cb0ef41Sopenharmony_ci}
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci// This class provides the internal state of a URL object. An instance of this
1751cb0ef41Sopenharmony_ci// class is stored in every URL object and is accessed internally by setters
1761cb0ef41Sopenharmony_ci// and getters. It roughly corresponds to the concept of a URL record in the
1771cb0ef41Sopenharmony_ci// URL Standard, with a few differences. It is also the object transported to
1781cb0ef41Sopenharmony_ci// the C++ binding.
1791cb0ef41Sopenharmony_ci// Refs: https://url.spec.whatwg.org/#concept-url
1801cb0ef41Sopenharmony_ciclass URLContext {
1811cb0ef41Sopenharmony_ci  // This is the maximum value uint32_t can get.
1821cb0ef41Sopenharmony_ci  // Ada uses uint32_t(-1) for declaring omitted values.
1831cb0ef41Sopenharmony_ci  static #omitted = 4294967295;
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  href = '';
1861cb0ef41Sopenharmony_ci  protocol_end = 0;
1871cb0ef41Sopenharmony_ci  username_end = 0;
1881cb0ef41Sopenharmony_ci  host_start = 0;
1891cb0ef41Sopenharmony_ci  host_end = 0;
1901cb0ef41Sopenharmony_ci  pathname_start = 0;
1911cb0ef41Sopenharmony_ci  search_start = 0;
1921cb0ef41Sopenharmony_ci  hash_start = 0;
1931cb0ef41Sopenharmony_ci  port = 0;
1941cb0ef41Sopenharmony_ci  /**
1951cb0ef41Sopenharmony_ci   * Refers to `ada::scheme::type`
1961cb0ef41Sopenharmony_ci   *
1971cb0ef41Sopenharmony_ci   * enum type : uint8_t {
1981cb0ef41Sopenharmony_ci   *   HTTP = 0,
1991cb0ef41Sopenharmony_ci   *   NOT_SPECIAL = 1,
2001cb0ef41Sopenharmony_ci   *   HTTPS = 2,
2011cb0ef41Sopenharmony_ci   *   WS = 3,
2021cb0ef41Sopenharmony_ci   *   FTP = 4,
2031cb0ef41Sopenharmony_ci   *   WSS = 5,
2041cb0ef41Sopenharmony_ci   *   FILE = 6
2051cb0ef41Sopenharmony_ci   * };
2061cb0ef41Sopenharmony_ci   * @type {number}
2071cb0ef41Sopenharmony_ci   */
2081cb0ef41Sopenharmony_ci  scheme_type = 1;
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci  get hasPort() {
2111cb0ef41Sopenharmony_ci    return this.port !== URLContext.#omitted;
2121cb0ef41Sopenharmony_ci  }
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci  get hasSearch() {
2151cb0ef41Sopenharmony_ci    return this.search_start !== URLContext.#omitted;
2161cb0ef41Sopenharmony_ci  }
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci  get hasHash() {
2191cb0ef41Sopenharmony_ci    return this.hash_start !== URLContext.#omitted;
2201cb0ef41Sopenharmony_ci  }
2211cb0ef41Sopenharmony_ci}
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_cifunction isURLSearchParams(self) {
2241cb0ef41Sopenharmony_ci  return self?.[searchParams];
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ciclass URLSearchParams {
2281cb0ef41Sopenharmony_ci  [searchParams] = [];
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci  // "associated url object"
2311cb0ef41Sopenharmony_ci  [context] = null;
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ci  // URL Standard says the default value is '', but as undefined and '' have
2341cb0ef41Sopenharmony_ci  // the same result, undefined is used to prevent unnecessary parsing.
2351cb0ef41Sopenharmony_ci  // Default parameter is necessary to keep URLSearchParams.length === 0 in
2361cb0ef41Sopenharmony_ci  // accordance with Web IDL spec.
2371cb0ef41Sopenharmony_ci  constructor(init = undefined) {
2381cb0ef41Sopenharmony_ci    if (init == null) {
2391cb0ef41Sopenharmony_ci      // Do nothing
2401cb0ef41Sopenharmony_ci    } else if (typeof init === 'object' || typeof init === 'function') {
2411cb0ef41Sopenharmony_ci      const method = init[SymbolIterator];
2421cb0ef41Sopenharmony_ci      if (method === this[SymbolIterator]) {
2431cb0ef41Sopenharmony_ci        // While the spec does not have this branch, we can use it as a
2441cb0ef41Sopenharmony_ci        // shortcut to avoid having to go through the costly generic iterator.
2451cb0ef41Sopenharmony_ci        const childParams = init[searchParams];
2461cb0ef41Sopenharmony_ci        this[searchParams] = childParams.slice();
2471cb0ef41Sopenharmony_ci      } else if (method != null) {
2481cb0ef41Sopenharmony_ci        // Sequence<sequence<USVString>>
2491cb0ef41Sopenharmony_ci        if (typeof method !== 'function') {
2501cb0ef41Sopenharmony_ci          throw new ERR_ARG_NOT_ITERABLE('Query pairs');
2511cb0ef41Sopenharmony_ci        }
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ci        // The following implementationd differs from the URL specification:
2541cb0ef41Sopenharmony_ci        // Sequences must first be converted from ECMAScript objects before
2551cb0ef41Sopenharmony_ci        // and operations are done on them, and the operation of converting
2561cb0ef41Sopenharmony_ci        // the sequences would first exhaust the iterators. If the iterator
2571cb0ef41Sopenharmony_ci        // returns something invalid in the middle, whether it would be called
2581cb0ef41Sopenharmony_ci        // after that would be an observable change to the users.
2591cb0ef41Sopenharmony_ci        // Exhausting the iterator and later converting them to USVString comes
2601cb0ef41Sopenharmony_ci        // with a significant cost (~40-80%). In order optimize URLSearchParams
2611cb0ef41Sopenharmony_ci        // creation duration, Node.js merges the iteration and converting
2621cb0ef41Sopenharmony_ci        // iterations into a single iteration.
2631cb0ef41Sopenharmony_ci        for (const pair of init) {
2641cb0ef41Sopenharmony_ci          if (pair == null) {
2651cb0ef41Sopenharmony_ci            throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]');
2661cb0ef41Sopenharmony_ci          } else if (ArrayIsArray(pair)) {
2671cb0ef41Sopenharmony_ci            // If innerSequence's size is not 2, then throw a TypeError.
2681cb0ef41Sopenharmony_ci            if (pair.length !== 2) {
2691cb0ef41Sopenharmony_ci              throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]');
2701cb0ef41Sopenharmony_ci            }
2711cb0ef41Sopenharmony_ci            // Append (innerSequence[0], innerSequence[1]) to querys list.
2721cb0ef41Sopenharmony_ci            ArrayPrototypePush(this[searchParams], toUSVString(pair[0]), toUSVString(pair[1]));
2731cb0ef41Sopenharmony_ci          } else {
2741cb0ef41Sopenharmony_ci            if (((typeof pair !== 'object' && typeof pair !== 'function') ||
2751cb0ef41Sopenharmony_ci                typeof pair[SymbolIterator] !== 'function')) {
2761cb0ef41Sopenharmony_ci              throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]');
2771cb0ef41Sopenharmony_ci            }
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci            let length = 0;
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci            for (const element of pair) {
2821cb0ef41Sopenharmony_ci              length++;
2831cb0ef41Sopenharmony_ci              ArrayPrototypePush(this[searchParams], toUSVString(element));
2841cb0ef41Sopenharmony_ci            }
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci            // If innerSequence's size is not 2, then throw a TypeError.
2871cb0ef41Sopenharmony_ci            if (length !== 2) {
2881cb0ef41Sopenharmony_ci              throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]');
2891cb0ef41Sopenharmony_ci            }
2901cb0ef41Sopenharmony_ci          }
2911cb0ef41Sopenharmony_ci        }
2921cb0ef41Sopenharmony_ci      } else {
2931cb0ef41Sopenharmony_ci        // Record<USVString, USVString>
2941cb0ef41Sopenharmony_ci        // Need to use reflection APIs for full spec compliance.
2951cb0ef41Sopenharmony_ci        const visited = new SafeMap();
2961cb0ef41Sopenharmony_ci        const keys = ReflectOwnKeys(init);
2971cb0ef41Sopenharmony_ci        for (let i = 0; i < keys.length; i++) {
2981cb0ef41Sopenharmony_ci          const key = keys[i];
2991cb0ef41Sopenharmony_ci          const desc = ReflectGetOwnPropertyDescriptor(init, key);
3001cb0ef41Sopenharmony_ci          if (desc !== undefined && desc.enumerable) {
3011cb0ef41Sopenharmony_ci            const typedKey = toUSVString(key);
3021cb0ef41Sopenharmony_ci            const typedValue = toUSVString(init[key]);
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci            // Two different keys may become the same USVString after normalization.
3051cb0ef41Sopenharmony_ci            // In that case, we retain the later one. Refer to WPT.
3061cb0ef41Sopenharmony_ci            const keyIdx = visited.get(typedKey);
3071cb0ef41Sopenharmony_ci            if (keyIdx !== undefined) {
3081cb0ef41Sopenharmony_ci              this[searchParams][keyIdx] = typedValue;
3091cb0ef41Sopenharmony_ci            } else {
3101cb0ef41Sopenharmony_ci              visited.set(typedKey, ArrayPrototypePush(this[searchParams],
3111cb0ef41Sopenharmony_ci                                                       typedKey,
3121cb0ef41Sopenharmony_ci                                                       typedValue) - 1);
3131cb0ef41Sopenharmony_ci            }
3141cb0ef41Sopenharmony_ci          }
3151cb0ef41Sopenharmony_ci        }
3161cb0ef41Sopenharmony_ci      }
3171cb0ef41Sopenharmony_ci    } else {
3181cb0ef41Sopenharmony_ci      // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams
3191cb0ef41Sopenharmony_ci      init = toUSVString(init);
3201cb0ef41Sopenharmony_ci      this[searchParams] = init ? parseParams(init) : [];
3211cb0ef41Sopenharmony_ci    }
3221cb0ef41Sopenharmony_ci  }
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci  [inspect.custom](recurseTimes, ctx) {
3251cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
3261cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci    if (typeof recurseTimes === 'number' && recurseTimes < 0)
3291cb0ef41Sopenharmony_ci      return ctx.stylize('[Object]', 'special');
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ci    const separator = ', ';
3321cb0ef41Sopenharmony_ci    const innerOpts = { ...ctx };
3331cb0ef41Sopenharmony_ci    if (recurseTimes !== null) {
3341cb0ef41Sopenharmony_ci      innerOpts.depth = recurseTimes - 1;
3351cb0ef41Sopenharmony_ci    }
3361cb0ef41Sopenharmony_ci    const innerInspect = (v) => inspect(v, innerOpts);
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci    const list = this[searchParams];
3391cb0ef41Sopenharmony_ci    const output = [];
3401cb0ef41Sopenharmony_ci    for (let i = 0; i < list.length; i += 2)
3411cb0ef41Sopenharmony_ci      ArrayPrototypePush(
3421cb0ef41Sopenharmony_ci        output,
3431cb0ef41Sopenharmony_ci        `${innerInspect(list[i])} => ${innerInspect(list[i + 1])}`);
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci    const length = ArrayPrototypeReduce(
3461cb0ef41Sopenharmony_ci      output,
3471cb0ef41Sopenharmony_ci      (prev, cur) => prev + removeColors(cur).length + separator.length,
3481cb0ef41Sopenharmony_ci      -separator.length,
3491cb0ef41Sopenharmony_ci    );
3501cb0ef41Sopenharmony_ci    if (length > ctx.breakLength) {
3511cb0ef41Sopenharmony_ci      return `${this.constructor.name} {\n` +
3521cb0ef41Sopenharmony_ci      `  ${ArrayPrototypeJoin(output, ',\n  ')} }`;
3531cb0ef41Sopenharmony_ci    } else if (output.length) {
3541cb0ef41Sopenharmony_ci      return `${this.constructor.name} { ` +
3551cb0ef41Sopenharmony_ci      `${ArrayPrototypeJoin(output, separator)} }`;
3561cb0ef41Sopenharmony_ci    }
3571cb0ef41Sopenharmony_ci    return `${this.constructor.name} {}`;
3581cb0ef41Sopenharmony_ci  }
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci  get size() {
3611cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
3621cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
3631cb0ef41Sopenharmony_ci    return this[searchParams].length / 2;
3641cb0ef41Sopenharmony_ci  }
3651cb0ef41Sopenharmony_ci
3661cb0ef41Sopenharmony_ci  append(name, value) {
3671cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
3681cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_ci    if (arguments.length < 2) {
3711cb0ef41Sopenharmony_ci      throw new ERR_MISSING_ARGS('name', 'value');
3721cb0ef41Sopenharmony_ci    }
3731cb0ef41Sopenharmony_ci
3741cb0ef41Sopenharmony_ci    name = toUSVString(name);
3751cb0ef41Sopenharmony_ci    value = toUSVString(value);
3761cb0ef41Sopenharmony_ci    ArrayPrototypePush(this[searchParams], name, value);
3771cb0ef41Sopenharmony_ci    if (this[context]) {
3781cb0ef41Sopenharmony_ci      this[context].search = this.toString();
3791cb0ef41Sopenharmony_ci    }
3801cb0ef41Sopenharmony_ci  }
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci  delete(name, value = undefined) {
3831cb0ef41Sopenharmony_ci    if (typeof this !== 'object' || this === null || !isURLSearchParams(this))
3841cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ci    if (arguments.length < 1) {
3871cb0ef41Sopenharmony_ci      throw new ERR_MISSING_ARGS('name');
3881cb0ef41Sopenharmony_ci    }
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci    const list = this[searchParams];
3911cb0ef41Sopenharmony_ci    name = toUSVString(name);
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ci    if (value !== undefined) {
3941cb0ef41Sopenharmony_ci      value = toUSVString(value);
3951cb0ef41Sopenharmony_ci      for (let i = 0; i < list.length;) {
3961cb0ef41Sopenharmony_ci        if (list[i] === name && list[i + 1] === value) {
3971cb0ef41Sopenharmony_ci          list.splice(i, 2);
3981cb0ef41Sopenharmony_ci        } else {
3991cb0ef41Sopenharmony_ci          i += 2;
4001cb0ef41Sopenharmony_ci        }
4011cb0ef41Sopenharmony_ci      }
4021cb0ef41Sopenharmony_ci    } else {
4031cb0ef41Sopenharmony_ci      for (let i = 0; i < list.length;) {
4041cb0ef41Sopenharmony_ci        if (list[i] === name) {
4051cb0ef41Sopenharmony_ci          list.splice(i, 2);
4061cb0ef41Sopenharmony_ci        } else {
4071cb0ef41Sopenharmony_ci          i += 2;
4081cb0ef41Sopenharmony_ci        }
4091cb0ef41Sopenharmony_ci      }
4101cb0ef41Sopenharmony_ci    }
4111cb0ef41Sopenharmony_ci    if (this[context]) {
4121cb0ef41Sopenharmony_ci      this[context].search = this.toString();
4131cb0ef41Sopenharmony_ci    }
4141cb0ef41Sopenharmony_ci  }
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_ci  get(name) {
4171cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
4181cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
4191cb0ef41Sopenharmony_ci
4201cb0ef41Sopenharmony_ci    if (arguments.length < 1) {
4211cb0ef41Sopenharmony_ci      throw new ERR_MISSING_ARGS('name');
4221cb0ef41Sopenharmony_ci    }
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci    const list = this[searchParams];
4251cb0ef41Sopenharmony_ci    name = toUSVString(name);
4261cb0ef41Sopenharmony_ci    for (let i = 0; i < list.length; i += 2) {
4271cb0ef41Sopenharmony_ci      if (list[i] === name) {
4281cb0ef41Sopenharmony_ci        return list[i + 1];
4291cb0ef41Sopenharmony_ci      }
4301cb0ef41Sopenharmony_ci    }
4311cb0ef41Sopenharmony_ci    return null;
4321cb0ef41Sopenharmony_ci  }
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci  getAll(name) {
4351cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
4361cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
4371cb0ef41Sopenharmony_ci
4381cb0ef41Sopenharmony_ci    if (arguments.length < 1) {
4391cb0ef41Sopenharmony_ci      throw new ERR_MISSING_ARGS('name');
4401cb0ef41Sopenharmony_ci    }
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci    const list = this[searchParams];
4431cb0ef41Sopenharmony_ci    const values = [];
4441cb0ef41Sopenharmony_ci    name = toUSVString(name);
4451cb0ef41Sopenharmony_ci    for (let i = 0; i < list.length; i += 2) {
4461cb0ef41Sopenharmony_ci      if (list[i] === name) {
4471cb0ef41Sopenharmony_ci        values.push(list[i + 1]);
4481cb0ef41Sopenharmony_ci      }
4491cb0ef41Sopenharmony_ci    }
4501cb0ef41Sopenharmony_ci    return values;
4511cb0ef41Sopenharmony_ci  }
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_ci  has(name, value = undefined) {
4541cb0ef41Sopenharmony_ci    if (typeof this !== 'object' || this === null || !isURLSearchParams(this))
4551cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci    if (arguments.length < 1) {
4581cb0ef41Sopenharmony_ci      throw new ERR_MISSING_ARGS('name');
4591cb0ef41Sopenharmony_ci    }
4601cb0ef41Sopenharmony_ci
4611cb0ef41Sopenharmony_ci    const list = this[searchParams];
4621cb0ef41Sopenharmony_ci    name = toUSVString(name);
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_ci    if (value !== undefined) {
4651cb0ef41Sopenharmony_ci      value = toUSVString(value);
4661cb0ef41Sopenharmony_ci    }
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_ci    for (let i = 0; i < list.length; i += 2) {
4691cb0ef41Sopenharmony_ci      if (list[i] === name) {
4701cb0ef41Sopenharmony_ci        if (value === undefined || list[i + 1] === value) {
4711cb0ef41Sopenharmony_ci          return true;
4721cb0ef41Sopenharmony_ci        }
4731cb0ef41Sopenharmony_ci      }
4741cb0ef41Sopenharmony_ci    }
4751cb0ef41Sopenharmony_ci
4761cb0ef41Sopenharmony_ci    return false;
4771cb0ef41Sopenharmony_ci  }
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_ci  set(name, value) {
4801cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
4811cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci    if (arguments.length < 2) {
4841cb0ef41Sopenharmony_ci      throw new ERR_MISSING_ARGS('name', 'value');
4851cb0ef41Sopenharmony_ci    }
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_ci    const list = this[searchParams];
4881cb0ef41Sopenharmony_ci    name = toUSVString(name);
4891cb0ef41Sopenharmony_ci    value = toUSVString(value);
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci    // If there are any name-value pairs whose name is `name`, in `list`, set
4921cb0ef41Sopenharmony_ci    // the value of the first such name-value pair to `value` and remove the
4931cb0ef41Sopenharmony_ci    // others.
4941cb0ef41Sopenharmony_ci    let found = false;
4951cb0ef41Sopenharmony_ci    for (let i = 0; i < list.length;) {
4961cb0ef41Sopenharmony_ci      const cur = list[i];
4971cb0ef41Sopenharmony_ci      if (cur === name) {
4981cb0ef41Sopenharmony_ci        if (!found) {
4991cb0ef41Sopenharmony_ci          list[i + 1] = value;
5001cb0ef41Sopenharmony_ci          found = true;
5011cb0ef41Sopenharmony_ci          i += 2;
5021cb0ef41Sopenharmony_ci        } else {
5031cb0ef41Sopenharmony_ci          list.splice(i, 2);
5041cb0ef41Sopenharmony_ci        }
5051cb0ef41Sopenharmony_ci      } else {
5061cb0ef41Sopenharmony_ci        i += 2;
5071cb0ef41Sopenharmony_ci      }
5081cb0ef41Sopenharmony_ci    }
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ci    // Otherwise, append a new name-value pair whose name is `name` and value
5111cb0ef41Sopenharmony_ci    // is `value`, to `list`.
5121cb0ef41Sopenharmony_ci    if (!found) {
5131cb0ef41Sopenharmony_ci      ArrayPrototypePush(list, name, value);
5141cb0ef41Sopenharmony_ci    }
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci    if (this[context]) {
5171cb0ef41Sopenharmony_ci      this[context].search = this.toString();
5181cb0ef41Sopenharmony_ci    }
5191cb0ef41Sopenharmony_ci  }
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ci  sort() {
5221cb0ef41Sopenharmony_ci    const a = this[searchParams];
5231cb0ef41Sopenharmony_ci    const len = a.length;
5241cb0ef41Sopenharmony_ci
5251cb0ef41Sopenharmony_ci    if (len <= 2) {
5261cb0ef41Sopenharmony_ci      // Nothing needs to be done.
5271cb0ef41Sopenharmony_ci    } else if (len < 100) {
5281cb0ef41Sopenharmony_ci      // 100 is found through testing.
5291cb0ef41Sopenharmony_ci      // Simple stable in-place insertion sort
5301cb0ef41Sopenharmony_ci      // Derived from v8/src/js/array.js
5311cb0ef41Sopenharmony_ci      for (let i = 2; i < len; i += 2) {
5321cb0ef41Sopenharmony_ci        const curKey = a[i];
5331cb0ef41Sopenharmony_ci        const curVal = a[i + 1];
5341cb0ef41Sopenharmony_ci        let j;
5351cb0ef41Sopenharmony_ci        for (j = i - 2; j >= 0; j -= 2) {
5361cb0ef41Sopenharmony_ci          if (a[j] > curKey) {
5371cb0ef41Sopenharmony_ci            a[j + 2] = a[j];
5381cb0ef41Sopenharmony_ci            a[j + 3] = a[j + 1];
5391cb0ef41Sopenharmony_ci          } else {
5401cb0ef41Sopenharmony_ci            break;
5411cb0ef41Sopenharmony_ci          }
5421cb0ef41Sopenharmony_ci        }
5431cb0ef41Sopenharmony_ci        a[j + 2] = curKey;
5441cb0ef41Sopenharmony_ci        a[j + 3] = curVal;
5451cb0ef41Sopenharmony_ci      }
5461cb0ef41Sopenharmony_ci    } else {
5471cb0ef41Sopenharmony_ci      // Bottom-up iterative stable merge sort
5481cb0ef41Sopenharmony_ci      const lBuffer = new Array(len);
5491cb0ef41Sopenharmony_ci      const rBuffer = new Array(len);
5501cb0ef41Sopenharmony_ci      for (let step = 2; step < len; step *= 2) {
5511cb0ef41Sopenharmony_ci        for (let start = 0; start < len - 2; start += 2 * step) {
5521cb0ef41Sopenharmony_ci          const mid = start + step;
5531cb0ef41Sopenharmony_ci          let end = mid + step;
5541cb0ef41Sopenharmony_ci          end = end < len ? end : len;
5551cb0ef41Sopenharmony_ci          if (mid > end)
5561cb0ef41Sopenharmony_ci            continue;
5571cb0ef41Sopenharmony_ci          merge(a, start, mid, end, lBuffer, rBuffer);
5581cb0ef41Sopenharmony_ci        }
5591cb0ef41Sopenharmony_ci      }
5601cb0ef41Sopenharmony_ci    }
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci    if (this[context]) {
5631cb0ef41Sopenharmony_ci      this[context].search = this.toString();
5641cb0ef41Sopenharmony_ci    }
5651cb0ef41Sopenharmony_ci  }
5661cb0ef41Sopenharmony_ci
5671cb0ef41Sopenharmony_ci  // https://heycam.github.io/webidl/#es-iterators
5681cb0ef41Sopenharmony_ci  // Define entries here rather than [Symbol.iterator] as the function name
5691cb0ef41Sopenharmony_ci  // must be set to `entries`.
5701cb0ef41Sopenharmony_ci  entries() {
5711cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
5721cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci    return createSearchParamsIterator(this, 'key+value');
5751cb0ef41Sopenharmony_ci  }
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci  forEach(callback, thisArg = undefined) {
5781cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
5791cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ci    validateFunction(callback, 'callback');
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci    let list = this[searchParams];
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_ci    let i = 0;
5861cb0ef41Sopenharmony_ci    while (i < list.length) {
5871cb0ef41Sopenharmony_ci      const key = list[i];
5881cb0ef41Sopenharmony_ci      const value = list[i + 1];
5891cb0ef41Sopenharmony_ci      callback.call(thisArg, value, key, this);
5901cb0ef41Sopenharmony_ci      // In case the URL object's `search` is updated
5911cb0ef41Sopenharmony_ci      list = this[searchParams];
5921cb0ef41Sopenharmony_ci      i += 2;
5931cb0ef41Sopenharmony_ci    }
5941cb0ef41Sopenharmony_ci  }
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci  // https://heycam.github.io/webidl/#es-iterable
5971cb0ef41Sopenharmony_ci  keys() {
5981cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
5991cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
6001cb0ef41Sopenharmony_ci
6011cb0ef41Sopenharmony_ci    return createSearchParamsIterator(this, 'key');
6021cb0ef41Sopenharmony_ci  }
6031cb0ef41Sopenharmony_ci
6041cb0ef41Sopenharmony_ci  values() {
6051cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
6061cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
6071cb0ef41Sopenharmony_ci
6081cb0ef41Sopenharmony_ci    return createSearchParamsIterator(this, 'value');
6091cb0ef41Sopenharmony_ci  }
6101cb0ef41Sopenharmony_ci
6111cb0ef41Sopenharmony_ci  // https://heycam.github.io/webidl/#es-stringifier
6121cb0ef41Sopenharmony_ci  // https://url.spec.whatwg.org/#urlsearchparams-stringification-behavior
6131cb0ef41Sopenharmony_ci  toString() {
6141cb0ef41Sopenharmony_ci    if (!isURLSearchParams(this))
6151cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParams');
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci    return serializeParams(this[searchParams]);
6181cb0ef41Sopenharmony_ci  }
6191cb0ef41Sopenharmony_ci}
6201cb0ef41Sopenharmony_ci
6211cb0ef41Sopenharmony_ciObjectDefineProperties(URLSearchParams.prototype, {
6221cb0ef41Sopenharmony_ci  append: kEnumerableProperty,
6231cb0ef41Sopenharmony_ci  delete: kEnumerableProperty,
6241cb0ef41Sopenharmony_ci  get: kEnumerableProperty,
6251cb0ef41Sopenharmony_ci  getAll: kEnumerableProperty,
6261cb0ef41Sopenharmony_ci  has: kEnumerableProperty,
6271cb0ef41Sopenharmony_ci  set: kEnumerableProperty,
6281cb0ef41Sopenharmony_ci  size: kEnumerableProperty,
6291cb0ef41Sopenharmony_ci  sort: kEnumerableProperty,
6301cb0ef41Sopenharmony_ci  entries: kEnumerableProperty,
6311cb0ef41Sopenharmony_ci  forEach: kEnumerableProperty,
6321cb0ef41Sopenharmony_ci  keys: kEnumerableProperty,
6331cb0ef41Sopenharmony_ci  values: kEnumerableProperty,
6341cb0ef41Sopenharmony_ci  toString: kEnumerableProperty,
6351cb0ef41Sopenharmony_ci  [SymbolToStringTag]: { __proto__: null, configurable: true, value: 'URLSearchParams' },
6361cb0ef41Sopenharmony_ci
6371cb0ef41Sopenharmony_ci  // https://heycam.github.io/webidl/#es-iterable-entries
6381cb0ef41Sopenharmony_ci  [SymbolIterator]: {
6391cb0ef41Sopenharmony_ci    __proto__: null,
6401cb0ef41Sopenharmony_ci    configurable: true,
6411cb0ef41Sopenharmony_ci    writable: true,
6421cb0ef41Sopenharmony_ci    value: URLSearchParams.prototype.entries,
6431cb0ef41Sopenharmony_ci  },
6441cb0ef41Sopenharmony_ci});
6451cb0ef41Sopenharmony_ci
6461cb0ef41Sopenharmony_ci/**
6471cb0ef41Sopenharmony_ci * Checks if a value has the shape of a WHATWG URL object.
6481cb0ef41Sopenharmony_ci *
6491cb0ef41Sopenharmony_ci * Using a symbol or instanceof would not be able to recognize URL objects
6501cb0ef41Sopenharmony_ci * coming from other implementations (e.g. in Electron), so instead we are
6511cb0ef41Sopenharmony_ci * checking some well known properties for a lack of a better test.
6521cb0ef41Sopenharmony_ci * @param {*} self
6531cb0ef41Sopenharmony_ci * @returns {self is URL}
6541cb0ef41Sopenharmony_ci */
6551cb0ef41Sopenharmony_cifunction isURL(self) {
6561cb0ef41Sopenharmony_ci  return self != null && ObjectPrototypeHasOwnProperty(self, context);
6571cb0ef41Sopenharmony_ci}
6581cb0ef41Sopenharmony_ci
6591cb0ef41Sopenharmony_ciclass URL {
6601cb0ef41Sopenharmony_ci  constructor(input, base = undefined) {
6611cb0ef41Sopenharmony_ci    if (arguments.length === 0) {
6621cb0ef41Sopenharmony_ci      throw new ERR_MISSING_ARGS('url');
6631cb0ef41Sopenharmony_ci    }
6641cb0ef41Sopenharmony_ci
6651cb0ef41Sopenharmony_ci    // toUSVString is not needed.
6661cb0ef41Sopenharmony_ci    input = `${input}`;
6671cb0ef41Sopenharmony_ci    this[context] = new URLContext();
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci    if (base !== undefined) {
6701cb0ef41Sopenharmony_ci      base = `${base}`;
6711cb0ef41Sopenharmony_ci    }
6721cb0ef41Sopenharmony_ci
6731cb0ef41Sopenharmony_ci    const href = bindingUrl.parse(input, base);
6741cb0ef41Sopenharmony_ci
6751cb0ef41Sopenharmony_ci    if (!href) {
6761cb0ef41Sopenharmony_ci      throw new ERR_INVALID_URL(input);
6771cb0ef41Sopenharmony_ci    }
6781cb0ef41Sopenharmony_ci
6791cb0ef41Sopenharmony_ci    this.#updateContext(href);
6801cb0ef41Sopenharmony_ci  }
6811cb0ef41Sopenharmony_ci
6821cb0ef41Sopenharmony_ci  [inspect.custom](depth, opts) {
6831cb0ef41Sopenharmony_ci    if (this == null ||
6841cb0ef41Sopenharmony_ci        ObjectGetPrototypeOf(this[context]) !== URLContext.prototype) {
6851cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
6861cb0ef41Sopenharmony_ci    }
6871cb0ef41Sopenharmony_ci
6881cb0ef41Sopenharmony_ci    if (typeof depth === 'number' && depth < 0)
6891cb0ef41Sopenharmony_ci      return this;
6901cb0ef41Sopenharmony_ci
6911cb0ef41Sopenharmony_ci    const constructor = getConstructorOf(this) || URL;
6921cb0ef41Sopenharmony_ci    const obj = ObjectCreate({ constructor });
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_ci    obj.href = this.href;
6951cb0ef41Sopenharmony_ci    obj.origin = this.origin;
6961cb0ef41Sopenharmony_ci    obj.protocol = this.protocol;
6971cb0ef41Sopenharmony_ci    obj.username = this.username;
6981cb0ef41Sopenharmony_ci    obj.password = this.password;
6991cb0ef41Sopenharmony_ci    obj.host = this.host;
7001cb0ef41Sopenharmony_ci    obj.hostname = this.hostname;
7011cb0ef41Sopenharmony_ci    obj.port = this.port;
7021cb0ef41Sopenharmony_ci    obj.pathname = this.pathname;
7031cb0ef41Sopenharmony_ci    obj.search = this.search;
7041cb0ef41Sopenharmony_ci    obj.searchParams = this.searchParams;
7051cb0ef41Sopenharmony_ci    obj.hash = this.hash;
7061cb0ef41Sopenharmony_ci
7071cb0ef41Sopenharmony_ci    if (opts.showHidden) {
7081cb0ef41Sopenharmony_ci      obj[context] = this[context];
7091cb0ef41Sopenharmony_ci    }
7101cb0ef41Sopenharmony_ci
7111cb0ef41Sopenharmony_ci    return `${constructor.name} ${inspect(obj, opts)}`;
7121cb0ef41Sopenharmony_ci  }
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_ci  #updateContext(href) {
7151cb0ef41Sopenharmony_ci    const ctx = this[context];
7161cb0ef41Sopenharmony_ci    ctx.href = href;
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ci    const {
7191cb0ef41Sopenharmony_ci      0: protocol_end,
7201cb0ef41Sopenharmony_ci      1: username_end,
7211cb0ef41Sopenharmony_ci      2: host_start,
7221cb0ef41Sopenharmony_ci      3: host_end,
7231cb0ef41Sopenharmony_ci      4: port,
7241cb0ef41Sopenharmony_ci      5: pathname_start,
7251cb0ef41Sopenharmony_ci      6: search_start,
7261cb0ef41Sopenharmony_ci      7: hash_start,
7271cb0ef41Sopenharmony_ci      8: scheme_type,
7281cb0ef41Sopenharmony_ci    } = bindingUrl.urlComponents;
7291cb0ef41Sopenharmony_ci
7301cb0ef41Sopenharmony_ci    ctx.protocol_end = protocol_end;
7311cb0ef41Sopenharmony_ci    ctx.username_end = username_end;
7321cb0ef41Sopenharmony_ci    ctx.host_start = host_start;
7331cb0ef41Sopenharmony_ci    ctx.host_end = host_end;
7341cb0ef41Sopenharmony_ci    ctx.port = port;
7351cb0ef41Sopenharmony_ci    ctx.pathname_start = pathname_start;
7361cb0ef41Sopenharmony_ci    ctx.search_start = search_start;
7371cb0ef41Sopenharmony_ci    ctx.hash_start = hash_start;
7381cb0ef41Sopenharmony_ci    ctx.scheme_type = scheme_type;
7391cb0ef41Sopenharmony_ci
7401cb0ef41Sopenharmony_ci    const alreadyInstantiatedSearchParams = internalSearchParams.get(this);
7411cb0ef41Sopenharmony_ci    if (alreadyInstantiatedSearchParams) {
7421cb0ef41Sopenharmony_ci      if (ctx.hasSearch) {
7431cb0ef41Sopenharmony_ci        alreadyInstantiatedSearchParams[searchParams] = parseParams(this.search);
7441cb0ef41Sopenharmony_ci      } else {
7451cb0ef41Sopenharmony_ci        alreadyInstantiatedSearchParams[searchParams] = [];
7461cb0ef41Sopenharmony_ci      }
7471cb0ef41Sopenharmony_ci    }
7481cb0ef41Sopenharmony_ci  }
7491cb0ef41Sopenharmony_ci
7501cb0ef41Sopenharmony_ci  toString() {
7511cb0ef41Sopenharmony_ci    if (!isURL(this))
7521cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
7531cb0ef41Sopenharmony_ci    return this[context].href;
7541cb0ef41Sopenharmony_ci  }
7551cb0ef41Sopenharmony_ci
7561cb0ef41Sopenharmony_ci  get href() {
7571cb0ef41Sopenharmony_ci    if (!isURL(this))
7581cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
7591cb0ef41Sopenharmony_ci    return this[context].href;
7601cb0ef41Sopenharmony_ci  }
7611cb0ef41Sopenharmony_ci
7621cb0ef41Sopenharmony_ci  set href(value) {
7631cb0ef41Sopenharmony_ci    if (!isURL(this))
7641cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
7651cb0ef41Sopenharmony_ci    value = `${value}`;
7661cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kHref, value);
7671cb0ef41Sopenharmony_ci    if (!href) { throw ERR_INVALID_URL(value); }
7681cb0ef41Sopenharmony_ci    this.#updateContext(href);
7691cb0ef41Sopenharmony_ci  }
7701cb0ef41Sopenharmony_ci
7711cb0ef41Sopenharmony_ci  // readonly
7721cb0ef41Sopenharmony_ci  get origin() {
7731cb0ef41Sopenharmony_ci    if (!isURL(this))
7741cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
7751cb0ef41Sopenharmony_ci    const ctx = this[context];
7761cb0ef41Sopenharmony_ci    const protocol = StringPrototypeSlice(ctx.href, 0, ctx.protocol_end);
7771cb0ef41Sopenharmony_ci
7781cb0ef41Sopenharmony_ci    // Check if scheme_type is not `NOT_SPECIAL`
7791cb0ef41Sopenharmony_ci    if (ctx.scheme_type !== 1) {
7801cb0ef41Sopenharmony_ci      // Check if scheme_type is `FILE`
7811cb0ef41Sopenharmony_ci      if (ctx.scheme_type === 6) {
7821cb0ef41Sopenharmony_ci        return 'null';
7831cb0ef41Sopenharmony_ci      }
7841cb0ef41Sopenharmony_ci      return `${protocol}//${this.host}`;
7851cb0ef41Sopenharmony_ci    }
7861cb0ef41Sopenharmony_ci
7871cb0ef41Sopenharmony_ci    if (protocol === 'blob:') {
7881cb0ef41Sopenharmony_ci      const path = this.pathname;
7891cb0ef41Sopenharmony_ci      if (path.length > 0) {
7901cb0ef41Sopenharmony_ci        try {
7911cb0ef41Sopenharmony_ci          const out = new URL(path);
7921cb0ef41Sopenharmony_ci          // Only return origin of scheme is `http` or `https`
7931cb0ef41Sopenharmony_ci          // Otherwise return a new opaque origin (null).
7941cb0ef41Sopenharmony_ci          if (out[context].scheme_type === 0 || out[context].scheme_type === 2) {
7951cb0ef41Sopenharmony_ci            return `${out.protocol}//${out.host}`;
7961cb0ef41Sopenharmony_ci          }
7971cb0ef41Sopenharmony_ci        } catch {
7981cb0ef41Sopenharmony_ci          // Do nothing.
7991cb0ef41Sopenharmony_ci        }
8001cb0ef41Sopenharmony_ci      }
8011cb0ef41Sopenharmony_ci    }
8021cb0ef41Sopenharmony_ci
8031cb0ef41Sopenharmony_ci    return 'null';
8041cb0ef41Sopenharmony_ci  }
8051cb0ef41Sopenharmony_ci
8061cb0ef41Sopenharmony_ci  get protocol() {
8071cb0ef41Sopenharmony_ci    if (!isURL(this))
8081cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8091cb0ef41Sopenharmony_ci    return StringPrototypeSlice(this[context].href, 0, this[context].protocol_end);
8101cb0ef41Sopenharmony_ci  }
8111cb0ef41Sopenharmony_ci
8121cb0ef41Sopenharmony_ci  set protocol(value) {
8131cb0ef41Sopenharmony_ci    if (!isURL(this))
8141cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8151cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kProtocol, `${value}`);
8161cb0ef41Sopenharmony_ci    if (href) {
8171cb0ef41Sopenharmony_ci      this.#updateContext(href);
8181cb0ef41Sopenharmony_ci    }
8191cb0ef41Sopenharmony_ci  }
8201cb0ef41Sopenharmony_ci
8211cb0ef41Sopenharmony_ci  get username() {
8221cb0ef41Sopenharmony_ci    if (!isURL(this))
8231cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8241cb0ef41Sopenharmony_ci    const ctx = this[context];
8251cb0ef41Sopenharmony_ci    if (ctx.protocol_end + 2 < ctx.username_end) {
8261cb0ef41Sopenharmony_ci      return StringPrototypeSlice(ctx.href, ctx.protocol_end + 2, ctx.username_end);
8271cb0ef41Sopenharmony_ci    }
8281cb0ef41Sopenharmony_ci    return '';
8291cb0ef41Sopenharmony_ci  }
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_ci  set username(value) {
8321cb0ef41Sopenharmony_ci    if (!isURL(this))
8331cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8341cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kUsername, `${value}`);
8351cb0ef41Sopenharmony_ci    if (href) {
8361cb0ef41Sopenharmony_ci      this.#updateContext(href);
8371cb0ef41Sopenharmony_ci    }
8381cb0ef41Sopenharmony_ci  }
8391cb0ef41Sopenharmony_ci
8401cb0ef41Sopenharmony_ci  get password() {
8411cb0ef41Sopenharmony_ci    if (!isURL(this))
8421cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8431cb0ef41Sopenharmony_ci    const ctx = this[context];
8441cb0ef41Sopenharmony_ci    if (ctx.host_start - ctx.username_end > 0) {
8451cb0ef41Sopenharmony_ci      return StringPrototypeSlice(ctx.href, ctx.username_end + 1, ctx.host_start);
8461cb0ef41Sopenharmony_ci    }
8471cb0ef41Sopenharmony_ci    return '';
8481cb0ef41Sopenharmony_ci  }
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ci  set password(value) {
8511cb0ef41Sopenharmony_ci    if (!isURL(this))
8521cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8531cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kPassword, `${value}`);
8541cb0ef41Sopenharmony_ci    if (href) {
8551cb0ef41Sopenharmony_ci      this.#updateContext(href);
8561cb0ef41Sopenharmony_ci    }
8571cb0ef41Sopenharmony_ci  }
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci  get host() {
8601cb0ef41Sopenharmony_ci    if (!isURL(this))
8611cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8621cb0ef41Sopenharmony_ci    const ctx = this[context];
8631cb0ef41Sopenharmony_ci    let startsAt = ctx.host_start;
8641cb0ef41Sopenharmony_ci    if (ctx.href[startsAt] === '@') {
8651cb0ef41Sopenharmony_ci      startsAt++;
8661cb0ef41Sopenharmony_ci    }
8671cb0ef41Sopenharmony_ci    // If we have an empty host, then the space between components.host_end and
8681cb0ef41Sopenharmony_ci    // components.pathname_start may be occupied by /.
8691cb0ef41Sopenharmony_ci    if (startsAt === ctx.host_end) {
8701cb0ef41Sopenharmony_ci      return '';
8711cb0ef41Sopenharmony_ci    }
8721cb0ef41Sopenharmony_ci    return StringPrototypeSlice(ctx.href, startsAt, ctx.pathname_start);
8731cb0ef41Sopenharmony_ci  }
8741cb0ef41Sopenharmony_ci
8751cb0ef41Sopenharmony_ci  set host(value) {
8761cb0ef41Sopenharmony_ci    if (!isURL(this))
8771cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8781cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kHost, `${value}`);
8791cb0ef41Sopenharmony_ci    if (href) {
8801cb0ef41Sopenharmony_ci      this.#updateContext(href);
8811cb0ef41Sopenharmony_ci    }
8821cb0ef41Sopenharmony_ci  }
8831cb0ef41Sopenharmony_ci
8841cb0ef41Sopenharmony_ci  get hostname() {
8851cb0ef41Sopenharmony_ci    if (!isURL(this))
8861cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8871cb0ef41Sopenharmony_ci    const ctx = this[context];
8881cb0ef41Sopenharmony_ci    let startsAt = ctx.host_start;
8891cb0ef41Sopenharmony_ci    // host_start might be "@" if the URL has credentials
8901cb0ef41Sopenharmony_ci    if (ctx.href[startsAt] === '@') {
8911cb0ef41Sopenharmony_ci      startsAt++;
8921cb0ef41Sopenharmony_ci    }
8931cb0ef41Sopenharmony_ci    return StringPrototypeSlice(ctx.href, startsAt, ctx.host_end);
8941cb0ef41Sopenharmony_ci  }
8951cb0ef41Sopenharmony_ci
8961cb0ef41Sopenharmony_ci  set hostname(value) {
8971cb0ef41Sopenharmony_ci    if (!isURL(this))
8981cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
8991cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kHostname, `${value}`);
9001cb0ef41Sopenharmony_ci    if (href) {
9011cb0ef41Sopenharmony_ci      this.#updateContext(href);
9021cb0ef41Sopenharmony_ci    }
9031cb0ef41Sopenharmony_ci  }
9041cb0ef41Sopenharmony_ci
9051cb0ef41Sopenharmony_ci  get port() {
9061cb0ef41Sopenharmony_ci    if (!isURL(this))
9071cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9081cb0ef41Sopenharmony_ci    if (this[context].hasPort) {
9091cb0ef41Sopenharmony_ci      return `${this[context].port}`;
9101cb0ef41Sopenharmony_ci    }
9111cb0ef41Sopenharmony_ci    return '';
9121cb0ef41Sopenharmony_ci  }
9131cb0ef41Sopenharmony_ci
9141cb0ef41Sopenharmony_ci  set port(value) {
9151cb0ef41Sopenharmony_ci    if (!isURL(this))
9161cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9171cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kPort, `${value}`);
9181cb0ef41Sopenharmony_ci    if (href) {
9191cb0ef41Sopenharmony_ci      this.#updateContext(href);
9201cb0ef41Sopenharmony_ci    }
9211cb0ef41Sopenharmony_ci  }
9221cb0ef41Sopenharmony_ci
9231cb0ef41Sopenharmony_ci  get pathname() {
9241cb0ef41Sopenharmony_ci    if (!isURL(this))
9251cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9261cb0ef41Sopenharmony_ci    const ctx = this[context];
9271cb0ef41Sopenharmony_ci    let endsAt;
9281cb0ef41Sopenharmony_ci    if (ctx.hasSearch) {
9291cb0ef41Sopenharmony_ci      endsAt = ctx.search_start;
9301cb0ef41Sopenharmony_ci    } else if (ctx.hasHash) {
9311cb0ef41Sopenharmony_ci      endsAt = ctx.hash_start;
9321cb0ef41Sopenharmony_ci    }
9331cb0ef41Sopenharmony_ci    return StringPrototypeSlice(ctx.href, ctx.pathname_start, endsAt);
9341cb0ef41Sopenharmony_ci  }
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_ci  set pathname(value) {
9371cb0ef41Sopenharmony_ci    if (!isURL(this))
9381cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9391cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kPathname, `${value}`);
9401cb0ef41Sopenharmony_ci    if (href) {
9411cb0ef41Sopenharmony_ci      this.#updateContext(href);
9421cb0ef41Sopenharmony_ci    }
9431cb0ef41Sopenharmony_ci  }
9441cb0ef41Sopenharmony_ci
9451cb0ef41Sopenharmony_ci  get search() {
9461cb0ef41Sopenharmony_ci    if (!isURL(this))
9471cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9481cb0ef41Sopenharmony_ci    const ctx = this[context];
9491cb0ef41Sopenharmony_ci    if (!ctx.hasSearch) { return ''; }
9501cb0ef41Sopenharmony_ci    let endsAt = ctx.href.length;
9511cb0ef41Sopenharmony_ci    if (ctx.hasHash) { endsAt = ctx.hash_start; }
9521cb0ef41Sopenharmony_ci    if (endsAt - ctx.search_start <= 1) { return ''; }
9531cb0ef41Sopenharmony_ci    return StringPrototypeSlice(ctx.href, ctx.search_start, endsAt);
9541cb0ef41Sopenharmony_ci  }
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci  set search(value) {
9571cb0ef41Sopenharmony_ci    if (!isURL(this))
9581cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9591cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kSearch, toUSVString(value));
9601cb0ef41Sopenharmony_ci    if (href) {
9611cb0ef41Sopenharmony_ci      this.#updateContext(href);
9621cb0ef41Sopenharmony_ci    }
9631cb0ef41Sopenharmony_ci  }
9641cb0ef41Sopenharmony_ci
9651cb0ef41Sopenharmony_ci  // readonly
9661cb0ef41Sopenharmony_ci  get searchParams() {
9671cb0ef41Sopenharmony_ci    if (!isURL(this))
9681cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9691cb0ef41Sopenharmony_ci
9701cb0ef41Sopenharmony_ci    const cachedValue = internalSearchParams.get(this);
9711cb0ef41Sopenharmony_ci    if (cachedValue != null)
9721cb0ef41Sopenharmony_ci      return cachedValue;
9731cb0ef41Sopenharmony_ci
9741cb0ef41Sopenharmony_ci    const value = new URLSearchParams(this.search);
9751cb0ef41Sopenharmony_ci    value[context] = this;
9761cb0ef41Sopenharmony_ci    internalSearchParams.set(this, value);
9771cb0ef41Sopenharmony_ci    return value;
9781cb0ef41Sopenharmony_ci  }
9791cb0ef41Sopenharmony_ci
9801cb0ef41Sopenharmony_ci  get hash() {
9811cb0ef41Sopenharmony_ci    if (!isURL(this))
9821cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9831cb0ef41Sopenharmony_ci    const ctx = this[context];
9841cb0ef41Sopenharmony_ci    if (!ctx.hasHash || (ctx.href.length - ctx.hash_start <= 1)) {
9851cb0ef41Sopenharmony_ci      return '';
9861cb0ef41Sopenharmony_ci    }
9871cb0ef41Sopenharmony_ci    return StringPrototypeSlice(ctx.href, ctx.hash_start);
9881cb0ef41Sopenharmony_ci  }
9891cb0ef41Sopenharmony_ci
9901cb0ef41Sopenharmony_ci  set hash(value) {
9911cb0ef41Sopenharmony_ci    if (!isURL(this))
9921cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
9931cb0ef41Sopenharmony_ci    const href = bindingUrl.update(this[context].href, updateActions.kHash, `${value}`);
9941cb0ef41Sopenharmony_ci    if (href) {
9951cb0ef41Sopenharmony_ci      this.#updateContext(href);
9961cb0ef41Sopenharmony_ci    }
9971cb0ef41Sopenharmony_ci  }
9981cb0ef41Sopenharmony_ci
9991cb0ef41Sopenharmony_ci  toJSON() {
10001cb0ef41Sopenharmony_ci    if (!isURL(this))
10011cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URL');
10021cb0ef41Sopenharmony_ci    return this[context].href;
10031cb0ef41Sopenharmony_ci  }
10041cb0ef41Sopenharmony_ci
10051cb0ef41Sopenharmony_ci  static canParse(url, base = undefined) {
10061cb0ef41Sopenharmony_ci    if (arguments.length === 0) {
10071cb0ef41Sopenharmony_ci      throw new ERR_MISSING_ARGS('url');
10081cb0ef41Sopenharmony_ci    }
10091cb0ef41Sopenharmony_ci
10101cb0ef41Sopenharmony_ci    url = `${url}`;
10111cb0ef41Sopenharmony_ci
10121cb0ef41Sopenharmony_ci    if (base !== undefined) {
10131cb0ef41Sopenharmony_ci      base = `${base}`;
10141cb0ef41Sopenharmony_ci    }
10151cb0ef41Sopenharmony_ci
10161cb0ef41Sopenharmony_ci    return bindingUrl.canParse(url, base);
10171cb0ef41Sopenharmony_ci  }
10181cb0ef41Sopenharmony_ci
10191cb0ef41Sopenharmony_ci  static createObjectURL(obj) {
10201cb0ef41Sopenharmony_ci    const cryptoRandom = lazyCryptoRandom();
10211cb0ef41Sopenharmony_ci    if (cryptoRandom === undefined)
10221cb0ef41Sopenharmony_ci      throw new ERR_NO_CRYPTO();
10231cb0ef41Sopenharmony_ci
10241cb0ef41Sopenharmony_ci    const blob = lazyBlob();
10251cb0ef41Sopenharmony_ci    if (!blob.isBlob(obj))
10261cb0ef41Sopenharmony_ci      throw new ERR_INVALID_ARG_TYPE('obj', 'Blob', obj);
10271cb0ef41Sopenharmony_ci
10281cb0ef41Sopenharmony_ci    const id = cryptoRandom.randomUUID();
10291cb0ef41Sopenharmony_ci
10301cb0ef41Sopenharmony_ci    storeDataObject(id, obj[blob.kHandle], obj.size, obj.type);
10311cb0ef41Sopenharmony_ci
10321cb0ef41Sopenharmony_ci    return `blob:nodedata:${id}`;
10331cb0ef41Sopenharmony_ci  }
10341cb0ef41Sopenharmony_ci
10351cb0ef41Sopenharmony_ci  static revokeObjectURL(url) {
10361cb0ef41Sopenharmony_ci    url = `${url}`;
10371cb0ef41Sopenharmony_ci    try {
10381cb0ef41Sopenharmony_ci      // TODO(@anonrig): Remove this try/catch by calling `parse` directly.
10391cb0ef41Sopenharmony_ci      const parsed = new URL(url);
10401cb0ef41Sopenharmony_ci      const split = StringPrototypeSplit(parsed.pathname, ':');
10411cb0ef41Sopenharmony_ci      if (split.length === 2)
10421cb0ef41Sopenharmony_ci        revokeDataObject(split[1]);
10431cb0ef41Sopenharmony_ci    } catch {
10441cb0ef41Sopenharmony_ci      // If there's an error, it's ignored.
10451cb0ef41Sopenharmony_ci    }
10461cb0ef41Sopenharmony_ci  }
10471cb0ef41Sopenharmony_ci}
10481cb0ef41Sopenharmony_ci
10491cb0ef41Sopenharmony_ciObjectDefineProperties(URL.prototype, {
10501cb0ef41Sopenharmony_ci  [SymbolToStringTag]: { __proto__: null, configurable: true, value: 'URL' },
10511cb0ef41Sopenharmony_ci  toString: kEnumerableProperty,
10521cb0ef41Sopenharmony_ci  href: kEnumerableProperty,
10531cb0ef41Sopenharmony_ci  origin: kEnumerableProperty,
10541cb0ef41Sopenharmony_ci  protocol: kEnumerableProperty,
10551cb0ef41Sopenharmony_ci  username: kEnumerableProperty,
10561cb0ef41Sopenharmony_ci  password: kEnumerableProperty,
10571cb0ef41Sopenharmony_ci  host: kEnumerableProperty,
10581cb0ef41Sopenharmony_ci  hostname: kEnumerableProperty,
10591cb0ef41Sopenharmony_ci  port: kEnumerableProperty,
10601cb0ef41Sopenharmony_ci  pathname: kEnumerableProperty,
10611cb0ef41Sopenharmony_ci  search: kEnumerableProperty,
10621cb0ef41Sopenharmony_ci  searchParams: kEnumerableProperty,
10631cb0ef41Sopenharmony_ci  hash: kEnumerableProperty,
10641cb0ef41Sopenharmony_ci  toJSON: kEnumerableProperty,
10651cb0ef41Sopenharmony_ci});
10661cb0ef41Sopenharmony_ci
10671cb0ef41Sopenharmony_ciObjectDefineProperties(URL, {
10681cb0ef41Sopenharmony_ci  canParse: {
10691cb0ef41Sopenharmony_ci    __proto__: null,
10701cb0ef41Sopenharmony_ci    configurable: true,
10711cb0ef41Sopenharmony_ci    writable: true,
10721cb0ef41Sopenharmony_ci    enumerable: true,
10731cb0ef41Sopenharmony_ci  },
10741cb0ef41Sopenharmony_ci  createObjectURL: kEnumerableProperty,
10751cb0ef41Sopenharmony_ci  revokeObjectURL: kEnumerableProperty,
10761cb0ef41Sopenharmony_ci});
10771cb0ef41Sopenharmony_ci
10781cb0ef41Sopenharmony_ci// application/x-www-form-urlencoded parser
10791cb0ef41Sopenharmony_ci// Ref: https://url.spec.whatwg.org/#concept-urlencoded-parser
10801cb0ef41Sopenharmony_cifunction parseParams(qs) {
10811cb0ef41Sopenharmony_ci  const out = [];
10821cb0ef41Sopenharmony_ci  let seenSep = false;
10831cb0ef41Sopenharmony_ci  let buf = '';
10841cb0ef41Sopenharmony_ci  let encoded = false;
10851cb0ef41Sopenharmony_ci  let encodeCheck = 0;
10861cb0ef41Sopenharmony_ci  let i = qs[0] === '?' ? 1 : 0;
10871cb0ef41Sopenharmony_ci  let pairStart = i;
10881cb0ef41Sopenharmony_ci  let lastPos = i;
10891cb0ef41Sopenharmony_ci  for (; i < qs.length; ++i) {
10901cb0ef41Sopenharmony_ci    const code = StringPrototypeCharCodeAt(qs, i);
10911cb0ef41Sopenharmony_ci
10921cb0ef41Sopenharmony_ci    // Try matching key/value pair separator
10931cb0ef41Sopenharmony_ci    if (code === CHAR_AMPERSAND) {
10941cb0ef41Sopenharmony_ci      if (pairStart === i) {
10951cb0ef41Sopenharmony_ci        // We saw an empty substring between pair separators
10961cb0ef41Sopenharmony_ci        lastPos = pairStart = i + 1;
10971cb0ef41Sopenharmony_ci        continue;
10981cb0ef41Sopenharmony_ci      }
10991cb0ef41Sopenharmony_ci
11001cb0ef41Sopenharmony_ci      if (lastPos < i)
11011cb0ef41Sopenharmony_ci        buf += qs.slice(lastPos, i);
11021cb0ef41Sopenharmony_ci      if (encoded)
11031cb0ef41Sopenharmony_ci        buf = querystring.unescape(buf);
11041cb0ef41Sopenharmony_ci      out.push(buf);
11051cb0ef41Sopenharmony_ci
11061cb0ef41Sopenharmony_ci      // If `buf` is the key, add an empty value.
11071cb0ef41Sopenharmony_ci      if (!seenSep)
11081cb0ef41Sopenharmony_ci        out.push('');
11091cb0ef41Sopenharmony_ci
11101cb0ef41Sopenharmony_ci      seenSep = false;
11111cb0ef41Sopenharmony_ci      buf = '';
11121cb0ef41Sopenharmony_ci      encoded = false;
11131cb0ef41Sopenharmony_ci      encodeCheck = 0;
11141cb0ef41Sopenharmony_ci      lastPos = pairStart = i + 1;
11151cb0ef41Sopenharmony_ci      continue;
11161cb0ef41Sopenharmony_ci    }
11171cb0ef41Sopenharmony_ci
11181cb0ef41Sopenharmony_ci    // Try matching key/value separator (e.g. '=') if we haven't already
11191cb0ef41Sopenharmony_ci    if (!seenSep && code === CHAR_EQUAL) {
11201cb0ef41Sopenharmony_ci      // Key/value separator match!
11211cb0ef41Sopenharmony_ci      if (lastPos < i)
11221cb0ef41Sopenharmony_ci        buf += qs.slice(lastPos, i);
11231cb0ef41Sopenharmony_ci      if (encoded)
11241cb0ef41Sopenharmony_ci        buf = querystring.unescape(buf);
11251cb0ef41Sopenharmony_ci      out.push(buf);
11261cb0ef41Sopenharmony_ci
11271cb0ef41Sopenharmony_ci      seenSep = true;
11281cb0ef41Sopenharmony_ci      buf = '';
11291cb0ef41Sopenharmony_ci      encoded = false;
11301cb0ef41Sopenharmony_ci      encodeCheck = 0;
11311cb0ef41Sopenharmony_ci      lastPos = i + 1;
11321cb0ef41Sopenharmony_ci      continue;
11331cb0ef41Sopenharmony_ci    }
11341cb0ef41Sopenharmony_ci
11351cb0ef41Sopenharmony_ci    // Handle + and percent decoding.
11361cb0ef41Sopenharmony_ci    if (code === CHAR_PLUS) {
11371cb0ef41Sopenharmony_ci      if (lastPos < i)
11381cb0ef41Sopenharmony_ci        buf += StringPrototypeSlice(qs, lastPos, i);
11391cb0ef41Sopenharmony_ci      buf += ' ';
11401cb0ef41Sopenharmony_ci      lastPos = i + 1;
11411cb0ef41Sopenharmony_ci    } else if (!encoded) {
11421cb0ef41Sopenharmony_ci      // Try to match an (valid) encoded byte (once) to minimize unnecessary
11431cb0ef41Sopenharmony_ci      // calls to string decoding functions
11441cb0ef41Sopenharmony_ci      if (code === CHAR_PERCENT) {
11451cb0ef41Sopenharmony_ci        encodeCheck = 1;
11461cb0ef41Sopenharmony_ci      } else if (encodeCheck > 0) {
11471cb0ef41Sopenharmony_ci        if (isHexTable[code] === 1) {
11481cb0ef41Sopenharmony_ci          if (++encodeCheck === 3) {
11491cb0ef41Sopenharmony_ci            encoded = true;
11501cb0ef41Sopenharmony_ci          }
11511cb0ef41Sopenharmony_ci        } else {
11521cb0ef41Sopenharmony_ci          encodeCheck = 0;
11531cb0ef41Sopenharmony_ci        }
11541cb0ef41Sopenharmony_ci      }
11551cb0ef41Sopenharmony_ci    }
11561cb0ef41Sopenharmony_ci  }
11571cb0ef41Sopenharmony_ci
11581cb0ef41Sopenharmony_ci  // Deal with any leftover key or value data
11591cb0ef41Sopenharmony_ci
11601cb0ef41Sopenharmony_ci  // There is a trailing &. No more processing is needed.
11611cb0ef41Sopenharmony_ci  if (pairStart === i)
11621cb0ef41Sopenharmony_ci    return out;
11631cb0ef41Sopenharmony_ci
11641cb0ef41Sopenharmony_ci  if (lastPos < i)
11651cb0ef41Sopenharmony_ci    buf += StringPrototypeSlice(qs, lastPos, i);
11661cb0ef41Sopenharmony_ci  if (encoded)
11671cb0ef41Sopenharmony_ci    buf = querystring.unescape(buf);
11681cb0ef41Sopenharmony_ci  ArrayPrototypePush(out, buf);
11691cb0ef41Sopenharmony_ci
11701cb0ef41Sopenharmony_ci  // If `buf` is the key, add an empty value.
11711cb0ef41Sopenharmony_ci  if (!seenSep)
11721cb0ef41Sopenharmony_ci    ArrayPrototypePush(out, '');
11731cb0ef41Sopenharmony_ci
11741cb0ef41Sopenharmony_ci  return out;
11751cb0ef41Sopenharmony_ci}
11761cb0ef41Sopenharmony_ci
11771cb0ef41Sopenharmony_ci// Adapted from querystring's implementation.
11781cb0ef41Sopenharmony_ci// Ref: https://url.spec.whatwg.org/#concept-urlencoded-byte-serializer
11791cb0ef41Sopenharmony_ciconst noEscape = new Int8Array([
11801cb0ef41Sopenharmony_ci/*
11811cb0ef41Sopenharmony_ci  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
11821cb0ef41Sopenharmony_ci*/
11831cb0ef41Sopenharmony_ci  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F
11841cb0ef41Sopenharmony_ci  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F
11851cb0ef41Sopenharmony_ci  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, // 0x20 - 0x2F
11861cb0ef41Sopenharmony_ci  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F
11871cb0ef41Sopenharmony_ci  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 0x4F
11881cb0ef41Sopenharmony_ci  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 0x50 - 0x5F
11891cb0ef41Sopenharmony_ci  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6F
11901cb0ef41Sopenharmony_ci  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  // 0x70 - 0x7F
11911cb0ef41Sopenharmony_ci]);
11921cb0ef41Sopenharmony_ci
11931cb0ef41Sopenharmony_ci// Special version of hexTable that uses `+` for U+0020 SPACE.
11941cb0ef41Sopenharmony_ciconst paramHexTable = hexTable.slice();
11951cb0ef41Sopenharmony_ciparamHexTable[0x20] = '+';
11961cb0ef41Sopenharmony_ci
11971cb0ef41Sopenharmony_ci// application/x-www-form-urlencoded serializer
11981cb0ef41Sopenharmony_ci// Ref: https://url.spec.whatwg.org/#concept-urlencoded-serializer
11991cb0ef41Sopenharmony_cifunction serializeParams(array) {
12001cb0ef41Sopenharmony_ci  const len = array.length;
12011cb0ef41Sopenharmony_ci  if (len === 0)
12021cb0ef41Sopenharmony_ci    return '';
12031cb0ef41Sopenharmony_ci
12041cb0ef41Sopenharmony_ci  const firstEncodedParam = encodeStr(array[0], noEscape, paramHexTable);
12051cb0ef41Sopenharmony_ci  const firstEncodedValue = encodeStr(array[1], noEscape, paramHexTable);
12061cb0ef41Sopenharmony_ci  let output = `${firstEncodedParam}=${firstEncodedValue}`;
12071cb0ef41Sopenharmony_ci
12081cb0ef41Sopenharmony_ci  for (let i = 2; i < len; i += 2) {
12091cb0ef41Sopenharmony_ci    const encodedParam = encodeStr(array[i], noEscape, paramHexTable);
12101cb0ef41Sopenharmony_ci    const encodedValue = encodeStr(array[i + 1], noEscape, paramHexTable);
12111cb0ef41Sopenharmony_ci    output += `&${encodedParam}=${encodedValue}`;
12121cb0ef41Sopenharmony_ci  }
12131cb0ef41Sopenharmony_ci
12141cb0ef41Sopenharmony_ci  return output;
12151cb0ef41Sopenharmony_ci}
12161cb0ef41Sopenharmony_ci
12171cb0ef41Sopenharmony_ci// Mainly to mitigate func-name-matching ESLint rule
12181cb0ef41Sopenharmony_cifunction defineIDLClass(proto, classStr, obj) {
12191cb0ef41Sopenharmony_ci  // https://heycam.github.io/webidl/#dfn-class-string
12201cb0ef41Sopenharmony_ci  ObjectDefineProperty(proto, SymbolToStringTag, {
12211cb0ef41Sopenharmony_ci    __proto__: null,
12221cb0ef41Sopenharmony_ci    writable: false,
12231cb0ef41Sopenharmony_ci    enumerable: false,
12241cb0ef41Sopenharmony_ci    configurable: true,
12251cb0ef41Sopenharmony_ci    value: classStr,
12261cb0ef41Sopenharmony_ci  });
12271cb0ef41Sopenharmony_ci
12281cb0ef41Sopenharmony_ci  // https://heycam.github.io/webidl/#es-operations
12291cb0ef41Sopenharmony_ci  for (const key of ObjectKeys(obj)) {
12301cb0ef41Sopenharmony_ci    ObjectDefineProperty(proto, key, {
12311cb0ef41Sopenharmony_ci      __proto__: null,
12321cb0ef41Sopenharmony_ci      writable: true,
12331cb0ef41Sopenharmony_ci      enumerable: true,
12341cb0ef41Sopenharmony_ci      configurable: true,
12351cb0ef41Sopenharmony_ci      value: obj[key],
12361cb0ef41Sopenharmony_ci    });
12371cb0ef41Sopenharmony_ci  }
12381cb0ef41Sopenharmony_ci  for (const key of ObjectGetOwnPropertySymbols(obj)) {
12391cb0ef41Sopenharmony_ci    ObjectDefineProperty(proto, key, {
12401cb0ef41Sopenharmony_ci      __proto__: null,
12411cb0ef41Sopenharmony_ci      writable: true,
12421cb0ef41Sopenharmony_ci      enumerable: false,
12431cb0ef41Sopenharmony_ci      configurable: true,
12441cb0ef41Sopenharmony_ci      value: obj[key],
12451cb0ef41Sopenharmony_ci    });
12461cb0ef41Sopenharmony_ci  }
12471cb0ef41Sopenharmony_ci}
12481cb0ef41Sopenharmony_ci
12491cb0ef41Sopenharmony_ci// for merge sort
12501cb0ef41Sopenharmony_cifunction merge(out, start, mid, end, lBuffer, rBuffer) {
12511cb0ef41Sopenharmony_ci  const sizeLeft = mid - start;
12521cb0ef41Sopenharmony_ci  const sizeRight = end - mid;
12531cb0ef41Sopenharmony_ci  let l, r, o;
12541cb0ef41Sopenharmony_ci
12551cb0ef41Sopenharmony_ci  for (l = 0; l < sizeLeft; l++)
12561cb0ef41Sopenharmony_ci    lBuffer[l] = out[start + l];
12571cb0ef41Sopenharmony_ci  for (r = 0; r < sizeRight; r++)
12581cb0ef41Sopenharmony_ci    rBuffer[r] = out[mid + r];
12591cb0ef41Sopenharmony_ci
12601cb0ef41Sopenharmony_ci  l = 0;
12611cb0ef41Sopenharmony_ci  r = 0;
12621cb0ef41Sopenharmony_ci  o = start;
12631cb0ef41Sopenharmony_ci  while (l < sizeLeft && r < sizeRight) {
12641cb0ef41Sopenharmony_ci    if (lBuffer[l] <= rBuffer[r]) {
12651cb0ef41Sopenharmony_ci      out[o++] = lBuffer[l++];
12661cb0ef41Sopenharmony_ci      out[o++] = lBuffer[l++];
12671cb0ef41Sopenharmony_ci    } else {
12681cb0ef41Sopenharmony_ci      out[o++] = rBuffer[r++];
12691cb0ef41Sopenharmony_ci      out[o++] = rBuffer[r++];
12701cb0ef41Sopenharmony_ci    }
12711cb0ef41Sopenharmony_ci  }
12721cb0ef41Sopenharmony_ci  while (l < sizeLeft)
12731cb0ef41Sopenharmony_ci    out[o++] = lBuffer[l++];
12741cb0ef41Sopenharmony_ci  while (r < sizeRight)
12751cb0ef41Sopenharmony_ci    out[o++] = rBuffer[r++];
12761cb0ef41Sopenharmony_ci}
12771cb0ef41Sopenharmony_ci
12781cb0ef41Sopenharmony_ci// https://heycam.github.io/webidl/#dfn-default-iterator-object
12791cb0ef41Sopenharmony_cifunction createSearchParamsIterator(target, kind) {
12801cb0ef41Sopenharmony_ci  const iterator = ObjectCreate(URLSearchParamsIteratorPrototype);
12811cb0ef41Sopenharmony_ci  iterator[context] = {
12821cb0ef41Sopenharmony_ci    target,
12831cb0ef41Sopenharmony_ci    kind,
12841cb0ef41Sopenharmony_ci    index: 0,
12851cb0ef41Sopenharmony_ci  };
12861cb0ef41Sopenharmony_ci  return iterator;
12871cb0ef41Sopenharmony_ci}
12881cb0ef41Sopenharmony_ci
12891cb0ef41Sopenharmony_ci// https://heycam.github.io/webidl/#dfn-iterator-prototype-object
12901cb0ef41Sopenharmony_ciconst URLSearchParamsIteratorPrototype = ObjectCreate(IteratorPrototype);
12911cb0ef41Sopenharmony_ci
12921cb0ef41Sopenharmony_cidefineIDLClass(URLSearchParamsIteratorPrototype, 'URLSearchParams Iterator', {
12931cb0ef41Sopenharmony_ci  next() {
12941cb0ef41Sopenharmony_ci    if (!this ||
12951cb0ef41Sopenharmony_ci        ObjectGetPrototypeOf(this) !== URLSearchParamsIteratorPrototype) {
12961cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParamsIterator');
12971cb0ef41Sopenharmony_ci    }
12981cb0ef41Sopenharmony_ci
12991cb0ef41Sopenharmony_ci    const {
13001cb0ef41Sopenharmony_ci      target,
13011cb0ef41Sopenharmony_ci      kind,
13021cb0ef41Sopenharmony_ci      index,
13031cb0ef41Sopenharmony_ci    } = this[context];
13041cb0ef41Sopenharmony_ci    const values = target[searchParams];
13051cb0ef41Sopenharmony_ci    const len = values.length;
13061cb0ef41Sopenharmony_ci    if (index >= len) {
13071cb0ef41Sopenharmony_ci      return {
13081cb0ef41Sopenharmony_ci        value: undefined,
13091cb0ef41Sopenharmony_ci        done: true,
13101cb0ef41Sopenharmony_ci      };
13111cb0ef41Sopenharmony_ci    }
13121cb0ef41Sopenharmony_ci
13131cb0ef41Sopenharmony_ci    const name = values[index];
13141cb0ef41Sopenharmony_ci    const value = values[index + 1];
13151cb0ef41Sopenharmony_ci    this[context].index = index + 2;
13161cb0ef41Sopenharmony_ci
13171cb0ef41Sopenharmony_ci    let result;
13181cb0ef41Sopenharmony_ci    if (kind === 'key') {
13191cb0ef41Sopenharmony_ci      result = name;
13201cb0ef41Sopenharmony_ci    } else if (kind === 'value') {
13211cb0ef41Sopenharmony_ci      result = value;
13221cb0ef41Sopenharmony_ci    } else {
13231cb0ef41Sopenharmony_ci      result = [name, value];
13241cb0ef41Sopenharmony_ci    }
13251cb0ef41Sopenharmony_ci
13261cb0ef41Sopenharmony_ci    return {
13271cb0ef41Sopenharmony_ci      value: result,
13281cb0ef41Sopenharmony_ci      done: false,
13291cb0ef41Sopenharmony_ci    };
13301cb0ef41Sopenharmony_ci  },
13311cb0ef41Sopenharmony_ci  [inspect.custom](recurseTimes, ctx) {
13321cb0ef41Sopenharmony_ci    if (this == null || this[context] == null || this[context].target == null)
13331cb0ef41Sopenharmony_ci      throw new ERR_INVALID_THIS('URLSearchParamsIterator');
13341cb0ef41Sopenharmony_ci
13351cb0ef41Sopenharmony_ci    if (typeof recurseTimes === 'number' && recurseTimes < 0)
13361cb0ef41Sopenharmony_ci      return ctx.stylize('[Object]', 'special');
13371cb0ef41Sopenharmony_ci
13381cb0ef41Sopenharmony_ci    const innerOpts = { ...ctx };
13391cb0ef41Sopenharmony_ci    if (recurseTimes !== null) {
13401cb0ef41Sopenharmony_ci      innerOpts.depth = recurseTimes - 1;
13411cb0ef41Sopenharmony_ci    }
13421cb0ef41Sopenharmony_ci    const {
13431cb0ef41Sopenharmony_ci      target,
13441cb0ef41Sopenharmony_ci      kind,
13451cb0ef41Sopenharmony_ci      index,
13461cb0ef41Sopenharmony_ci    } = this[context];
13471cb0ef41Sopenharmony_ci    const output = ArrayPrototypeReduce(
13481cb0ef41Sopenharmony_ci      ArrayPrototypeSlice(target[searchParams], index),
13491cb0ef41Sopenharmony_ci      (prev, cur, i) => {
13501cb0ef41Sopenharmony_ci        const key = i % 2 === 0;
13511cb0ef41Sopenharmony_ci        if (kind === 'key' && key) {
13521cb0ef41Sopenharmony_ci          ArrayPrototypePush(prev, cur);
13531cb0ef41Sopenharmony_ci        } else if (kind === 'value' && !key) {
13541cb0ef41Sopenharmony_ci          ArrayPrototypePush(prev, cur);
13551cb0ef41Sopenharmony_ci        } else if (kind === 'key+value' && !key) {
13561cb0ef41Sopenharmony_ci          ArrayPrototypePush(prev, [target[searchParams][index + i - 1], cur]);
13571cb0ef41Sopenharmony_ci        }
13581cb0ef41Sopenharmony_ci        return prev;
13591cb0ef41Sopenharmony_ci      },
13601cb0ef41Sopenharmony_ci      [],
13611cb0ef41Sopenharmony_ci    );
13621cb0ef41Sopenharmony_ci    const breakLn = StringPrototypeIncludes(inspect(output, innerOpts), '\n');
13631cb0ef41Sopenharmony_ci    const outputStrs = ArrayPrototypeMap(output, (p) => inspect(p, innerOpts));
13641cb0ef41Sopenharmony_ci    let outputStr;
13651cb0ef41Sopenharmony_ci    if (breakLn) {
13661cb0ef41Sopenharmony_ci      outputStr = `\n  ${ArrayPrototypeJoin(outputStrs, ',\n  ')}`;
13671cb0ef41Sopenharmony_ci    } else {
13681cb0ef41Sopenharmony_ci      outputStr = ` ${ArrayPrototypeJoin(outputStrs, ', ')}`;
13691cb0ef41Sopenharmony_ci    }
13701cb0ef41Sopenharmony_ci    return `${this[SymbolToStringTag]} {${outputStr} }`;
13711cb0ef41Sopenharmony_ci  },
13721cb0ef41Sopenharmony_ci});
13731cb0ef41Sopenharmony_ci
13741cb0ef41Sopenharmony_cifunction domainToASCII(domain) {
13751cb0ef41Sopenharmony_ci  if (arguments.length < 1)
13761cb0ef41Sopenharmony_ci    throw new ERR_MISSING_ARGS('domain');
13771cb0ef41Sopenharmony_ci
13781cb0ef41Sopenharmony_ci  // toUSVString is not needed.
13791cb0ef41Sopenharmony_ci  return bindingUrl.domainToASCII(`${domain}`);
13801cb0ef41Sopenharmony_ci}
13811cb0ef41Sopenharmony_ci
13821cb0ef41Sopenharmony_cifunction domainToUnicode(domain) {
13831cb0ef41Sopenharmony_ci  if (arguments.length < 1)
13841cb0ef41Sopenharmony_ci    throw new ERR_MISSING_ARGS('domain');
13851cb0ef41Sopenharmony_ci
13861cb0ef41Sopenharmony_ci  // toUSVString is not needed.
13871cb0ef41Sopenharmony_ci  return bindingUrl.domainToUnicode(`${domain}`);
13881cb0ef41Sopenharmony_ci}
13891cb0ef41Sopenharmony_ci
13901cb0ef41Sopenharmony_ci/**
13911cb0ef41Sopenharmony_ci * Utility function that converts a URL object into an ordinary options object
13921cb0ef41Sopenharmony_ci * as expected by the `http.request` and `https.request` APIs.
13931cb0ef41Sopenharmony_ci * @param {URL} url
13941cb0ef41Sopenharmony_ci * @returns {Record<string, unknown>}
13951cb0ef41Sopenharmony_ci */
13961cb0ef41Sopenharmony_cifunction urlToHttpOptions(url) {
13971cb0ef41Sopenharmony_ci  const { hostname, pathname, port, username, password, search } = url;
13981cb0ef41Sopenharmony_ci  const options = {
13991cb0ef41Sopenharmony_ci    __proto__: null,
14001cb0ef41Sopenharmony_ci    ...url, // In case the url object was extended by the user.
14011cb0ef41Sopenharmony_ci    protocol: url.protocol,
14021cb0ef41Sopenharmony_ci    hostname: hostname && StringPrototypeStartsWith(hostname, '[') ?
14031cb0ef41Sopenharmony_ci      StringPrototypeSlice(hostname, 1, -1) :
14041cb0ef41Sopenharmony_ci      hostname,
14051cb0ef41Sopenharmony_ci    hash: url.hash,
14061cb0ef41Sopenharmony_ci    search: search,
14071cb0ef41Sopenharmony_ci    pathname: pathname,
14081cb0ef41Sopenharmony_ci    path: `${pathname || ''}${search || ''}`,
14091cb0ef41Sopenharmony_ci    href: url.href,
14101cb0ef41Sopenharmony_ci  };
14111cb0ef41Sopenharmony_ci  if (port !== '') {
14121cb0ef41Sopenharmony_ci    options.port = Number(port);
14131cb0ef41Sopenharmony_ci  }
14141cb0ef41Sopenharmony_ci  if (username || password) {
14151cb0ef41Sopenharmony_ci    options.auth = `${decodeURIComponent(username)}:${decodeURIComponent(password)}`;
14161cb0ef41Sopenharmony_ci  }
14171cb0ef41Sopenharmony_ci  return options;
14181cb0ef41Sopenharmony_ci}
14191cb0ef41Sopenharmony_ci
14201cb0ef41Sopenharmony_cifunction getPathFromURLWin32(url) {
14211cb0ef41Sopenharmony_ci  const hostname = url.hostname;
14221cb0ef41Sopenharmony_ci  let pathname = url.pathname;
14231cb0ef41Sopenharmony_ci  for (let n = 0; n < pathname.length; n++) {
14241cb0ef41Sopenharmony_ci    if (pathname[n] === '%') {
14251cb0ef41Sopenharmony_ci      const third = StringPrototypeCodePointAt(pathname, n + 2) | 0x20;
14261cb0ef41Sopenharmony_ci      if ((pathname[n + 1] === '2' && third === 102) || // 2f 2F /
14271cb0ef41Sopenharmony_ci          (pathname[n + 1] === '5' && third === 99)) {  // 5c 5C \
14281cb0ef41Sopenharmony_ci        throw new ERR_INVALID_FILE_URL_PATH(
14291cb0ef41Sopenharmony_ci          'must not include encoded \\ or / characters',
14301cb0ef41Sopenharmony_ci        );
14311cb0ef41Sopenharmony_ci      }
14321cb0ef41Sopenharmony_ci    }
14331cb0ef41Sopenharmony_ci  }
14341cb0ef41Sopenharmony_ci  pathname = SideEffectFreeRegExpPrototypeSymbolReplace(FORWARD_SLASH, pathname, '\\');
14351cb0ef41Sopenharmony_ci  pathname = decodeURIComponent(pathname);
14361cb0ef41Sopenharmony_ci  if (hostname !== '') {
14371cb0ef41Sopenharmony_ci    // If hostname is set, then we have a UNC path
14381cb0ef41Sopenharmony_ci    // Pass the hostname through domainToUnicode just in case
14391cb0ef41Sopenharmony_ci    // it is an IDN using punycode encoding. We do not need to worry
14401cb0ef41Sopenharmony_ci    // about percent encoding because the URL parser will have
14411cb0ef41Sopenharmony_ci    // already taken care of that for us. Note that this only
14421cb0ef41Sopenharmony_ci    // causes IDNs with an appropriate `xn--` prefix to be decoded.
14431cb0ef41Sopenharmony_ci    return `\\\\${domainToUnicode(hostname)}${pathname}`;
14441cb0ef41Sopenharmony_ci  }
14451cb0ef41Sopenharmony_ci  // Otherwise, it's a local path that requires a drive letter
14461cb0ef41Sopenharmony_ci  const letter = StringPrototypeCodePointAt(pathname, 1) | 0x20;
14471cb0ef41Sopenharmony_ci  const sep = StringPrototypeCharAt(pathname, 2);
14481cb0ef41Sopenharmony_ci  if (letter < CHAR_LOWERCASE_A || letter > CHAR_LOWERCASE_Z ||   // a..z A..Z
14491cb0ef41Sopenharmony_ci      (sep !== ':')) {
14501cb0ef41Sopenharmony_ci    throw new ERR_INVALID_FILE_URL_PATH('must be absolute');
14511cb0ef41Sopenharmony_ci  }
14521cb0ef41Sopenharmony_ci  return StringPrototypeSlice(pathname, 1);
14531cb0ef41Sopenharmony_ci}
14541cb0ef41Sopenharmony_ci
14551cb0ef41Sopenharmony_cifunction getPathFromURLPosix(url) {
14561cb0ef41Sopenharmony_ci  if (url.hostname !== '') {
14571cb0ef41Sopenharmony_ci    throw new ERR_INVALID_FILE_URL_HOST(platform);
14581cb0ef41Sopenharmony_ci  }
14591cb0ef41Sopenharmony_ci  const pathname = url.pathname;
14601cb0ef41Sopenharmony_ci  for (let n = 0; n < pathname.length; n++) {
14611cb0ef41Sopenharmony_ci    if (pathname[n] === '%') {
14621cb0ef41Sopenharmony_ci      const third = StringPrototypeCodePointAt(pathname, n + 2) | 0x20;
14631cb0ef41Sopenharmony_ci      if (pathname[n + 1] === '2' && third === 102) {
14641cb0ef41Sopenharmony_ci        throw new ERR_INVALID_FILE_URL_PATH(
14651cb0ef41Sopenharmony_ci          'must not include encoded / characters',
14661cb0ef41Sopenharmony_ci        );
14671cb0ef41Sopenharmony_ci      }
14681cb0ef41Sopenharmony_ci    }
14691cb0ef41Sopenharmony_ci  }
14701cb0ef41Sopenharmony_ci  return decodeURIComponent(pathname);
14711cb0ef41Sopenharmony_ci}
14721cb0ef41Sopenharmony_ci
14731cb0ef41Sopenharmony_cifunction fileURLToPath(path) {
14741cb0ef41Sopenharmony_ci  if (typeof path === 'string')
14751cb0ef41Sopenharmony_ci    path = new URL(path);
14761cb0ef41Sopenharmony_ci  else if (!isURL(path))
14771cb0ef41Sopenharmony_ci    throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path);
14781cb0ef41Sopenharmony_ci  if (path.protocol !== 'file:')
14791cb0ef41Sopenharmony_ci    throw new ERR_INVALID_URL_SCHEME('file');
14801cb0ef41Sopenharmony_ci  return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path);
14811cb0ef41Sopenharmony_ci}
14821cb0ef41Sopenharmony_ci
14831cb0ef41Sopenharmony_ci// The following characters are percent-encoded when converting from file path
14841cb0ef41Sopenharmony_ci// to URL:
14851cb0ef41Sopenharmony_ci// - %: The percent character is the only character not encoded by the
14861cb0ef41Sopenharmony_ci//        `pathname` setter.
14871cb0ef41Sopenharmony_ci// - \: Backslash is encoded on non-windows platforms since it's a valid
14881cb0ef41Sopenharmony_ci//      character but the `pathname` setters replaces it by a forward slash.
14891cb0ef41Sopenharmony_ci// - LF: The newline character is stripped out by the `pathname` setter.
14901cb0ef41Sopenharmony_ci//       (See whatwg/url#419)
14911cb0ef41Sopenharmony_ci// - CR: The carriage return character is also stripped out by the `pathname`
14921cb0ef41Sopenharmony_ci//       setter.
14931cb0ef41Sopenharmony_ci// - TAB: The tab character is also stripped out by the `pathname` setter.
14941cb0ef41Sopenharmony_ciconst percentRegEx = /%/g;
14951cb0ef41Sopenharmony_ciconst backslashRegEx = /\\/g;
14961cb0ef41Sopenharmony_ciconst newlineRegEx = /\n/g;
14971cb0ef41Sopenharmony_ciconst carriageReturnRegEx = /\r/g;
14981cb0ef41Sopenharmony_ciconst tabRegEx = /\t/g;
14991cb0ef41Sopenharmony_ciconst questionRegex = /\?/g;
15001cb0ef41Sopenharmony_ciconst hashRegex = /#/g;
15011cb0ef41Sopenharmony_ci
15021cb0ef41Sopenharmony_cifunction encodePathChars(filepath) {
15031cb0ef41Sopenharmony_ci  if (StringPrototypeIndexOf(filepath, '%') !== -1)
15041cb0ef41Sopenharmony_ci    filepath = RegExpPrototypeSymbolReplace(percentRegEx, filepath, '%25');
15051cb0ef41Sopenharmony_ci  // In posix, backslash is a valid character in paths:
15061cb0ef41Sopenharmony_ci  if (!isWindows && StringPrototypeIndexOf(filepath, '\\') !== -1)
15071cb0ef41Sopenharmony_ci    filepath = RegExpPrototypeSymbolReplace(backslashRegEx, filepath, '%5C');
15081cb0ef41Sopenharmony_ci  if (StringPrototypeIndexOf(filepath, '\n') !== -1)
15091cb0ef41Sopenharmony_ci    filepath = RegExpPrototypeSymbolReplace(newlineRegEx, filepath, '%0A');
15101cb0ef41Sopenharmony_ci  if (StringPrototypeIndexOf(filepath, '\r') !== -1)
15111cb0ef41Sopenharmony_ci    filepath = RegExpPrototypeSymbolReplace(carriageReturnRegEx, filepath, '%0D');
15121cb0ef41Sopenharmony_ci  if (StringPrototypeIndexOf(filepath, '\t') !== -1)
15131cb0ef41Sopenharmony_ci    filepath = RegExpPrototypeSymbolReplace(tabRegEx, filepath, '%09');
15141cb0ef41Sopenharmony_ci  return filepath;
15151cb0ef41Sopenharmony_ci}
15161cb0ef41Sopenharmony_ci
15171cb0ef41Sopenharmony_cifunction pathToFileURL(filepath) {
15181cb0ef41Sopenharmony_ci  if (isWindows && StringPrototypeStartsWith(filepath, '\\\\')) {
15191cb0ef41Sopenharmony_ci    const outURL = new URL('file://');
15201cb0ef41Sopenharmony_ci    // UNC path format: \\server\share\resource
15211cb0ef41Sopenharmony_ci    const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', 2);
15221cb0ef41Sopenharmony_ci    if (hostnameEndIndex === -1) {
15231cb0ef41Sopenharmony_ci      throw new ERR_INVALID_ARG_VALUE(
15241cb0ef41Sopenharmony_ci        'path',
15251cb0ef41Sopenharmony_ci        filepath,
15261cb0ef41Sopenharmony_ci        'Missing UNC resource path',
15271cb0ef41Sopenharmony_ci      );
15281cb0ef41Sopenharmony_ci    }
15291cb0ef41Sopenharmony_ci    if (hostnameEndIndex === 2) {
15301cb0ef41Sopenharmony_ci      throw new ERR_INVALID_ARG_VALUE(
15311cb0ef41Sopenharmony_ci        'path',
15321cb0ef41Sopenharmony_ci        filepath,
15331cb0ef41Sopenharmony_ci        'Empty UNC servername',
15341cb0ef41Sopenharmony_ci      );
15351cb0ef41Sopenharmony_ci    }
15361cb0ef41Sopenharmony_ci    const hostname = StringPrototypeSlice(filepath, 2, hostnameEndIndex);
15371cb0ef41Sopenharmony_ci    outURL.hostname = domainToASCII(hostname);
15381cb0ef41Sopenharmony_ci    outURL.pathname = encodePathChars(
15391cb0ef41Sopenharmony_ci      RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/'));
15401cb0ef41Sopenharmony_ci    return outURL;
15411cb0ef41Sopenharmony_ci  }
15421cb0ef41Sopenharmony_ci  let resolved = path.resolve(filepath);
15431cb0ef41Sopenharmony_ci  // path.resolve strips trailing slashes so we must add them back
15441cb0ef41Sopenharmony_ci  const filePathLast = StringPrototypeCharCodeAt(filepath,
15451cb0ef41Sopenharmony_ci                                                 filepath.length - 1);
15461cb0ef41Sopenharmony_ci  if ((filePathLast === CHAR_FORWARD_SLASH ||
15471cb0ef41Sopenharmony_ci       (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) &&
15481cb0ef41Sopenharmony_ci      resolved[resolved.length - 1] !== path.sep)
15491cb0ef41Sopenharmony_ci    resolved += '/';
15501cb0ef41Sopenharmony_ci
15511cb0ef41Sopenharmony_ci  // Call encodePathChars first to avoid encoding % again for ? and #.
15521cb0ef41Sopenharmony_ci  resolved = encodePathChars(resolved);
15531cb0ef41Sopenharmony_ci
15541cb0ef41Sopenharmony_ci  // Question and hash character should be included in pathname.
15551cb0ef41Sopenharmony_ci  // Therefore, encoding is required to eliminate parsing them in different states.
15561cb0ef41Sopenharmony_ci  // This is done as an optimization to not creating a URL instance and
15571cb0ef41Sopenharmony_ci  // later triggering pathname setter, which impacts performance
15581cb0ef41Sopenharmony_ci  if (StringPrototypeIndexOf(resolved, '?') !== -1)
15591cb0ef41Sopenharmony_ci    resolved = RegExpPrototypeSymbolReplace(questionRegex, resolved, '%3F');
15601cb0ef41Sopenharmony_ci  if (StringPrototypeIndexOf(resolved, '#') !== -1)
15611cb0ef41Sopenharmony_ci    resolved = RegExpPrototypeSymbolReplace(hashRegex, resolved, '%23');
15621cb0ef41Sopenharmony_ci  return new URL(`file://${resolved}`);
15631cb0ef41Sopenharmony_ci}
15641cb0ef41Sopenharmony_ci
15651cb0ef41Sopenharmony_cifunction toPathIfFileURL(fileURLOrPath) {
15661cb0ef41Sopenharmony_ci  if (!isURL(fileURLOrPath))
15671cb0ef41Sopenharmony_ci    return fileURLOrPath;
15681cb0ef41Sopenharmony_ci  return fileURLToPath(fileURLOrPath);
15691cb0ef41Sopenharmony_ci}
15701cb0ef41Sopenharmony_ci
15711cb0ef41Sopenharmony_cimodule.exports = {
15721cb0ef41Sopenharmony_ci  toUSVString,
15731cb0ef41Sopenharmony_ci  fileURLToPath,
15741cb0ef41Sopenharmony_ci  pathToFileURL,
15751cb0ef41Sopenharmony_ci  toPathIfFileURL,
15761cb0ef41Sopenharmony_ci  URL,
15771cb0ef41Sopenharmony_ci  URLSearchParams,
15781cb0ef41Sopenharmony_ci  domainToASCII,
15791cb0ef41Sopenharmony_ci  domainToUnicode,
15801cb0ef41Sopenharmony_ci  urlToHttpOptions,
15811cb0ef41Sopenharmony_ci  encodeStr,
15821cb0ef41Sopenharmony_ci  isURL,
15831cb0ef41Sopenharmony_ci
15841cb0ef41Sopenharmony_ci  urlUpdateActions: updateActions,
15851cb0ef41Sopenharmony_ci  unsafeProtocol,
15861cb0ef41Sopenharmony_ci  hostlessProtocol,
15871cb0ef41Sopenharmony_ci  slashedProtocol,
15881cb0ef41Sopenharmony_ci};
1589