11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst {
41cb0ef41Sopenharmony_ci  FunctionPrototypeCall,
51cb0ef41Sopenharmony_ci  ObjectDefineProperty,
61cb0ef41Sopenharmony_ci  RegExpPrototypeExec,
71cb0ef41Sopenharmony_ci  SafeMap,
81cb0ef41Sopenharmony_ci  SafeStringPrototypeSearch,
91cb0ef41Sopenharmony_ci  StringPrototypeCharAt,
101cb0ef41Sopenharmony_ci  StringPrototypeIndexOf,
111cb0ef41Sopenharmony_ci  StringPrototypeSlice,
121cb0ef41Sopenharmony_ci  StringPrototypeToLowerCase,
131cb0ef41Sopenharmony_ci  SymbolIterator,
141cb0ef41Sopenharmony_ci} = primordials;
151cb0ef41Sopenharmony_ciconst {
161cb0ef41Sopenharmony_ci  ERR_INVALID_MIME_SYNTAX,
171cb0ef41Sopenharmony_ci} = require('internal/errors').codes;
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciconst NOT_HTTP_TOKEN_CODE_POINT = /[^!#$%&'*+\-.^_`|~A-Za-z0-9]/g;
201cb0ef41Sopenharmony_ciconst NOT_HTTP_QUOTED_STRING_CODE_POINT = /[^\t\u0020-~\u0080-\u00FF]/g;
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ciconst END_BEGINNING_WHITESPACE = /[^\r\n\t ]|$/;
231cb0ef41Sopenharmony_ciconst START_ENDING_WHITESPACE = /[\r\n\t ]*$/;
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_cifunction toASCIILower(str) {
261cb0ef41Sopenharmony_ci  let result = '';
271cb0ef41Sopenharmony_ci  for (let i = 0; i < str.length; i++) {
281cb0ef41Sopenharmony_ci    const char = str[i];
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci    result += char >= 'A' && char <= 'Z' ?
311cb0ef41Sopenharmony_ci      StringPrototypeToLowerCase(char) :
321cb0ef41Sopenharmony_ci      char;
331cb0ef41Sopenharmony_ci  }
341cb0ef41Sopenharmony_ci  return result;
351cb0ef41Sopenharmony_ci}
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ciconst SOLIDUS = '/';
381cb0ef41Sopenharmony_ciconst SEMICOLON = ';';
391cb0ef41Sopenharmony_cifunction parseTypeAndSubtype(str) {
401cb0ef41Sopenharmony_ci  // Skip only HTTP whitespace from start
411cb0ef41Sopenharmony_ci  let position = SafeStringPrototypeSearch(str, END_BEGINNING_WHITESPACE);
421cb0ef41Sopenharmony_ci  // read until '/'
431cb0ef41Sopenharmony_ci  const typeEnd = StringPrototypeIndexOf(str, SOLIDUS, position);
441cb0ef41Sopenharmony_ci  const trimmedType = typeEnd === -1 ?
451cb0ef41Sopenharmony_ci    StringPrototypeSlice(str, position) :
461cb0ef41Sopenharmony_ci    StringPrototypeSlice(str, position, typeEnd);
471cb0ef41Sopenharmony_ci  const invalidTypeIndex = SafeStringPrototypeSearch(trimmedType,
481cb0ef41Sopenharmony_ci                                                     NOT_HTTP_TOKEN_CODE_POINT);
491cb0ef41Sopenharmony_ci  if (trimmedType === '' || invalidTypeIndex !== -1 || typeEnd === -1) {
501cb0ef41Sopenharmony_ci    throw new ERR_INVALID_MIME_SYNTAX('type', str, invalidTypeIndex);
511cb0ef41Sopenharmony_ci  }
521cb0ef41Sopenharmony_ci  // skip type and '/'
531cb0ef41Sopenharmony_ci  position = typeEnd + 1;
541cb0ef41Sopenharmony_ci  const type = toASCIILower(trimmedType);
551cb0ef41Sopenharmony_ci  // read until ';'
561cb0ef41Sopenharmony_ci  const subtypeEnd = StringPrototypeIndexOf(str, SEMICOLON, position);
571cb0ef41Sopenharmony_ci  const rawSubtype = subtypeEnd === -1 ?
581cb0ef41Sopenharmony_ci    StringPrototypeSlice(str, position) :
591cb0ef41Sopenharmony_ci    StringPrototypeSlice(str, position, subtypeEnd);
601cb0ef41Sopenharmony_ci  position += rawSubtype.length;
611cb0ef41Sopenharmony_ci  if (subtypeEnd !== -1) {
621cb0ef41Sopenharmony_ci    // skip ';'
631cb0ef41Sopenharmony_ci    position += 1;
641cb0ef41Sopenharmony_ci  }
651cb0ef41Sopenharmony_ci  const trimmedSubtype = StringPrototypeSlice(
661cb0ef41Sopenharmony_ci    rawSubtype,
671cb0ef41Sopenharmony_ci    0,
681cb0ef41Sopenharmony_ci    SafeStringPrototypeSearch(rawSubtype, START_ENDING_WHITESPACE));
691cb0ef41Sopenharmony_ci  const invalidSubtypeIndex = SafeStringPrototypeSearch(trimmedSubtype,
701cb0ef41Sopenharmony_ci                                                        NOT_HTTP_TOKEN_CODE_POINT);
711cb0ef41Sopenharmony_ci  if (trimmedSubtype === '' || invalidSubtypeIndex !== -1) {
721cb0ef41Sopenharmony_ci    throw new ERR_INVALID_MIME_SYNTAX('subtype', str, trimmedSubtype);
731cb0ef41Sopenharmony_ci  }
741cb0ef41Sopenharmony_ci  const subtype = toASCIILower(trimmedSubtype);
751cb0ef41Sopenharmony_ci  return {
761cb0ef41Sopenharmony_ci    __proto__: null,
771cb0ef41Sopenharmony_ci    type,
781cb0ef41Sopenharmony_ci    subtype,
791cb0ef41Sopenharmony_ci    parametersStringIndex: position,
801cb0ef41Sopenharmony_ci  };
811cb0ef41Sopenharmony_ci}
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ciconst EQUALS_SEMICOLON_OR_END = /[;=]|$/;
841cb0ef41Sopenharmony_ciconst QUOTED_VALUE_PATTERN = /^(?:([\\]$)|[\\][\s\S]|[^"])*(?:(")|$)/u;
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cifunction removeBackslashes(str) {
871cb0ef41Sopenharmony_ci  let ret = '';
881cb0ef41Sopenharmony_ci  // We stop at str.length - 1 because we want to look ahead one character.
891cb0ef41Sopenharmony_ci  let i;
901cb0ef41Sopenharmony_ci  for (i = 0; i < str.length - 1; i++) {
911cb0ef41Sopenharmony_ci    const c = str[i];
921cb0ef41Sopenharmony_ci    if (c === '\\') {
931cb0ef41Sopenharmony_ci      i++;
941cb0ef41Sopenharmony_ci      ret += str[i];
951cb0ef41Sopenharmony_ci    } else {
961cb0ef41Sopenharmony_ci      ret += c;
971cb0ef41Sopenharmony_ci    }
981cb0ef41Sopenharmony_ci  }
991cb0ef41Sopenharmony_ci  // We add the last character if we didn't skip to it.
1001cb0ef41Sopenharmony_ci  if (i === str.length - 1) {
1011cb0ef41Sopenharmony_ci    ret += str[i];
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci  return ret;
1041cb0ef41Sopenharmony_ci}
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_cifunction escapeQuoteOrSolidus(str) {
1081cb0ef41Sopenharmony_ci  let result = '';
1091cb0ef41Sopenharmony_ci  for (let i = 0; i < str.length; i++) {
1101cb0ef41Sopenharmony_ci    const char = str[i];
1111cb0ef41Sopenharmony_ci    result += (char === '"' || char === '\\') ? `\\${char}` : char;
1121cb0ef41Sopenharmony_ci  }
1131cb0ef41Sopenharmony_ci  return result;
1141cb0ef41Sopenharmony_ci}
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ciconst encode = (value) => {
1171cb0ef41Sopenharmony_ci  if (value.length === 0) return '""';
1181cb0ef41Sopenharmony_ci  const encode = SafeStringPrototypeSearch(value, NOT_HTTP_TOKEN_CODE_POINT) !== -1;
1191cb0ef41Sopenharmony_ci  if (!encode) return value;
1201cb0ef41Sopenharmony_ci  const escaped = escapeQuoteOrSolidus(value);
1211cb0ef41Sopenharmony_ci  return `"${escaped}"`;
1221cb0ef41Sopenharmony_ci};
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ciclass MIMEParams {
1251cb0ef41Sopenharmony_ci  #data = new SafeMap();
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  delete(name) {
1281cb0ef41Sopenharmony_ci    this.#data.delete(name);
1291cb0ef41Sopenharmony_ci  }
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  get(name) {
1321cb0ef41Sopenharmony_ci    const data = this.#data;
1331cb0ef41Sopenharmony_ci    if (data.has(name)) {
1341cb0ef41Sopenharmony_ci      return data.get(name);
1351cb0ef41Sopenharmony_ci    }
1361cb0ef41Sopenharmony_ci    return null;
1371cb0ef41Sopenharmony_ci  }
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci  has(name) {
1401cb0ef41Sopenharmony_ci    return this.#data.has(name);
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  set(name, value) {
1441cb0ef41Sopenharmony_ci    const data = this.#data;
1451cb0ef41Sopenharmony_ci    name = `${name}`;
1461cb0ef41Sopenharmony_ci    value = `${value}`;
1471cb0ef41Sopenharmony_ci    const invalidNameIndex = SafeStringPrototypeSearch(name, NOT_HTTP_TOKEN_CODE_POINT);
1481cb0ef41Sopenharmony_ci    if (name.length === 0 || invalidNameIndex !== -1) {
1491cb0ef41Sopenharmony_ci      throw new ERR_INVALID_MIME_SYNTAX(
1501cb0ef41Sopenharmony_ci        'parameter name',
1511cb0ef41Sopenharmony_ci        name,
1521cb0ef41Sopenharmony_ci        invalidNameIndex,
1531cb0ef41Sopenharmony_ci      );
1541cb0ef41Sopenharmony_ci    }
1551cb0ef41Sopenharmony_ci    const invalidValueIndex = SafeStringPrototypeSearch(
1561cb0ef41Sopenharmony_ci      value,
1571cb0ef41Sopenharmony_ci      NOT_HTTP_QUOTED_STRING_CODE_POINT);
1581cb0ef41Sopenharmony_ci    if (invalidValueIndex !== -1) {
1591cb0ef41Sopenharmony_ci      throw new ERR_INVALID_MIME_SYNTAX(
1601cb0ef41Sopenharmony_ci        'parameter value',
1611cb0ef41Sopenharmony_ci        value,
1621cb0ef41Sopenharmony_ci        invalidValueIndex,
1631cb0ef41Sopenharmony_ci      );
1641cb0ef41Sopenharmony_ci    }
1651cb0ef41Sopenharmony_ci    data.set(name, value);
1661cb0ef41Sopenharmony_ci  }
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  *entries() {
1691cb0ef41Sopenharmony_ci    yield* this.#data.entries();
1701cb0ef41Sopenharmony_ci  }
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  *keys() {
1731cb0ef41Sopenharmony_ci    yield* this.#data.keys();
1741cb0ef41Sopenharmony_ci  }
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci  *values() {
1771cb0ef41Sopenharmony_ci    yield* this.#data.values();
1781cb0ef41Sopenharmony_ci  }
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci  toString() {
1811cb0ef41Sopenharmony_ci    let ret = '';
1821cb0ef41Sopenharmony_ci    for (const { 0: key, 1: value } of this.#data) {
1831cb0ef41Sopenharmony_ci      const encoded = encode(value);
1841cb0ef41Sopenharmony_ci      // Ensure they are separated
1851cb0ef41Sopenharmony_ci      if (ret.length) ret += ';';
1861cb0ef41Sopenharmony_ci      ret += `${key}=${encoded}`;
1871cb0ef41Sopenharmony_ci    }
1881cb0ef41Sopenharmony_ci    return ret;
1891cb0ef41Sopenharmony_ci  }
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ci  // Used to act as a friendly class to stringifying stuff
1921cb0ef41Sopenharmony_ci  // not meant to be exposed to users, could inject invalid values
1931cb0ef41Sopenharmony_ci  static parseParametersString(str, position, params) {
1941cb0ef41Sopenharmony_ci    const paramsMap = params.#data;
1951cb0ef41Sopenharmony_ci    const endOfSource = SafeStringPrototypeSearch(
1961cb0ef41Sopenharmony_ci      StringPrototypeSlice(str, position),
1971cb0ef41Sopenharmony_ci      START_ENDING_WHITESPACE,
1981cb0ef41Sopenharmony_ci    ) + position;
1991cb0ef41Sopenharmony_ci    while (position < endOfSource) {
2001cb0ef41Sopenharmony_ci      // Skip any whitespace before parameter
2011cb0ef41Sopenharmony_ci      position += SafeStringPrototypeSearch(
2021cb0ef41Sopenharmony_ci        StringPrototypeSlice(str, position),
2031cb0ef41Sopenharmony_ci        END_BEGINNING_WHITESPACE,
2041cb0ef41Sopenharmony_ci      );
2051cb0ef41Sopenharmony_ci      // Read until ';' or '='
2061cb0ef41Sopenharmony_ci      const afterParameterName = SafeStringPrototypeSearch(
2071cb0ef41Sopenharmony_ci        StringPrototypeSlice(str, position),
2081cb0ef41Sopenharmony_ci        EQUALS_SEMICOLON_OR_END,
2091cb0ef41Sopenharmony_ci      ) + position;
2101cb0ef41Sopenharmony_ci      const parameterString = toASCIILower(
2111cb0ef41Sopenharmony_ci        StringPrototypeSlice(str, position, afterParameterName),
2121cb0ef41Sopenharmony_ci      );
2131cb0ef41Sopenharmony_ci      position = afterParameterName;
2141cb0ef41Sopenharmony_ci      // If we found a terminating character
2151cb0ef41Sopenharmony_ci      if (position < endOfSource) {
2161cb0ef41Sopenharmony_ci        // Safe to use because we never do special actions for surrogate pairs
2171cb0ef41Sopenharmony_ci        const char = StringPrototypeCharAt(str, position);
2181cb0ef41Sopenharmony_ci        // Skip the terminating character
2191cb0ef41Sopenharmony_ci        position += 1;
2201cb0ef41Sopenharmony_ci        // Ignore parameters without values
2211cb0ef41Sopenharmony_ci        if (char === ';') {
2221cb0ef41Sopenharmony_ci          continue;
2231cb0ef41Sopenharmony_ci        }
2241cb0ef41Sopenharmony_ci      }
2251cb0ef41Sopenharmony_ci      // If we are at end of the string, it cannot have a value
2261cb0ef41Sopenharmony_ci      if (position >= endOfSource) break;
2271cb0ef41Sopenharmony_ci      // Safe to use because we never do special actions for surrogate pairs
2281cb0ef41Sopenharmony_ci      const char = StringPrototypeCharAt(str, position);
2291cb0ef41Sopenharmony_ci      let parameterValue = null;
2301cb0ef41Sopenharmony_ci      if (char === '"') {
2311cb0ef41Sopenharmony_ci        // Handle quoted-string form of values
2321cb0ef41Sopenharmony_ci        // skip '"'
2331cb0ef41Sopenharmony_ci        position += 1;
2341cb0ef41Sopenharmony_ci        // Find matching closing '"' or end of string
2351cb0ef41Sopenharmony_ci        //   use $1 to see if we terminated on unmatched '\'
2361cb0ef41Sopenharmony_ci        //   use $2 to see if we terminated on a matching '"'
2371cb0ef41Sopenharmony_ci        //   so we can skip the last char in either case
2381cb0ef41Sopenharmony_ci        const insideMatch = RegExpPrototypeExec(
2391cb0ef41Sopenharmony_ci          QUOTED_VALUE_PATTERN,
2401cb0ef41Sopenharmony_ci          StringPrototypeSlice(str, position));
2411cb0ef41Sopenharmony_ci        position += insideMatch[0].length;
2421cb0ef41Sopenharmony_ci        // Skip including last character if an unmatched '\' or '"' during
2431cb0ef41Sopenharmony_ci        // unescape
2441cb0ef41Sopenharmony_ci        const inside = insideMatch[1] || insideMatch[2] ?
2451cb0ef41Sopenharmony_ci          StringPrototypeSlice(insideMatch[0], 0, -1) :
2461cb0ef41Sopenharmony_ci          insideMatch[0];
2471cb0ef41Sopenharmony_ci        // Unescape '\' quoted characters
2481cb0ef41Sopenharmony_ci        parameterValue = removeBackslashes(inside);
2491cb0ef41Sopenharmony_ci        // If we did have an unmatched '\' add it back to the end
2501cb0ef41Sopenharmony_ci        if (insideMatch[1]) parameterValue += '\\';
2511cb0ef41Sopenharmony_ci      } else {
2521cb0ef41Sopenharmony_ci        // Handle the normal parameter value form
2531cb0ef41Sopenharmony_ci        const valueEnd = StringPrototypeIndexOf(str, SEMICOLON, position);
2541cb0ef41Sopenharmony_ci        const rawValue = valueEnd === -1 ?
2551cb0ef41Sopenharmony_ci          StringPrototypeSlice(str, position) :
2561cb0ef41Sopenharmony_ci          StringPrototypeSlice(str, position, valueEnd);
2571cb0ef41Sopenharmony_ci        position += rawValue.length;
2581cb0ef41Sopenharmony_ci        const trimmedValue = StringPrototypeSlice(
2591cb0ef41Sopenharmony_ci          rawValue,
2601cb0ef41Sopenharmony_ci          0,
2611cb0ef41Sopenharmony_ci          SafeStringPrototypeSearch(rawValue, START_ENDING_WHITESPACE),
2621cb0ef41Sopenharmony_ci        );
2631cb0ef41Sopenharmony_ci        // Ignore parameters without values
2641cb0ef41Sopenharmony_ci        if (trimmedValue === '') continue;
2651cb0ef41Sopenharmony_ci        parameterValue = trimmedValue;
2661cb0ef41Sopenharmony_ci      }
2671cb0ef41Sopenharmony_ci      if (
2681cb0ef41Sopenharmony_ci        parameterString !== '' &&
2691cb0ef41Sopenharmony_ci        SafeStringPrototypeSearch(parameterString,
2701cb0ef41Sopenharmony_ci                                  NOT_HTTP_TOKEN_CODE_POINT) === -1 &&
2711cb0ef41Sopenharmony_ci        SafeStringPrototypeSearch(parameterValue,
2721cb0ef41Sopenharmony_ci                                  NOT_HTTP_QUOTED_STRING_CODE_POINT) === -1 &&
2731cb0ef41Sopenharmony_ci        params.has(parameterString) === false
2741cb0ef41Sopenharmony_ci      ) {
2751cb0ef41Sopenharmony_ci        paramsMap.set(parameterString, parameterValue);
2761cb0ef41Sopenharmony_ci      }
2771cb0ef41Sopenharmony_ci      position++;
2781cb0ef41Sopenharmony_ci    }
2791cb0ef41Sopenharmony_ci    return paramsMap;
2801cb0ef41Sopenharmony_ci  }
2811cb0ef41Sopenharmony_ci}
2821cb0ef41Sopenharmony_ciconst MIMEParamsStringify = MIMEParams.prototype.toString;
2831cb0ef41Sopenharmony_ciObjectDefineProperty(MIMEParams.prototype, SymbolIterator, {
2841cb0ef41Sopenharmony_ci  __proto__: null,
2851cb0ef41Sopenharmony_ci  configurable: true,
2861cb0ef41Sopenharmony_ci  value: MIMEParams.prototype.entries,
2871cb0ef41Sopenharmony_ci  writable: true,
2881cb0ef41Sopenharmony_ci});
2891cb0ef41Sopenharmony_ciObjectDefineProperty(MIMEParams.prototype, 'toJSON', {
2901cb0ef41Sopenharmony_ci  __proto__: null,
2911cb0ef41Sopenharmony_ci  configurable: true,
2921cb0ef41Sopenharmony_ci  value: MIMEParamsStringify,
2931cb0ef41Sopenharmony_ci  writable: true,
2941cb0ef41Sopenharmony_ci});
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ciconst { parseParametersString } = MIMEParams;
2971cb0ef41Sopenharmony_cidelete MIMEParams.parseParametersString;
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ciclass MIMEType {
3001cb0ef41Sopenharmony_ci  #type;
3011cb0ef41Sopenharmony_ci  #subtype;
3021cb0ef41Sopenharmony_ci  #parameters;
3031cb0ef41Sopenharmony_ci  constructor(string) {
3041cb0ef41Sopenharmony_ci    string = `${string}`;
3051cb0ef41Sopenharmony_ci    const data = parseTypeAndSubtype(string);
3061cb0ef41Sopenharmony_ci    this.#type = data.type;
3071cb0ef41Sopenharmony_ci    this.#subtype = data.subtype;
3081cb0ef41Sopenharmony_ci    this.#parameters = new MIMEParams();
3091cb0ef41Sopenharmony_ci    parseParametersString(
3101cb0ef41Sopenharmony_ci      string,
3111cb0ef41Sopenharmony_ci      data.parametersStringIndex,
3121cb0ef41Sopenharmony_ci      this.#parameters,
3131cb0ef41Sopenharmony_ci    );
3141cb0ef41Sopenharmony_ci  }
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci  get type() {
3171cb0ef41Sopenharmony_ci    return this.#type;
3181cb0ef41Sopenharmony_ci  }
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci  set type(v) {
3211cb0ef41Sopenharmony_ci    v = `${v}`;
3221cb0ef41Sopenharmony_ci    const invalidTypeIndex = SafeStringPrototypeSearch(v, NOT_HTTP_TOKEN_CODE_POINT);
3231cb0ef41Sopenharmony_ci    if (v.length === 0 || invalidTypeIndex !== -1) {
3241cb0ef41Sopenharmony_ci      throw new ERR_INVALID_MIME_SYNTAX('type', v, invalidTypeIndex);
3251cb0ef41Sopenharmony_ci    }
3261cb0ef41Sopenharmony_ci    this.#type = toASCIILower(v);
3271cb0ef41Sopenharmony_ci  }
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci  get subtype() {
3301cb0ef41Sopenharmony_ci    return this.#subtype;
3311cb0ef41Sopenharmony_ci  }
3321cb0ef41Sopenharmony_ci
3331cb0ef41Sopenharmony_ci  set subtype(v) {
3341cb0ef41Sopenharmony_ci    v = `${v}`;
3351cb0ef41Sopenharmony_ci    const invalidSubtypeIndex = SafeStringPrototypeSearch(v, NOT_HTTP_TOKEN_CODE_POINT);
3361cb0ef41Sopenharmony_ci    if (v.length === 0 || invalidSubtypeIndex !== -1) {
3371cb0ef41Sopenharmony_ci      throw new ERR_INVALID_MIME_SYNTAX('subtype', v, invalidSubtypeIndex);
3381cb0ef41Sopenharmony_ci    }
3391cb0ef41Sopenharmony_ci    this.#subtype = toASCIILower(v);
3401cb0ef41Sopenharmony_ci  }
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ci  get essence() {
3431cb0ef41Sopenharmony_ci    return `${this.#type}/${this.#subtype}`;
3441cb0ef41Sopenharmony_ci  }
3451cb0ef41Sopenharmony_ci
3461cb0ef41Sopenharmony_ci  get params() {
3471cb0ef41Sopenharmony_ci    return this.#parameters;
3481cb0ef41Sopenharmony_ci  }
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ci  toString() {
3511cb0ef41Sopenharmony_ci    let ret = `${this.#type}/${this.#subtype}`;
3521cb0ef41Sopenharmony_ci    const paramStr = FunctionPrototypeCall(MIMEParamsStringify, this.#parameters);
3531cb0ef41Sopenharmony_ci    if (paramStr.length) ret += `;${paramStr}`;
3541cb0ef41Sopenharmony_ci    return ret;
3551cb0ef41Sopenharmony_ci  }
3561cb0ef41Sopenharmony_ci}
3571cb0ef41Sopenharmony_ciObjectDefineProperty(MIMEType.prototype, 'toJSON', {
3581cb0ef41Sopenharmony_ci  __proto__: null,
3591cb0ef41Sopenharmony_ci  configurable: true,
3601cb0ef41Sopenharmony_ci  value: MIMEType.prototype.toString,
3611cb0ef41Sopenharmony_ci  writable: true,
3621cb0ef41Sopenharmony_ci});
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_cimodule.exports = {
3651cb0ef41Sopenharmony_ci  MIMEParams,
3661cb0ef41Sopenharmony_ci  MIMEType,
3671cb0ef41Sopenharmony_ci};
368