"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var consoleApiSource_exports = {};
__export(consoleApiSource_exports, {
  source: () => source
});
module.exports = __toCommonJS(consoleApiSource_exports);
const source = '\nvar __commonJS = obj => {\n  let required = false;\n  let result;\n  return function __require() {\n    if (!required) {\n      required = true;\n      let fn;\n      for (const name in obj) { fn = obj[name]; break; }\n      const module = { exports: {} };\n      fn(module.exports, module);\n      result = module.exports;\n    }\n    return result;\n  }\n};\nvar __export = (target, all) => {for (var name in all) target[name] = all[name];};\nvar __toESM = mod => ({ ...mod, \'default\': mod });\nvar __toCommonJS = mod => ({ ...mod, __esModule: true });\n\n\n// packages/injected/src/consoleApi.ts\nvar consoleApi_exports = {};\n__export(consoleApi_exports, {\n  default: () => consoleApi_default\n});\nmodule.exports = __toCommonJS(consoleApi_exports);\n\n// packages/playwright-core/src/utils/isomorphic/builtins.ts\nfunction builtins(global) {\n  var _a, _b, _c, _d, _e, _f, _g, _h, _i;\n  global = global != null ? global : globalThis;\n  if (!global["__playwright_builtins__"]) {\n    const builtins2 = {\n      setTimeout: (_a = global.setTimeout) == null ? void 0 : _a.bind(global),\n      clearTimeout: (_b = global.clearTimeout) == null ? void 0 : _b.bind(global),\n      setInterval: (_c = global.setInterval) == null ? void 0 : _c.bind(global),\n      clearInterval: (_d = global.clearInterval) == null ? void 0 : _d.bind(global),\n      requestAnimationFrame: (_e = global.requestAnimationFrame) == null ? void 0 : _e.bind(global),\n      cancelAnimationFrame: (_f = global.cancelAnimationFrame) == null ? void 0 : _f.bind(global),\n      requestIdleCallback: (_g = global.requestIdleCallback) == null ? void 0 : _g.bind(global),\n      cancelIdleCallback: (_h = global.cancelIdleCallback) == null ? void 0 : _h.bind(global),\n      performance: global.performance,\n      eval: (_i = global.eval) == null ? void 0 : _i.bind(global),\n      Intl: global.Intl,\n      Date: global.Date,\n      Map: global.Map,\n      Set: global.Set\n    };\n    Object.defineProperty(global, "__playwright_builtins__", { value: builtins2, configurable: false, enumerable: false, writable: false });\n  }\n  return global["__playwright_builtins__"];\n}\nvar instance = builtins();\nvar setTimeout = instance.setTimeout;\nvar clearTimeout = instance.clearTimeout;\nvar setInterval = instance.setInterval;\nvar clearInterval = instance.clearInterval;\nvar requestAnimationFrame = instance.requestAnimationFrame;\nvar cancelAnimationFrame = instance.cancelAnimationFrame;\nvar requestIdleCallback = instance.requestIdleCallback;\nvar cancelIdleCallback = instance.cancelIdleCallback;\nvar performance = instance.performance;\nvar Intl = instance.Intl;\nvar Date = instance.Date;\nvar Map = instance.Map;\nvar Set = instance.Set;\n\n// packages/playwright-core/src/utils/isomorphic/cssTokenizer.ts\nvar between = function(num, first, last) {\n  return num >= first && num <= last;\n};\nfunction digit(code) {\n  return between(code, 48, 57);\n}\nfunction hexdigit(code) {\n  return digit(code) || between(code, 65, 70) || between(code, 97, 102);\n}\nfunction uppercaseletter(code) {\n  return between(code, 65, 90);\n}\nfunction lowercaseletter(code) {\n  return between(code, 97, 122);\n}\nfunction letter(code) {\n  return uppercaseletter(code) || lowercaseletter(code);\n}\nfunction nonascii(code) {\n  return code >= 128;\n}\nfunction namestartchar(code) {\n  return letter(code) || nonascii(code) || code === 95;\n}\nfunction namechar(code) {\n  return namestartchar(code) || digit(code) || code === 45;\n}\nfunction nonprintable(code) {\n  return between(code, 0, 8) || code === 11 || between(code, 14, 31) || code === 127;\n}\nfunction newline(code) {\n  return code === 10;\n}\nfunction whitespace(code) {\n  return newline(code) || code === 9 || code === 32;\n}\nvar maximumallowedcodepoint = 1114111;\nvar InvalidCharacterError = class extends Error {\n  constructor(message) {\n    super(message);\n    this.name = "InvalidCharacterError";\n  }\n};\nfunction preprocess(str) {\n  const codepoints = [];\n  for (let i = 0; i < str.length; i++) {\n    let code = str.charCodeAt(i);\n    if (code === 13 && str.charCodeAt(i + 1) === 10) {\n      code = 10;\n      i++;\n    }\n    if (code === 13 || code === 12)\n      code = 10;\n    if (code === 0)\n      code = 65533;\n    if (between(code, 55296, 56319) && between(str.charCodeAt(i + 1), 56320, 57343)) {\n      const lead = code - 55296;\n      const trail = str.charCodeAt(i + 1) - 56320;\n      code = Math.pow(2, 16) + lead * Math.pow(2, 10) + trail;\n      i++;\n    }\n    codepoints.push(code);\n  }\n  return codepoints;\n}\nfunction stringFromCode(code) {\n  if (code <= 65535)\n    return String.fromCharCode(code);\n  code -= Math.pow(2, 16);\n  const lead = Math.floor(code / Math.pow(2, 10)) + 55296;\n  const trail = code % Math.pow(2, 10) + 56320;\n  return String.fromCharCode(lead) + String.fromCharCode(trail);\n}\nfunction tokenize(str1) {\n  const str = preprocess(str1);\n  let i = -1;\n  const tokens = [];\n  let code;\n  let line = 0;\n  let column = 0;\n  let lastLineLength = 0;\n  const incrLineno = function() {\n    line += 1;\n    lastLineLength = column;\n    column = 0;\n  };\n  const locStart = { line, column };\n  const codepoint = function(i2) {\n    if (i2 >= str.length)\n      return -1;\n    return str[i2];\n  };\n  const next = function(num) {\n    if (num === void 0)\n      num = 1;\n    if (num > 3)\n      throw "Spec Error: no more than three codepoints of lookahead.";\n    return codepoint(i + num);\n  };\n  const consume = function(num) {\n    if (num === void 0)\n      num = 1;\n    i += num;\n    code = codepoint(i);\n    if (newline(code))\n      incrLineno();\n    else\n      column += num;\n    return true;\n  };\n  const reconsume = function() {\n    i -= 1;\n    if (newline(code)) {\n      line -= 1;\n      column = lastLineLength;\n    } else {\n      column -= 1;\n    }\n    locStart.line = line;\n    locStart.column = column;\n    return true;\n  };\n  const eof = function(codepoint2) {\n    if (codepoint2 === void 0)\n      codepoint2 = code;\n    return codepoint2 === -1;\n  };\n  const donothing = function() {\n  };\n  const parseerror = function() {\n  };\n  const consumeAToken = function() {\n    consumeComments();\n    consume();\n    if (whitespace(code)) {\n      while (whitespace(next()))\n        consume();\n      return new WhitespaceToken();\n    } else if (code === 34) {\n      return consumeAStringToken();\n    } else if (code === 35) {\n      if (namechar(next()) || areAValidEscape(next(1), next(2))) {\n        const token = new HashToken("");\n        if (wouldStartAnIdentifier(next(1), next(2), next(3)))\n          token.type = "id";\n        token.value = consumeAName();\n        return token;\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 36) {\n      if (next() === 61) {\n        consume();\n        return new SuffixMatchToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 39) {\n      return consumeAStringToken();\n    } else if (code === 40) {\n      return new OpenParenToken();\n    } else if (code === 41) {\n      return new CloseParenToken();\n    } else if (code === 42) {\n      if (next() === 61) {\n        consume();\n        return new SubstringMatchToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 43) {\n      if (startsWithANumber()) {\n        reconsume();\n        return consumeANumericToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 44) {\n      return new CommaToken();\n    } else if (code === 45) {\n      if (startsWithANumber()) {\n        reconsume();\n        return consumeANumericToken();\n      } else if (next(1) === 45 && next(2) === 62) {\n        consume(2);\n        return new CDCToken();\n      } else if (startsWithAnIdentifier()) {\n        reconsume();\n        return consumeAnIdentlikeToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 46) {\n      if (startsWithANumber()) {\n        reconsume();\n        return consumeANumericToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 58) {\n      return new ColonToken();\n    } else if (code === 59) {\n      return new SemicolonToken();\n    } else if (code === 60) {\n      if (next(1) === 33 && next(2) === 45 && next(3) === 45) {\n        consume(3);\n        return new CDOToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 64) {\n      if (wouldStartAnIdentifier(next(1), next(2), next(3)))\n        return new AtKeywordToken(consumeAName());\n      else\n        return new DelimToken(code);\n    } else if (code === 91) {\n      return new OpenSquareToken();\n    } else if (code === 92) {\n      if (startsWithAValidEscape()) {\n        reconsume();\n        return consumeAnIdentlikeToken();\n      } else {\n        parseerror();\n        return new DelimToken(code);\n      }\n    } else if (code === 93) {\n      return new CloseSquareToken();\n    } else if (code === 94) {\n      if (next() === 61) {\n        consume();\n        return new PrefixMatchToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 123) {\n      return new OpenCurlyToken();\n    } else if (code === 124) {\n      if (next() === 61) {\n        consume();\n        return new DashMatchToken();\n      } else if (next() === 124) {\n        consume();\n        return new ColumnToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (code === 125) {\n      return new CloseCurlyToken();\n    } else if (code === 126) {\n      if (next() === 61) {\n        consume();\n        return new IncludeMatchToken();\n      } else {\n        return new DelimToken(code);\n      }\n    } else if (digit(code)) {\n      reconsume();\n      return consumeANumericToken();\n    } else if (namestartchar(code)) {\n      reconsume();\n      return consumeAnIdentlikeToken();\n    } else if (eof()) {\n      return new EOFToken();\n    } else {\n      return new DelimToken(code);\n    }\n  };\n  const consumeComments = function() {\n    while (next(1) === 47 && next(2) === 42) {\n      consume(2);\n      while (true) {\n        consume();\n        if (code === 42 && next() === 47) {\n          consume();\n          break;\n        } else if (eof()) {\n          parseerror();\n          return;\n        }\n      }\n    }\n  };\n  const consumeANumericToken = function() {\n    const num = consumeANumber();\n    if (wouldStartAnIdentifier(next(1), next(2), next(3))) {\n      const token = new DimensionToken();\n      token.value = num.value;\n      token.repr = num.repr;\n      token.type = num.type;\n      token.unit = consumeAName();\n      return token;\n    } else if (next() === 37) {\n      consume();\n      const token = new PercentageToken();\n      token.value = num.value;\n      token.repr = num.repr;\n      return token;\n    } else {\n      const token = new NumberToken();\n      token.value = num.value;\n      token.repr = num.repr;\n      token.type = num.type;\n      return token;\n    }\n  };\n  const consumeAnIdentlikeToken = function() {\n    const str2 = consumeAName();\n    if (str2.toLowerCase() === "url" && next() === 40) {\n      consume();\n      while (whitespace(next(1)) && whitespace(next(2)))\n        consume();\n      if (next() === 34 || next() === 39)\n        return new FunctionToken(str2);\n      else if (whitespace(next()) && (next(2) === 34 || next(2) === 39))\n        return new FunctionToken(str2);\n      else\n        return consumeAURLToken();\n    } else if (next() === 40) {\n      consume();\n      return new FunctionToken(str2);\n    } else {\n      return new IdentToken(str2);\n    }\n  };\n  const consumeAStringToken = function(endingCodePoint) {\n    if (endingCodePoint === void 0)\n      endingCodePoint = code;\n    let string = "";\n    while (consume()) {\n      if (code === endingCodePoint || eof()) {\n        return new StringToken(string);\n      } else if (newline(code)) {\n        parseerror();\n        reconsume();\n        return new BadStringToken();\n      } else if (code === 92) {\n        if (eof(next()))\n          donothing();\n        else if (newline(next()))\n          consume();\n        else\n          string += stringFromCode(consumeEscape());\n      } else {\n        string += stringFromCode(code);\n      }\n    }\n    throw new Error("Internal error");\n  };\n  const consumeAURLToken = function() {\n    const token = new URLToken("");\n    while (whitespace(next()))\n      consume();\n    if (eof(next()))\n      return token;\n    while (consume()) {\n      if (code === 41 || eof()) {\n        return token;\n      } else if (whitespace(code)) {\n        while (whitespace(next()))\n          consume();\n        if (next() === 41 || eof(next())) {\n          consume();\n          return token;\n        } else {\n          consumeTheRemnantsOfABadURL();\n          return new BadURLToken();\n        }\n      } else if (code === 34 || code === 39 || code === 40 || nonprintable(code)) {\n        parseerror();\n        consumeTheRemnantsOfABadURL();\n        return new BadURLToken();\n      } else if (code === 92) {\n        if (startsWithAValidEscape()) {\n          token.value += stringFromCode(consumeEscape());\n        } else {\n          parseerror();\n          consumeTheRemnantsOfABadURL();\n          return new BadURLToken();\n        }\n      } else {\n        token.value += stringFromCode(code);\n      }\n    }\n    throw new Error("Internal error");\n  };\n  const consumeEscape = function() {\n    consume();\n    if (hexdigit(code)) {\n      const digits = [code];\n      for (let total = 0; total < 5; total++) {\n        if (hexdigit(next())) {\n          consume();\n          digits.push(code);\n        } else {\n          break;\n        }\n      }\n      if (whitespace(next()))\n        consume();\n      let value = parseInt(digits.map(function(x) {\n        return String.fromCharCode(x);\n      }).join(""), 16);\n      if (value > maximumallowedcodepoint)\n        value = 65533;\n      return value;\n    } else if (eof()) {\n      return 65533;\n    } else {\n      return code;\n    }\n  };\n  const areAValidEscape = function(c1, c2) {\n    if (c1 !== 92)\n      return false;\n    if (newline(c2))\n      return false;\n    return true;\n  };\n  const startsWithAValidEscape = function() {\n    return areAValidEscape(code, next());\n  };\n  const wouldStartAnIdentifier = function(c1, c2, c3) {\n    if (c1 === 45)\n      return namestartchar(c2) || c2 === 45 || areAValidEscape(c2, c3);\n    else if (namestartchar(c1))\n      return true;\n    else if (c1 === 92)\n      return areAValidEscape(c1, c2);\n    else\n      return false;\n  };\n  const startsWithAnIdentifier = function() {\n    return wouldStartAnIdentifier(code, next(1), next(2));\n  };\n  const wouldStartANumber = function(c1, c2, c3) {\n    if (c1 === 43 || c1 === 45) {\n      if (digit(c2))\n        return true;\n      if (c2 === 46 && digit(c3))\n        return true;\n      return false;\n    } else if (c1 === 46) {\n      if (digit(c2))\n        return true;\n      return false;\n    } else if (digit(c1)) {\n      return true;\n    } else {\n      return false;\n    }\n  };\n  const startsWithANumber = function() {\n    return wouldStartANumber(code, next(1), next(2));\n  };\n  const consumeAName = function() {\n    let result = "";\n    while (consume()) {\n      if (namechar(code)) {\n        result += stringFromCode(code);\n      } else if (startsWithAValidEscape()) {\n        result += stringFromCode(consumeEscape());\n      } else {\n        reconsume();\n        return result;\n      }\n    }\n    throw new Error("Internal parse error");\n  };\n  const consumeANumber = function() {\n    let repr = "";\n    let type = "integer";\n    if (next() === 43 || next() === 45) {\n      consume();\n      repr += stringFromCode(code);\n    }\n    while (digit(next())) {\n      consume();\n      repr += stringFromCode(code);\n    }\n    if (next(1) === 46 && digit(next(2))) {\n      consume();\n      repr += stringFromCode(code);\n      consume();\n      repr += stringFromCode(code);\n      type = "number";\n      while (digit(next())) {\n        consume();\n        repr += stringFromCode(code);\n      }\n    }\n    const c1 = next(1), c2 = next(2), c3 = next(3);\n    if ((c1 === 69 || c1 === 101) && digit(c2)) {\n      consume();\n      repr += stringFromCode(code);\n      consume();\n      repr += stringFromCode(code);\n      type = "number";\n      while (digit(next())) {\n        consume();\n        repr += stringFromCode(code);\n      }\n    } else if ((c1 === 69 || c1 === 101) && (c2 === 43 || c2 === 45) && digit(c3)) {\n      consume();\n      repr += stringFromCode(code);\n      consume();\n      repr += stringFromCode(code);\n      consume();\n      repr += stringFromCode(code);\n      type = "number";\n      while (digit(next())) {\n        consume();\n        repr += stringFromCode(code);\n      }\n    }\n    const value = convertAStringToANumber(repr);\n    return { type, value, repr };\n  };\n  const convertAStringToANumber = function(string) {\n    return +string;\n  };\n  const consumeTheRemnantsOfABadURL = function() {\n    while (consume()) {\n      if (code === 41 || eof()) {\n        return;\n      } else if (startsWithAValidEscape()) {\n        consumeEscape();\n        donothing();\n      } else {\n        donothing();\n      }\n    }\n  };\n  let iterationCount = 0;\n  while (!eof(next())) {\n    tokens.push(consumeAToken());\n    iterationCount++;\n    if (iterationCount > str.length * 2)\n      throw new Error("I\'m infinite-looping!");\n  }\n  return tokens;\n}\nvar CSSParserToken = class {\n  constructor() {\n    this.tokenType = "";\n  }\n  toJSON() {\n    return { token: this.tokenType };\n  }\n  toString() {\n    return this.tokenType;\n  }\n  toSource() {\n    return "" + this;\n  }\n};\nvar BadStringToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "BADSTRING";\n  }\n};\nvar BadURLToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "BADURL";\n  }\n};\nvar WhitespaceToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "WHITESPACE";\n  }\n  toString() {\n    return "WS";\n  }\n  toSource() {\n    return " ";\n  }\n};\nvar CDOToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "CDO";\n  }\n  toSource() {\n    return "<!--";\n  }\n};\nvar CDCToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "CDC";\n  }\n  toSource() {\n    return "-->";\n  }\n};\nvar ColonToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = ":";\n  }\n};\nvar SemicolonToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = ";";\n  }\n};\nvar CommaToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = ",";\n  }\n};\nvar GroupingToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.value = "";\n    this.mirror = "";\n  }\n};\nvar OpenCurlyToken = class extends GroupingToken {\n  constructor() {\n    super();\n    this.tokenType = "{";\n    this.value = "{";\n    this.mirror = "}";\n  }\n};\nvar CloseCurlyToken = class extends GroupingToken {\n  constructor() {\n    super();\n    this.tokenType = "}";\n    this.value = "}";\n    this.mirror = "{";\n  }\n};\nvar OpenSquareToken = class extends GroupingToken {\n  constructor() {\n    super();\n    this.tokenType = "[";\n    this.value = "[";\n    this.mirror = "]";\n  }\n};\nvar CloseSquareToken = class extends GroupingToken {\n  constructor() {\n    super();\n    this.tokenType = "]";\n    this.value = "]";\n    this.mirror = "[";\n  }\n};\nvar OpenParenToken = class extends GroupingToken {\n  constructor() {\n    super();\n    this.tokenType = "(";\n    this.value = "(";\n    this.mirror = ")";\n  }\n};\nvar CloseParenToken = class extends GroupingToken {\n  constructor() {\n    super();\n    this.tokenType = ")";\n    this.value = ")";\n    this.mirror = "(";\n  }\n};\nvar IncludeMatchToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "~=";\n  }\n};\nvar DashMatchToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "|=";\n  }\n};\nvar PrefixMatchToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "^=";\n  }\n};\nvar SuffixMatchToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "$=";\n  }\n};\nvar SubstringMatchToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "*=";\n  }\n};\nvar ColumnToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "||";\n  }\n};\nvar EOFToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.tokenType = "EOF";\n  }\n  toSource() {\n    return "";\n  }\n};\nvar DelimToken = class extends CSSParserToken {\n  constructor(code) {\n    super();\n    this.tokenType = "DELIM";\n    this.value = "";\n    this.value = stringFromCode(code);\n  }\n  toString() {\n    return "DELIM(" + this.value + ")";\n  }\n  toJSON() {\n    const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);\n    json.value = this.value;\n    return json;\n  }\n  toSource() {\n    if (this.value === "\\\\")\n      return "\\\\\\n";\n    else\n      return this.value;\n  }\n};\nvar StringValuedToken = class extends CSSParserToken {\n  constructor() {\n    super(...arguments);\n    this.value = "";\n  }\n  ASCIIMatch(str) {\n    return this.value.toLowerCase() === str.toLowerCase();\n  }\n  toJSON() {\n    const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);\n    json.value = this.value;\n    return json;\n  }\n};\nvar IdentToken = class extends StringValuedToken {\n  constructor(val) {\n    super();\n    this.tokenType = "IDENT";\n    this.value = val;\n  }\n  toString() {\n    return "IDENT(" + this.value + ")";\n  }\n  toSource() {\n    return escapeIdent(this.value);\n  }\n};\nvar FunctionToken = class extends StringValuedToken {\n  constructor(val) {\n    super();\n    this.tokenType = "FUNCTION";\n    this.value = val;\n    this.mirror = ")";\n  }\n  toString() {\n    return "FUNCTION(" + this.value + ")";\n  }\n  toSource() {\n    return escapeIdent(this.value) + "(";\n  }\n};\nvar AtKeywordToken = class extends StringValuedToken {\n  constructor(val) {\n    super();\n    this.tokenType = "AT-KEYWORD";\n    this.value = val;\n  }\n  toString() {\n    return "AT(" + this.value + ")";\n  }\n  toSource() {\n    return "@" + escapeIdent(this.value);\n  }\n};\nvar HashToken = class extends StringValuedToken {\n  constructor(val) {\n    super();\n    this.tokenType = "HASH";\n    this.value = val;\n    this.type = "unrestricted";\n  }\n  toString() {\n    return "HASH(" + this.value + ")";\n  }\n  toJSON() {\n    const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);\n    json.value = this.value;\n    json.type = this.type;\n    return json;\n  }\n  toSource() {\n    if (this.type === "id")\n      return "#" + escapeIdent(this.value);\n    else\n      return "#" + escapeHash(this.value);\n  }\n};\nvar StringToken = class extends StringValuedToken {\n  constructor(val) {\n    super();\n    this.tokenType = "STRING";\n    this.value = val;\n  }\n  toString() {\n    return \'"\' + escapeString(this.value) + \'"\';\n  }\n};\nvar URLToken = class extends StringValuedToken {\n  constructor(val) {\n    super();\n    this.tokenType = "URL";\n    this.value = val;\n  }\n  toString() {\n    return "URL(" + this.value + ")";\n  }\n  toSource() {\n    return \'url("\' + escapeString(this.value) + \'")\';\n  }\n};\nvar NumberToken = class extends CSSParserToken {\n  constructor() {\n    super();\n    this.tokenType = "NUMBER";\n    this.type = "integer";\n    this.repr = "";\n  }\n  toString() {\n    if (this.type === "integer")\n      return "INT(" + this.value + ")";\n    return "NUMBER(" + this.value + ")";\n  }\n  toJSON() {\n    const json = super.toJSON();\n    json.value = this.value;\n    json.type = this.type;\n    json.repr = this.repr;\n    return json;\n  }\n  toSource() {\n    return this.repr;\n  }\n};\nvar PercentageToken = class extends CSSParserToken {\n  constructor() {\n    super();\n    this.tokenType = "PERCENTAGE";\n    this.repr = "";\n  }\n  toString() {\n    return "PERCENTAGE(" + this.value + ")";\n  }\n  toJSON() {\n    const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);\n    json.value = this.value;\n    json.repr = this.repr;\n    return json;\n  }\n  toSource() {\n    return this.repr + "%";\n  }\n};\nvar DimensionToken = class extends CSSParserToken {\n  constructor() {\n    super();\n    this.tokenType = "DIMENSION";\n    this.type = "integer";\n    this.repr = "";\n    this.unit = "";\n  }\n  toString() {\n    return "DIM(" + this.value + "," + this.unit + ")";\n  }\n  toJSON() {\n    const json = this.constructor.prototype.constructor.prototype.toJSON.call(this);\n    json.value = this.value;\n    json.type = this.type;\n    json.repr = this.repr;\n    json.unit = this.unit;\n    return json;\n  }\n  toSource() {\n    const source = this.repr;\n    let unit = escapeIdent(this.unit);\n    if (unit[0].toLowerCase() === "e" && (unit[1] === "-" || between(unit.charCodeAt(1), 48, 57))) {\n      unit = "\\\\65 " + unit.slice(1, unit.length);\n    }\n    return source + unit;\n  }\n};\nfunction escapeIdent(string) {\n  string = "" + string;\n  let result = "";\n  const firstcode = string.charCodeAt(0);\n  for (let i = 0; i < string.length; i++) {\n    const code = string.charCodeAt(i);\n    if (code === 0)\n      throw new InvalidCharacterError("Invalid character: the input contains U+0000.");\n    if (between(code, 1, 31) || code === 127 || i === 0 && between(code, 48, 57) || i === 1 && between(code, 48, 57) && firstcode === 45)\n      result += "\\\\" + code.toString(16) + " ";\n    else if (code >= 128 || code === 45 || code === 95 || between(code, 48, 57) || between(code, 65, 90) || between(code, 97, 122))\n      result += string[i];\n    else\n      result += "\\\\" + string[i];\n  }\n  return result;\n}\nfunction escapeHash(string) {\n  string = "" + string;\n  let result = "";\n  for (let i = 0; i < string.length; i++) {\n    const code = string.charCodeAt(i);\n    if (code === 0)\n      throw new InvalidCharacterError("Invalid character: the input contains U+0000.");\n    if (code >= 128 || code === 45 || code === 95 || between(code, 48, 57) || between(code, 65, 90) || between(code, 97, 122))\n      result += string[i];\n    else\n      result += "\\\\" + code.toString(16) + " ";\n  }\n  return result;\n}\nfunction escapeString(string) {\n  string = "" + string;\n  let result = "";\n  for (let i = 0; i < string.length; i++) {\n    const code = string.charCodeAt(i);\n    if (code === 0)\n      throw new InvalidCharacterError("Invalid character: the input contains U+0000.");\n    if (between(code, 1, 31) || code === 127)\n      result += "\\\\" + code.toString(16) + " ";\n    else if (code === 34 || code === 92)\n      result += "\\\\" + string[i];\n    else\n      result += string[i];\n  }\n  return result;\n}\n\n// packages/playwright-core/src/utils/isomorphic/cssParser.ts\nvar InvalidSelectorError = class extends Error {\n};\nfunction parseCSS(selector, customNames) {\n  let tokens;\n  try {\n    tokens = tokenize(selector);\n    if (!(tokens[tokens.length - 1] instanceof EOFToken))\n      tokens.push(new EOFToken());\n  } catch (e) {\n    const newMessage = e.message + ` while parsing css selector "${selector}". Did you mean to CSS.escape it?`;\n    const index = (e.stack || "").indexOf(e.message);\n    if (index !== -1)\n      e.stack = e.stack.substring(0, index) + newMessage + e.stack.substring(index + e.message.length);\n    e.message = newMessage;\n    throw e;\n  }\n  const unsupportedToken = tokens.find((token) => {\n    return token instanceof AtKeywordToken || token instanceof BadStringToken || token instanceof BadURLToken || token instanceof ColumnToken || token instanceof CDOToken || token instanceof CDCToken || token instanceof SemicolonToken || // TODO: Consider using these for something, e.g. to escape complex strings.\n    // For example :xpath{ (//div/bar[@attr="foo"])[2]/baz }\n    // Or this way :xpath( {complex-xpath-goes-here("hello")} )\n    token instanceof OpenCurlyToken || token instanceof CloseCurlyToken || // TODO: Consider treating these as strings?\n    token instanceof URLToken || token instanceof PercentageToken;\n  });\n  if (unsupportedToken)\n    throw new InvalidSelectorError(`Unsupported token "${unsupportedToken.toSource()}" while parsing css selector "${selector}". Did you mean to CSS.escape it?`);\n  let pos = 0;\n  const names = new Set();\n  function unexpected() {\n    return new InvalidSelectorError(`Unexpected token "${tokens[pos].toSource()}" while parsing css selector "${selector}". Did you mean to CSS.escape it?`);\n  }\n  function skipWhitespace() {\n    while (tokens[pos] instanceof WhitespaceToken)\n      pos++;\n  }\n  function isIdent(p = pos) {\n    return tokens[p] instanceof IdentToken;\n  }\n  function isString(p = pos) {\n    return tokens[p] instanceof StringToken;\n  }\n  function isNumber(p = pos) {\n    return tokens[p] instanceof NumberToken;\n  }\n  function isComma(p = pos) {\n    return tokens[p] instanceof CommaToken;\n  }\n  function isOpenParen(p = pos) {\n    return tokens[p] instanceof OpenParenToken;\n  }\n  function isCloseParen(p = pos) {\n    return tokens[p] instanceof CloseParenToken;\n  }\n  function isFunction(p = pos) {\n    return tokens[p] instanceof FunctionToken;\n  }\n  function isStar(p = pos) {\n    return tokens[p] instanceof DelimToken && tokens[p].value === "*";\n  }\n  function isEOF(p = pos) {\n    return tokens[p] instanceof EOFToken;\n  }\n  function isClauseCombinator(p = pos) {\n    return tokens[p] instanceof DelimToken && [">", "+", "~"].includes(tokens[p].value);\n  }\n  function isSelectorClauseEnd(p = pos) {\n    return isComma(p) || isCloseParen(p) || isEOF(p) || isClauseCombinator(p) || tokens[p] instanceof WhitespaceToken;\n  }\n  function consumeFunctionArguments() {\n    const result2 = [consumeArgument()];\n    while (true) {\n      skipWhitespace();\n      if (!isComma())\n        break;\n      pos++;\n      result2.push(consumeArgument());\n    }\n    return result2;\n  }\n  function consumeArgument() {\n    skipWhitespace();\n    if (isNumber())\n      return tokens[pos++].value;\n    if (isString())\n      return tokens[pos++].value;\n    return consumeComplexSelector();\n  }\n  function consumeComplexSelector() {\n    const result2 = { simples: [] };\n    skipWhitespace();\n    if (isClauseCombinator()) {\n      result2.simples.push({ selector: { functions: [{ name: "scope", args: [] }] }, combinator: "" });\n    } else {\n      result2.simples.push({ selector: consumeSimpleSelector(), combinator: "" });\n    }\n    while (true) {\n      skipWhitespace();\n      if (isClauseCombinator()) {\n        result2.simples[result2.simples.length - 1].combinator = tokens[pos++].value;\n        skipWhitespace();\n      } else if (isSelectorClauseEnd()) {\n        break;\n      }\n      result2.simples.push({ combinator: "", selector: consumeSimpleSelector() });\n    }\n    return result2;\n  }\n  function consumeSimpleSelector() {\n    let rawCSSString = "";\n    const functions = [];\n    while (!isSelectorClauseEnd()) {\n      if (isIdent() || isStar()) {\n        rawCSSString += tokens[pos++].toSource();\n      } else if (tokens[pos] instanceof HashToken) {\n        rawCSSString += tokens[pos++].toSource();\n      } else if (tokens[pos] instanceof DelimToken && tokens[pos].value === ".") {\n        pos++;\n        if (isIdent())\n          rawCSSString += "." + tokens[pos++].toSource();\n        else\n          throw unexpected();\n      } else if (tokens[pos] instanceof ColonToken) {\n        pos++;\n        if (isIdent()) {\n          if (!customNames.has(tokens[pos].value.toLowerCase())) {\n            rawCSSString += ":" + tokens[pos++].toSource();\n          } else {\n            const name = tokens[pos++].value.toLowerCase();\n            functions.push({ name, args: [] });\n            names.add(name);\n          }\n        } else if (isFunction()) {\n          const name = tokens[pos++].value.toLowerCase();\n          if (!customNames.has(name)) {\n            rawCSSString += `:${name}(${consumeBuiltinFunctionArguments()})`;\n          } else {\n            functions.push({ name, args: consumeFunctionArguments() });\n            names.add(name);\n          }\n          skipWhitespace();\n          if (!isCloseParen())\n            throw unexpected();\n          pos++;\n        } else {\n          throw unexpected();\n        }\n      } else if (tokens[pos] instanceof OpenSquareToken) {\n        rawCSSString += "[";\n        pos++;\n        while (!(tokens[pos] instanceof CloseSquareToken) && !isEOF())\n          rawCSSString += tokens[pos++].toSource();\n        if (!(tokens[pos] instanceof CloseSquareToken))\n          throw unexpected();\n        rawCSSString += "]";\n        pos++;\n      } else {\n        throw unexpected();\n      }\n    }\n    if (!rawCSSString && !functions.length)\n      throw unexpected();\n    return { css: rawCSSString || void 0, functions };\n  }\n  function consumeBuiltinFunctionArguments() {\n    let s = "";\n    let balance = 1;\n    while (!isEOF()) {\n      if (isOpenParen() || isFunction())\n        balance++;\n      if (isCloseParen())\n        balance--;\n      if (!balance)\n        break;\n      s += tokens[pos++].toSource();\n    }\n    return s;\n  }\n  const result = consumeFunctionArguments();\n  if (!isEOF())\n    throw unexpected();\n  if (result.some((arg) => typeof arg !== "object" || !("simples" in arg)))\n    throw new InvalidSelectorError(`Error while parsing css selector "${selector}". Did you mean to CSS.escape it?`);\n  return { selector: result, names: Array.from(names) };\n}\n\n// packages/playwright-core/src/utils/isomorphic/selectorParser.ts\nvar kNestedSelectorNames = new Set(["internal:has", "internal:has-not", "internal:and", "internal:or", "internal:chain", "left-of", "right-of", "above", "below", "near"]);\nvar kNestedSelectorNamesWithDistance = new Set(["left-of", "right-of", "above", "below", "near"]);\nvar customCSSNames = new Set(["not", "is", "where", "has", "scope", "light", "visible", "text", "text-matches", "text-is", "has-text", "above", "below", "right-of", "left-of", "near", "nth-match"]);\nfunction parseSelector(selector) {\n  const parsedStrings = parseSelectorString(selector);\n  const parts = [];\n  for (const part of parsedStrings.parts) {\n    if (part.name === "css" || part.name === "css:light") {\n      if (part.name === "css:light")\n        part.body = ":light(" + part.body + ")";\n      const parsedCSS = parseCSS(part.body, customCSSNames);\n      parts.push({\n        name: "css",\n        body: parsedCSS.selector,\n        source: part.body\n      });\n      continue;\n    }\n    if (kNestedSelectorNames.has(part.name)) {\n      let innerSelector;\n      let distance;\n      try {\n        const unescaped = JSON.parse("[" + part.body + "]");\n        if (!Array.isArray(unescaped) || unescaped.length < 1 || unescaped.length > 2 || typeof unescaped[0] !== "string")\n          throw new InvalidSelectorError(`Malformed selector: ${part.name}=` + part.body);\n        innerSelector = unescaped[0];\n        if (unescaped.length === 2) {\n          if (typeof unescaped[1] !== "number" || !kNestedSelectorNamesWithDistance.has(part.name))\n            throw new InvalidSelectorError(`Malformed selector: ${part.name}=` + part.body);\n          distance = unescaped[1];\n        }\n      } catch (e) {\n        throw new InvalidSelectorError(`Malformed selector: ${part.name}=` + part.body);\n      }\n      const nested = { name: part.name, source: part.body, body: { parsed: parseSelector(innerSelector), distance } };\n      const lastFrame = [...nested.body.parsed.parts].reverse().find((part2) => part2.name === "internal:control" && part2.body === "enter-frame");\n      const lastFrameIndex = lastFrame ? nested.body.parsed.parts.indexOf(lastFrame) : -1;\n      if (lastFrameIndex !== -1 && selectorPartsEqual(nested.body.parsed.parts.slice(0, lastFrameIndex + 1), parts.slice(0, lastFrameIndex + 1)))\n        nested.body.parsed.parts.splice(0, lastFrameIndex + 1);\n      parts.push(nested);\n      continue;\n    }\n    parts.push({ ...part, source: part.body });\n  }\n  if (kNestedSelectorNames.has(parts[0].name))\n    throw new InvalidSelectorError(`"${parts[0].name}" selector cannot be first`);\n  return {\n    capture: parsedStrings.capture,\n    parts\n  };\n}\nfunction selectorPartsEqual(list1, list2) {\n  return stringifySelector({ parts: list1 }) === stringifySelector({ parts: list2 });\n}\nfunction stringifySelector(selector, forceEngineName) {\n  if (typeof selector === "string")\n    return selector;\n  return selector.parts.map((p, i) => {\n    let includeEngine = true;\n    if (!forceEngineName && i !== selector.capture) {\n      if (p.name === "css")\n        includeEngine = false;\n      else if (p.name === "xpath" && p.source.startsWith("//") || p.source.startsWith(".."))\n        includeEngine = false;\n    }\n    const prefix = includeEngine ? p.name + "=" : "";\n    return `${i === selector.capture ? "*" : ""}${prefix}${p.source}`;\n  }).join(" >> ");\n}\nfunction parseSelectorString(selector) {\n  let index = 0;\n  let quote;\n  let start = 0;\n  const result = { parts: [] };\n  const append = () => {\n    const part = selector.substring(start, index).trim();\n    const eqIndex = part.indexOf("=");\n    let name;\n    let body;\n    if (eqIndex !== -1 && part.substring(0, eqIndex).trim().match(/^[a-zA-Z_0-9-+:*]+$/)) {\n      name = part.substring(0, eqIndex).trim();\n      body = part.substring(eqIndex + 1);\n    } else if (part.length > 1 && part[0] === \'"\' && part[part.length - 1] === \'"\') {\n      name = "text";\n      body = part;\n    } else if (part.length > 1 && part[0] === "\'" && part[part.length - 1] === "\'") {\n      name = "text";\n      body = part;\n    } else if (/^\\(*\\/\\//.test(part) || part.startsWith("..")) {\n      name = "xpath";\n      body = part;\n    } else {\n      name = "css";\n      body = part;\n    }\n    let capture = false;\n    if (name[0] === "*") {\n      capture = true;\n      name = name.substring(1);\n    }\n    result.parts.push({ name, body });\n    if (capture) {\n      if (result.capture !== void 0)\n        throw new InvalidSelectorError(`Only one of the selectors can capture using * modifier`);\n      result.capture = result.parts.length - 1;\n    }\n  };\n  if (!selector.includes(">>")) {\n    index = selector.length;\n    append();\n    return result;\n  }\n  const shouldIgnoreTextSelectorQuote = () => {\n    const prefix = selector.substring(start, index);\n    const match = prefix.match(/^\\s*text\\s*=(.*)$/);\n    return !!match && !!match[1];\n  };\n  while (index < selector.length) {\n    const c = selector[index];\n    if (c === "\\\\" && index + 1 < selector.length) {\n      index += 2;\n    } else if (c === quote) {\n      quote = void 0;\n      index++;\n    } else if (!quote && (c === \'"\' || c === "\'" || c === "`") && !shouldIgnoreTextSelectorQuote()) {\n      quote = c;\n      index++;\n    } else if (!quote && c === ">" && selector[index + 1] === ">") {\n      append();\n      index += 2;\n      start = index;\n    } else {\n      index++;\n    }\n  }\n  append();\n  return result;\n}\nfunction parseAttributeSelector(selector, allowUnquotedStrings) {\n  let wp = 0;\n  let EOL = selector.length === 0;\n  const next = () => selector[wp] || "";\n  const eat1 = () => {\n    const result2 = next();\n    ++wp;\n    EOL = wp >= selector.length;\n    return result2;\n  };\n  const syntaxError = (stage) => {\n    if (EOL)\n      throw new InvalidSelectorError(`Unexpected end of selector while parsing selector \\`${selector}\\``);\n    throw new InvalidSelectorError(`Error while parsing selector \\`${selector}\\` - unexpected symbol "${next()}" at position ${wp}` + (stage ? " during " + stage : ""));\n  };\n  function skipSpaces() {\n    while (!EOL && /\\s/.test(next()))\n      eat1();\n  }\n  function isCSSNameChar(char) {\n    return char >= "\\x80" || char >= "0" && char <= "9" || char >= "A" && char <= "Z" || char >= "a" && char <= "z" || char >= "0" && char <= "9" || char === "_" || char === "-";\n  }\n  function readIdentifier() {\n    let result2 = "";\n    skipSpaces();\n    while (!EOL && isCSSNameChar(next()))\n      result2 += eat1();\n    return result2;\n  }\n  function readQuotedString(quote) {\n    let result2 = eat1();\n    if (result2 !== quote)\n      syntaxError("parsing quoted string");\n    while (!EOL && next() !== quote) {\n      if (next() === "\\\\")\n        eat1();\n      result2 += eat1();\n    }\n    if (next() !== quote)\n      syntaxError("parsing quoted string");\n    result2 += eat1();\n    return result2;\n  }\n  function readRegularExpression() {\n    if (eat1() !== "/")\n      syntaxError("parsing regular expression");\n    let source = "";\n    let inClass = false;\n    while (!EOL) {\n      if (next() === "\\\\") {\n        source += eat1();\n        if (EOL)\n          syntaxError("parsing regular expression");\n      } else if (inClass && next() === "]") {\n        inClass = false;\n      } else if (!inClass && next() === "[") {\n        inClass = true;\n      } else if (!inClass && next() === "/") {\n        break;\n      }\n      source += eat1();\n    }\n    if (eat1() !== "/")\n      syntaxError("parsing regular expression");\n    let flags = "";\n    while (!EOL && next().match(/[dgimsuy]/))\n      flags += eat1();\n    try {\n      return new RegExp(source, flags);\n    } catch (e) {\n      throw new InvalidSelectorError(`Error while parsing selector \\`${selector}\\`: ${e.message}`);\n    }\n  }\n  function readAttributeToken() {\n    let token = "";\n    skipSpaces();\n    if (next() === `\'` || next() === `"`)\n      token = readQuotedString(next()).slice(1, -1);\n    else\n      token = readIdentifier();\n    if (!token)\n      syntaxError("parsing property path");\n    return token;\n  }\n  function readOperator() {\n    skipSpaces();\n    let op = "";\n    if (!EOL)\n      op += eat1();\n    if (!EOL && op !== "=")\n      op += eat1();\n    if (!["=", "*=", "^=", "$=", "|=", "~="].includes(op))\n      syntaxError("parsing operator");\n    return op;\n  }\n  function readAttribute() {\n    eat1();\n    const jsonPath = [];\n    jsonPath.push(readAttributeToken());\n    skipSpaces();\n    while (next() === ".") {\n      eat1();\n      jsonPath.push(readAttributeToken());\n      skipSpaces();\n    }\n    if (next() === "]") {\n      eat1();\n      return { name: jsonPath.join("."), jsonPath, op: "<truthy>", value: null, caseSensitive: false };\n    }\n    const operator = readOperator();\n    let value = void 0;\n    let caseSensitive = true;\n    skipSpaces();\n    if (next() === "/") {\n      if (operator !== "=")\n        throw new InvalidSelectorError(`Error while parsing selector \\`${selector}\\` - cannot use ${operator} in attribute with regular expression`);\n      value = readRegularExpression();\n    } else if (next() === `\'` || next() === `"`) {\n      value = readQuotedString(next()).slice(1, -1);\n      skipSpaces();\n      if (next() === "i" || next() === "I") {\n        caseSensitive = false;\n        eat1();\n      } else if (next() === "s" || next() === "S") {\n        caseSensitive = true;\n        eat1();\n      }\n    } else {\n      value = "";\n      while (!EOL && (isCSSNameChar(next()) || next() === "+" || next() === "."))\n        value += eat1();\n      if (value === "true") {\n        value = true;\n      } else if (value === "false") {\n        value = false;\n      } else {\n        if (!allowUnquotedStrings) {\n          value = +value;\n          if (Number.isNaN(value))\n            syntaxError("parsing attribute value");\n        }\n      }\n    }\n    skipSpaces();\n    if (next() !== "]")\n      syntaxError("parsing attribute value");\n    eat1();\n    if (operator !== "=" && typeof value !== "string")\n      throw new InvalidSelectorError(`Error while parsing selector \\`${selector}\\` - cannot use ${operator} in attribute with non-string matching value - ${value}`);\n    return { name: jsonPath.join("."), jsonPath, op: operator, value, caseSensitive };\n  }\n  const result = {\n    name: "",\n    attributes: []\n  };\n  result.name = readIdentifier();\n  skipSpaces();\n  while (next() === "[") {\n    result.attributes.push(readAttribute());\n    skipSpaces();\n  }\n  if (!EOL)\n    syntaxError(void 0);\n  if (!result.name && !result.attributes.length)\n    throw new InvalidSelectorError(`Error while parsing selector \\`${selector}\\` - selector cannot be empty`);\n  return result;\n}\n\n// packages/playwright-core/src/utils/isomorphic/stringUtils.ts\nfunction escapeWithQuotes(text, char = "\'") {\n  const stringified = JSON.stringify(text);\n  const escapedText = stringified.substring(1, stringified.length - 1).replace(/\\\\"/g, \'"\');\n  if (char === "\'")\n    return char + escapedText.replace(/[\']/g, "\\\\\'") + char;\n  if (char === \'"\')\n    return char + escapedText.replace(/["]/g, \'\\\\"\') + char;\n  if (char === "`")\n    return char + escapedText.replace(/[`]/g, "`") + char;\n  throw new Error("Invalid escape char");\n}\nfunction toTitleCase(name) {\n  return name.charAt(0).toUpperCase() + name.substring(1);\n}\nfunction toSnakeCase(name) {\n  return name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase();\n}\nfunction normalizeEscapedRegexQuotes(source) {\n  return source.replace(/(^|[^\\\\])(\\\\\\\\)*\\\\([\'"`])/g, "$1$2$3");\n}\nfunction escapeRegexForSelector(re) {\n  if (re.unicode || re.unicodeSets)\n    return String(re);\n  return String(re).replace(/(^|[^\\\\])(\\\\\\\\)*(["\'`])/g, "$1$2\\\\$3").replace(/>>/g, "\\\\>\\\\>");\n}\nfunction escapeForTextSelector(text, exact) {\n  if (typeof text !== "string")\n    return escapeRegexForSelector(text);\n  return `${JSON.stringify(text)}${exact ? "s" : "i"}`;\n}\nfunction escapeForAttributeSelector(value, exact) {\n  if (typeof value !== "string")\n    return escapeRegexForSelector(value);\n  return `"${value.replace(/\\\\/g, "\\\\\\\\").replace(/["]/g, \'\\\\"\')}"${exact ? "s" : "i"}`;\n}\n\n// packages/playwright-core/src/utils/isomorphic/locatorGenerators.ts\nfunction asLocator(lang, selector, isFrameLocator = false) {\n  return asLocators(lang, selector, isFrameLocator, 1)[0];\n}\nfunction asLocators(lang, selector, isFrameLocator = false, maxOutputSize = 20, preferredQuote) {\n  try {\n    return innerAsLocators(new generators[lang](preferredQuote), parseSelector(selector), isFrameLocator, maxOutputSize);\n  } catch (e) {\n    return [selector];\n  }\n}\nfunction innerAsLocators(factory, parsed, isFrameLocator = false, maxOutputSize = 20) {\n  const parts = [...parsed.parts];\n  const tokens = [];\n  let nextBase = isFrameLocator ? "frame-locator" : "page";\n  for (let index = 0; index < parts.length; index++) {\n    const part = parts[index];\n    const base = nextBase;\n    nextBase = "locator";\n    if (part.name === "nth") {\n      if (part.body === "0")\n        tokens.push([factory.generateLocator(base, "first", ""), factory.generateLocator(base, "nth", "0")]);\n      else if (part.body === "-1")\n        tokens.push([factory.generateLocator(base, "last", ""), factory.generateLocator(base, "nth", "-1")]);\n      else\n        tokens.push([factory.generateLocator(base, "nth", part.body)]);\n      continue;\n    }\n    if (part.name === "visible") {\n      tokens.push([factory.generateLocator(base, "visible", part.body), factory.generateLocator(base, "default", `visible=${part.body}`)]);\n      continue;\n    }\n    if (part.name === "internal:text") {\n      const { exact, text } = detectExact(part.body);\n      tokens.push([factory.generateLocator(base, "text", text, { exact })]);\n      continue;\n    }\n    if (part.name === "internal:has-text") {\n      const { exact, text } = detectExact(part.body);\n      if (!exact) {\n        tokens.push([factory.generateLocator(base, "has-text", text, { exact })]);\n        continue;\n      }\n    }\n    if (part.name === "internal:has-not-text") {\n      const { exact, text } = detectExact(part.body);\n      if (!exact) {\n        tokens.push([factory.generateLocator(base, "has-not-text", text, { exact })]);\n        continue;\n      }\n    }\n    if (part.name === "internal:has") {\n      const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);\n      tokens.push(inners.map((inner) => factory.generateLocator(base, "has", inner)));\n      continue;\n    }\n    if (part.name === "internal:has-not") {\n      const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);\n      tokens.push(inners.map((inner) => factory.generateLocator(base, "hasNot", inner)));\n      continue;\n    }\n    if (part.name === "internal:and") {\n      const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);\n      tokens.push(inners.map((inner) => factory.generateLocator(base, "and", inner)));\n      continue;\n    }\n    if (part.name === "internal:or") {\n      const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);\n      tokens.push(inners.map((inner) => factory.generateLocator(base, "or", inner)));\n      continue;\n    }\n    if (part.name === "internal:chain") {\n      const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);\n      tokens.push(inners.map((inner) => factory.generateLocator(base, "chain", inner)));\n      continue;\n    }\n    if (part.name === "internal:label") {\n      const { exact, text } = detectExact(part.body);\n      tokens.push([factory.generateLocator(base, "label", text, { exact })]);\n      continue;\n    }\n    if (part.name === "internal:role") {\n      const attrSelector = parseAttributeSelector(part.body, true);\n      const options = { attrs: [] };\n      for (const attr of attrSelector.attributes) {\n        if (attr.name === "name") {\n          options.exact = attr.caseSensitive;\n          options.name = attr.value;\n        } else {\n          if (attr.name === "level" && typeof attr.value === "string")\n            attr.value = +attr.value;\n          options.attrs.push({ name: attr.name === "include-hidden" ? "includeHidden" : attr.name, value: attr.value });\n        }\n      }\n      tokens.push([factory.generateLocator(base, "role", attrSelector.name, options)]);\n      continue;\n    }\n    if (part.name === "internal:testid") {\n      const attrSelector = parseAttributeSelector(part.body, true);\n      const { value } = attrSelector.attributes[0];\n      tokens.push([factory.generateLocator(base, "test-id", value)]);\n      continue;\n    }\n    if (part.name === "internal:attr") {\n      const attrSelector = parseAttributeSelector(part.body, true);\n      const { name, value, caseSensitive } = attrSelector.attributes[0];\n      const text = value;\n      const exact = !!caseSensitive;\n      if (name === "placeholder") {\n        tokens.push([factory.generateLocator(base, "placeholder", text, { exact })]);\n        continue;\n      }\n      if (name === "alt") {\n        tokens.push([factory.generateLocator(base, "alt", text, { exact })]);\n        continue;\n      }\n      if (name === "title") {\n        tokens.push([factory.generateLocator(base, "title", text, { exact })]);\n        continue;\n      }\n    }\n    if (part.name === "internal:control" && part.body === "enter-frame") {\n      const lastTokens = tokens[tokens.length - 1];\n      const lastPart = parts[index - 1];\n      const transformed = lastTokens.map((token) => factory.chainLocators([token, factory.generateLocator(base, "frame", "")]));\n      if (["xpath", "css"].includes(lastPart.name)) {\n        transformed.push(\n          factory.generateLocator(base, "frame-locator", stringifySelector({ parts: [lastPart] })),\n          factory.generateLocator(base, "frame-locator", stringifySelector({ parts: [lastPart] }, true))\n        );\n      }\n      lastTokens.splice(0, lastTokens.length, ...transformed);\n      nextBase = "frame-locator";\n      continue;\n    }\n    const nextPart = parts[index + 1];\n    const selectorPart = stringifySelector({ parts: [part] });\n    const locatorPart = factory.generateLocator(base, "default", selectorPart);\n    if (nextPart && ["internal:has-text", "internal:has-not-text"].includes(nextPart.name)) {\n      const { exact, text } = detectExact(nextPart.body);\n      if (!exact) {\n        const nextLocatorPart = factory.generateLocator("locator", nextPart.name === "internal:has-text" ? "has-text" : "has-not-text", text, { exact });\n        const options = {};\n        if (nextPart.name === "internal:has-text")\n          options.hasText = text;\n        else\n          options.hasNotText = text;\n        const combinedPart = factory.generateLocator(base, "default", selectorPart, options);\n        tokens.push([factory.chainLocators([locatorPart, nextLocatorPart]), combinedPart]);\n        index++;\n        continue;\n      }\n    }\n    let locatorPartWithEngine;\n    if (["xpath", "css"].includes(part.name)) {\n      const selectorPart2 = stringifySelector(\n        { parts: [part] },\n        /* forceEngineName */\n        true\n      );\n      locatorPartWithEngine = factory.generateLocator(base, "default", selectorPart2);\n    }\n    tokens.push([locatorPart, locatorPartWithEngine].filter(Boolean));\n  }\n  return combineTokens(factory, tokens, maxOutputSize);\n}\nfunction combineTokens(factory, tokens, maxOutputSize) {\n  const currentTokens = tokens.map(() => "");\n  const result = [];\n  const visit = (index) => {\n    if (index === tokens.length) {\n      result.push(factory.chainLocators(currentTokens));\n      return result.length < maxOutputSize;\n    }\n    for (const taken of tokens[index]) {\n      currentTokens[index] = taken;\n      if (!visit(index + 1))\n        return false;\n    }\n    return true;\n  };\n  visit(0);\n  return result;\n}\nfunction detectExact(text) {\n  let exact = false;\n  const match = text.match(/^\\/(.*)\\/([igm]*)$/);\n  if (match)\n    return { text: new RegExp(match[1], match[2]) };\n  if (text.endsWith(\'"\')) {\n    text = JSON.parse(text);\n    exact = true;\n  } else if (text.endsWith(\'"s\')) {\n    text = JSON.parse(text.substring(0, text.length - 1));\n    exact = true;\n  } else if (text.endsWith(\'"i\')) {\n    text = JSON.parse(text.substring(0, text.length - 1));\n    exact = false;\n  }\n  return { exact, text };\n}\nvar JavaScriptLocatorFactory = class {\n  constructor(preferredQuote) {\n    this.preferredQuote = preferredQuote;\n  }\n  generateLocator(base, kind, body, options = {}) {\n    switch (kind) {\n      case "default":\n        if (options.hasText !== void 0)\n          return `locator(${this.quote(body)}, { hasText: ${this.toHasText(options.hasText)} })`;\n        if (options.hasNotText !== void 0)\n          return `locator(${this.quote(body)}, { hasNotText: ${this.toHasText(options.hasNotText)} })`;\n        return `locator(${this.quote(body)})`;\n      case "frame-locator":\n        return `frameLocator(${this.quote(body)})`;\n      case "frame":\n        return `contentFrame()`;\n      case "nth":\n        return `nth(${body})`;\n      case "first":\n        return `first()`;\n      case "last":\n        return `last()`;\n      case "visible":\n        return `filter({ visible: ${body === "true" ? "true" : "false"} })`;\n      case "role":\n        const attrs = [];\n        if (isRegExp(options.name)) {\n          attrs.push(`name: ${this.regexToSourceString(options.name)}`);\n        } else if (typeof options.name === "string") {\n          attrs.push(`name: ${this.quote(options.name)}`);\n          if (options.exact)\n            attrs.push(`exact: true`);\n        }\n        for (const { name, value } of options.attrs)\n          attrs.push(`${name}: ${typeof value === "string" ? this.quote(value) : value}`);\n        const attrString = attrs.length ? `, { ${attrs.join(", ")} }` : "";\n        return `getByRole(${this.quote(body)}${attrString})`;\n      case "has-text":\n        return `filter({ hasText: ${this.toHasText(body)} })`;\n      case "has-not-text":\n        return `filter({ hasNotText: ${this.toHasText(body)} })`;\n      case "has":\n        return `filter({ has: ${body} })`;\n      case "hasNot":\n        return `filter({ hasNot: ${body} })`;\n      case "and":\n        return `and(${body})`;\n      case "or":\n        return `or(${body})`;\n      case "chain":\n        return `locator(${body})`;\n      case "test-id":\n        return `getByTestId(${this.toTestIdValue(body)})`;\n      case "text":\n        return this.toCallWithExact("getByText", body, !!options.exact);\n      case "alt":\n        return this.toCallWithExact("getByAltText", body, !!options.exact);\n      case "placeholder":\n        return this.toCallWithExact("getByPlaceholder", body, !!options.exact);\n      case "label":\n        return this.toCallWithExact("getByLabel", body, !!options.exact);\n      case "title":\n        return this.toCallWithExact("getByTitle", body, !!options.exact);\n      default:\n        throw new Error("Unknown selector kind " + kind);\n    }\n  }\n  chainLocators(locators) {\n    return locators.join(".");\n  }\n  regexToSourceString(re) {\n    return normalizeEscapedRegexQuotes(String(re));\n  }\n  toCallWithExact(method, body, exact) {\n    if (isRegExp(body))\n      return `${method}(${this.regexToSourceString(body)})`;\n    return exact ? `${method}(${this.quote(body)}, { exact: true })` : `${method}(${this.quote(body)})`;\n  }\n  toHasText(body) {\n    if (isRegExp(body))\n      return this.regexToSourceString(body);\n    return this.quote(body);\n  }\n  toTestIdValue(value) {\n    if (isRegExp(value))\n      return this.regexToSourceString(value);\n    return this.quote(value);\n  }\n  quote(text) {\n    var _a;\n    return escapeWithQuotes(text, (_a = this.preferredQuote) != null ? _a : "\'");\n  }\n};\nvar PythonLocatorFactory = class {\n  generateLocator(base, kind, body, options = {}) {\n    switch (kind) {\n      case "default":\n        if (options.hasText !== void 0)\n          return `locator(${this.quote(body)}, has_text=${this.toHasText(options.hasText)})`;\n        if (options.hasNotText !== void 0)\n          return `locator(${this.quote(body)}, has_not_text=${this.toHasText(options.hasNotText)})`;\n        return `locator(${this.quote(body)})`;\n      case "frame-locator":\n        return `frame_locator(${this.quote(body)})`;\n      case "frame":\n        return `content_frame`;\n      case "nth":\n        return `nth(${body})`;\n      case "first":\n        return `first`;\n      case "last":\n        return `last`;\n      case "visible":\n        return `filter(visible=${body === "true" ? "True" : "False"})`;\n      case "role":\n        const attrs = [];\n        if (isRegExp(options.name)) {\n          attrs.push(`name=${this.regexToString(options.name)}`);\n        } else if (typeof options.name === "string") {\n          attrs.push(`name=${this.quote(options.name)}`);\n          if (options.exact)\n            attrs.push(`exact=True`);\n        }\n        for (const { name, value } of options.attrs) {\n          let valueString = typeof value === "string" ? this.quote(value) : value;\n          if (typeof value === "boolean")\n            valueString = value ? "True" : "False";\n          attrs.push(`${toSnakeCase(name)}=${valueString}`);\n        }\n        const attrString = attrs.length ? `, ${attrs.join(", ")}` : "";\n        return `get_by_role(${this.quote(body)}${attrString})`;\n      case "has-text":\n        return `filter(has_text=${this.toHasText(body)})`;\n      case "has-not-text":\n        return `filter(has_not_text=${this.toHasText(body)})`;\n      case "has":\n        return `filter(has=${body})`;\n      case "hasNot":\n        return `filter(has_not=${body})`;\n      case "and":\n        return `and_(${body})`;\n      case "or":\n        return `or_(${body})`;\n      case "chain":\n        return `locator(${body})`;\n      case "test-id":\n        return `get_by_test_id(${this.toTestIdValue(body)})`;\n      case "text":\n        return this.toCallWithExact("get_by_text", body, !!options.exact);\n      case "alt":\n        return this.toCallWithExact("get_by_alt_text", body, !!options.exact);\n      case "placeholder":\n        return this.toCallWithExact("get_by_placeholder", body, !!options.exact);\n      case "label":\n        return this.toCallWithExact("get_by_label", body, !!options.exact);\n      case "title":\n        return this.toCallWithExact("get_by_title", body, !!options.exact);\n      default:\n        throw new Error("Unknown selector kind " + kind);\n    }\n  }\n  chainLocators(locators) {\n    return locators.join(".");\n  }\n  regexToString(body) {\n    const suffix = body.flags.includes("i") ? ", re.IGNORECASE" : "";\n    return `re.compile(r"${normalizeEscapedRegexQuotes(body.source).replace(/\\\\\\//, "/").replace(/"/g, \'\\\\"\')}"${suffix})`;\n  }\n  toCallWithExact(method, body, exact) {\n    if (isRegExp(body))\n      return `${method}(${this.regexToString(body)})`;\n    if (exact)\n      return `${method}(${this.quote(body)}, exact=True)`;\n    return `${method}(${this.quote(body)})`;\n  }\n  toHasText(body) {\n    if (isRegExp(body))\n      return this.regexToString(body);\n    return `${this.quote(body)}`;\n  }\n  toTestIdValue(value) {\n    if (isRegExp(value))\n      return this.regexToString(value);\n    return this.quote(value);\n  }\n  quote(text) {\n    return escapeWithQuotes(text, \'"\');\n  }\n};\nvar JavaLocatorFactory = class {\n  generateLocator(base, kind, body, options = {}) {\n    let clazz;\n    switch (base) {\n      case "page":\n        clazz = "Page";\n        break;\n      case "frame-locator":\n        clazz = "FrameLocator";\n        break;\n      case "locator":\n        clazz = "Locator";\n        break;\n    }\n    switch (kind) {\n      case "default":\n        if (options.hasText !== void 0)\n          return `locator(${this.quote(body)}, new ${clazz}.LocatorOptions().setHasText(${this.toHasText(options.hasText)}))`;\n        if (options.hasNotText !== void 0)\n          return `locator(${this.quote(body)}, new ${clazz}.LocatorOptions().setHasNotText(${this.toHasText(options.hasNotText)}))`;\n        return `locator(${this.quote(body)})`;\n      case "frame-locator":\n        return `frameLocator(${this.quote(body)})`;\n      case "frame":\n        return `contentFrame()`;\n      case "nth":\n        return `nth(${body})`;\n      case "first":\n        return `first()`;\n      case "last":\n        return `last()`;\n      case "visible":\n        return `filter(new ${clazz}.FilterOptions().setVisible(${body === "true" ? "true" : "false"}))`;\n      case "role":\n        const attrs = [];\n        if (isRegExp(options.name)) {\n          attrs.push(`.setName(${this.regexToString(options.name)})`);\n        } else if (typeof options.name === "string") {\n          attrs.push(`.setName(${this.quote(options.name)})`);\n          if (options.exact)\n            attrs.push(`.setExact(true)`);\n        }\n        for (const { name, value } of options.attrs)\n          attrs.push(`.set${toTitleCase(name)}(${typeof value === "string" ? this.quote(value) : value})`);\n        const attrString = attrs.length ? `, new ${clazz}.GetByRoleOptions()${attrs.join("")}` : "";\n        return `getByRole(AriaRole.${toSnakeCase(body).toUpperCase()}${attrString})`;\n      case "has-text":\n        return `filter(new ${clazz}.FilterOptions().setHasText(${this.toHasText(body)}))`;\n      case "has-not-text":\n        return `filter(new ${clazz}.FilterOptions().setHasNotText(${this.toHasText(body)}))`;\n      case "has":\n        return `filter(new ${clazz}.FilterOptions().setHas(${body}))`;\n      case "hasNot":\n        return `filter(new ${clazz}.FilterOptions().setHasNot(${body}))`;\n      case "and":\n        return `and(${body})`;\n      case "or":\n        return `or(${body})`;\n      case "chain":\n        return `locator(${body})`;\n      case "test-id":\n        return `getByTestId(${this.toTestIdValue(body)})`;\n      case "text":\n        return this.toCallWithExact(clazz, "getByText", body, !!options.exact);\n      case "alt":\n        return this.toCallWithExact(clazz, "getByAltText", body, !!options.exact);\n      case "placeholder":\n        return this.toCallWithExact(clazz, "getByPlaceholder", body, !!options.exact);\n      case "label":\n        return this.toCallWithExact(clazz, "getByLabel", body, !!options.exact);\n      case "title":\n        return this.toCallWithExact(clazz, "getByTitle", body, !!options.exact);\n      default:\n        throw new Error("Unknown selector kind " + kind);\n    }\n  }\n  chainLocators(locators) {\n    return locators.join(".");\n  }\n  regexToString(body) {\n    const suffix = body.flags.includes("i") ? ", Pattern.CASE_INSENSITIVE" : "";\n    return `Pattern.compile(${this.quote(normalizeEscapedRegexQuotes(body.source))}${suffix})`;\n  }\n  toCallWithExact(clazz, method, body, exact) {\n    if (isRegExp(body))\n      return `${method}(${this.regexToString(body)})`;\n    if (exact)\n      return `${method}(${this.quote(body)}, new ${clazz}.${toTitleCase(method)}Options().setExact(true))`;\n    return `${method}(${this.quote(body)})`;\n  }\n  toHasText(body) {\n    if (isRegExp(body))\n      return this.regexToString(body);\n    return this.quote(body);\n  }\n  toTestIdValue(value) {\n    if (isRegExp(value))\n      return this.regexToString(value);\n    return this.quote(value);\n  }\n  quote(text) {\n    return escapeWithQuotes(text, \'"\');\n  }\n};\nvar CSharpLocatorFactory = class {\n  generateLocator(base, kind, body, options = {}) {\n    switch (kind) {\n      case "default":\n        if (options.hasText !== void 0)\n          return `Locator(${this.quote(body)}, new() { ${this.toHasText(options.hasText)} })`;\n        if (options.hasNotText !== void 0)\n          return `Locator(${this.quote(body)}, new() { ${this.toHasNotText(options.hasNotText)} })`;\n        return `Locator(${this.quote(body)})`;\n      case "frame-locator":\n        return `FrameLocator(${this.quote(body)})`;\n      case "frame":\n        return `ContentFrame`;\n      case "nth":\n        return `Nth(${body})`;\n      case "first":\n        return `First`;\n      case "last":\n        return `Last`;\n      case "visible":\n        return `Filter(new() { Visible = ${body === "true" ? "true" : "false"} })`;\n      case "role":\n        const attrs = [];\n        if (isRegExp(options.name)) {\n          attrs.push(`NameRegex = ${this.regexToString(options.name)}`);\n        } else if (typeof options.name === "string") {\n          attrs.push(`Name = ${this.quote(options.name)}`);\n          if (options.exact)\n            attrs.push(`Exact = true`);\n        }\n        for (const { name, value } of options.attrs)\n          attrs.push(`${toTitleCase(name)} = ${typeof value === "string" ? this.quote(value) : value}`);\n        const attrString = attrs.length ? `, new() { ${attrs.join(", ")} }` : "";\n        return `GetByRole(AriaRole.${toTitleCase(body)}${attrString})`;\n      case "has-text":\n        return `Filter(new() { ${this.toHasText(body)} })`;\n      case "has-not-text":\n        return `Filter(new() { ${this.toHasNotText(body)} })`;\n      case "has":\n        return `Filter(new() { Has = ${body} })`;\n      case "hasNot":\n        return `Filter(new() { HasNot = ${body} })`;\n      case "and":\n        return `And(${body})`;\n      case "or":\n        return `Or(${body})`;\n      case "chain":\n        return `Locator(${body})`;\n      case "test-id":\n        return `GetByTestId(${this.toTestIdValue(body)})`;\n      case "text":\n        return this.toCallWithExact("GetByText", body, !!options.exact);\n      case "alt":\n        return this.toCallWithExact("GetByAltText", body, !!options.exact);\n      case "placeholder":\n        return this.toCallWithExact("GetByPlaceholder", body, !!options.exact);\n      case "label":\n        return this.toCallWithExact("GetByLabel", body, !!options.exact);\n      case "title":\n        return this.toCallWithExact("GetByTitle", body, !!options.exact);\n      default:\n        throw new Error("Unknown selector kind " + kind);\n    }\n  }\n  chainLocators(locators) {\n    return locators.join(".");\n  }\n  regexToString(body) {\n    const suffix = body.flags.includes("i") ? ", RegexOptions.IgnoreCase" : "";\n    return `new Regex(${this.quote(normalizeEscapedRegexQuotes(body.source))}${suffix})`;\n  }\n  toCallWithExact(method, body, exact) {\n    if (isRegExp(body))\n      return `${method}(${this.regexToString(body)})`;\n    if (exact)\n      return `${method}(${this.quote(body)}, new() { Exact = true })`;\n    return `${method}(${this.quote(body)})`;\n  }\n  toHasText(body) {\n    if (isRegExp(body))\n      return `HasTextRegex = ${this.regexToString(body)}`;\n    return `HasText = ${this.quote(body)}`;\n  }\n  toTestIdValue(value) {\n    if (isRegExp(value))\n      return this.regexToString(value);\n    return this.quote(value);\n  }\n  toHasNotText(body) {\n    if (isRegExp(body))\n      return `HasNotTextRegex = ${this.regexToString(body)}`;\n    return `HasNotText = ${this.quote(body)}`;\n  }\n  quote(text) {\n    return escapeWithQuotes(text, \'"\');\n  }\n};\nvar JsonlLocatorFactory = class {\n  generateLocator(base, kind, body, options = {}) {\n    return JSON.stringify({\n      kind,\n      body,\n      options\n    });\n  }\n  chainLocators(locators) {\n    const objects = locators.map((l) => JSON.parse(l));\n    for (let i = 0; i < objects.length - 1; ++i)\n      objects[i].next = objects[i + 1];\n    return JSON.stringify(objects[0]);\n  }\n};\nvar generators = {\n  javascript: JavaScriptLocatorFactory,\n  python: PythonLocatorFactory,\n  java: JavaLocatorFactory,\n  csharp: CSharpLocatorFactory,\n  jsonl: JsonlLocatorFactory\n};\nfunction isRegExp(obj) {\n  return obj instanceof RegExp;\n}\n\n// packages/playwright-core/src/utils/isomorphic/locatorUtils.ts\nfunction getByAttributeTextSelector(attrName, text, options) {\n  return `internal:attr=[${attrName}=${escapeForAttributeSelector(text, (options == null ? void 0 : options.exact) || false)}]`;\n}\nfunction getByTestIdSelector(testIdAttributeName, testId) {\n  return `internal:testid=[${testIdAttributeName}=${escapeForAttributeSelector(testId, true)}]`;\n}\nfunction getByLabelSelector(text, options) {\n  return "internal:label=" + escapeForTextSelector(text, !!(options == null ? void 0 : options.exact));\n}\nfunction getByAltTextSelector(text, options) {\n  return getByAttributeTextSelector("alt", text, options);\n}\nfunction getByTitleSelector(text, options) {\n  return getByAttributeTextSelector("title", text, options);\n}\nfunction getByPlaceholderSelector(text, options) {\n  return getByAttributeTextSelector("placeholder", text, options);\n}\nfunction getByTextSelector(text, options) {\n  return "internal:text=" + escapeForTextSelector(text, !!(options == null ? void 0 : options.exact));\n}\nfunction getByRoleSelector(role, options = {}) {\n  const props = [];\n  if (options.checked !== void 0)\n    props.push(["checked", String(options.checked)]);\n  if (options.disabled !== void 0)\n    props.push(["disabled", String(options.disabled)]);\n  if (options.selected !== void 0)\n    props.push(["selected", String(options.selected)]);\n  if (options.expanded !== void 0)\n    props.push(["expanded", String(options.expanded)]);\n  if (options.includeHidden !== void 0)\n    props.push(["include-hidden", String(options.includeHidden)]);\n  if (options.level !== void 0)\n    props.push(["level", String(options.level)]);\n  if (options.name !== void 0)\n    props.push(["name", escapeForAttributeSelector(options.name, !!options.exact)]);\n  if (options.pressed !== void 0)\n    props.push(["pressed", String(options.pressed)]);\n  return `internal:role=${role}${props.map(([n, v]) => `[${n}=${v}]`).join("")}`;\n}\n\n// packages/injected/src/consoleApi.ts\nvar selectorSymbol = Symbol("selector");\nselectorSymbol;\nvar _Locator = class _Locator {\n  constructor(injectedScript, selector, options) {\n    if (options == null ? void 0 : options.hasText)\n      selector += ` >> internal:has-text=${escapeForTextSelector(options.hasText, false)}`;\n    if (options == null ? void 0 : options.hasNotText)\n      selector += ` >> internal:has-not-text=${escapeForTextSelector(options.hasNotText, false)}`;\n    if (options == null ? void 0 : options.has)\n      selector += ` >> internal:has=` + JSON.stringify(options.has[selectorSymbol]);\n    if (options == null ? void 0 : options.hasNot)\n      selector += ` >> internal:has-not=` + JSON.stringify(options.hasNot[selectorSymbol]);\n    if ((options == null ? void 0 : options.visible) !== void 0)\n      selector += ` >> visible=${options.visible ? "true" : "false"}`;\n    this[selectorSymbol] = selector;\n    if (selector) {\n      const parsed = injectedScript.parseSelector(selector);\n      this.element = injectedScript.querySelector(parsed, injectedScript.document, false);\n      this.elements = injectedScript.querySelectorAll(parsed, injectedScript.document);\n    }\n    const selectorBase = selector;\n    const self = this;\n    self.locator = (selector2, options2) => {\n      return new _Locator(injectedScript, selectorBase ? selectorBase + " >> " + selector2 : selector2, options2);\n    };\n    self.getByTestId = (testId) => self.locator(getByTestIdSelector(injectedScript.testIdAttributeNameForStrictErrorAndConsoleCodegen(), testId));\n    self.getByAltText = (text, options2) => self.locator(getByAltTextSelector(text, options2));\n    self.getByLabel = (text, options2) => self.locator(getByLabelSelector(text, options2));\n    self.getByPlaceholder = (text, options2) => self.locator(getByPlaceholderSelector(text, options2));\n    self.getByText = (text, options2) => self.locator(getByTextSelector(text, options2));\n    self.getByTitle = (text, options2) => self.locator(getByTitleSelector(text, options2));\n    self.getByRole = (role, options2 = {}) => self.locator(getByRoleSelector(role, options2));\n    self.filter = (options2) => new _Locator(injectedScript, selector, options2);\n    self.first = () => self.locator("nth=0");\n    self.last = () => self.locator("nth=-1");\n    self.nth = (index) => self.locator(`nth=${index}`);\n    self.and = (locator) => new _Locator(injectedScript, selectorBase + ` >> internal:and=` + JSON.stringify(locator[selectorSymbol]));\n    self.or = (locator) => new _Locator(injectedScript, selectorBase + ` >> internal:or=` + JSON.stringify(locator[selectorSymbol]));\n  }\n};\nvar Locator = _Locator;\nvar ConsoleAPI = class {\n  constructor(injectedScript) {\n    this._injectedScript = injectedScript;\n    if (this._injectedScript.window.playwright)\n      return;\n    this._injectedScript.window.playwright = {\n      $: (selector, strict) => this._querySelector(selector, !!strict),\n      $$: (selector) => this._querySelectorAll(selector),\n      inspect: (selector) => this._inspect(selector),\n      selector: (element) => this._selector(element),\n      generateLocator: (element, language) => this._generateLocator(element, language),\n      ariaSnapshot: (element, options) => {\n        return this._injectedScript.ariaSnapshot(element || this._injectedScript.document.body, options);\n      },\n      resume: () => this._resume(),\n      ...new Locator(injectedScript, "")\n    };\n    delete this._injectedScript.window.playwright.filter;\n    delete this._injectedScript.window.playwright.first;\n    delete this._injectedScript.window.playwright.last;\n    delete this._injectedScript.window.playwright.nth;\n    delete this._injectedScript.window.playwright.and;\n    delete this._injectedScript.window.playwright.or;\n  }\n  _querySelector(selector, strict) {\n    if (typeof selector !== "string")\n      throw new Error(`Usage: playwright.query(\'Playwright >> selector\').`);\n    const parsed = this._injectedScript.parseSelector(selector);\n    return this._injectedScript.querySelector(parsed, this._injectedScript.document, strict);\n  }\n  _querySelectorAll(selector) {\n    if (typeof selector !== "string")\n      throw new Error(`Usage: playwright.$$(\'Playwright >> selector\').`);\n    const parsed = this._injectedScript.parseSelector(selector);\n    return this._injectedScript.querySelectorAll(parsed, this._injectedScript.document);\n  }\n  _inspect(selector) {\n    if (typeof selector !== "string")\n      throw new Error(`Usage: playwright.inspect(\'Playwright >> selector\').`);\n    this._injectedScript.window.inspect(this._querySelector(selector, false));\n  }\n  _selector(element) {\n    if (!(element instanceof Element))\n      throw new Error(`Usage: playwright.selector(element).`);\n    return this._injectedScript.generateSelectorSimple(element);\n  }\n  _generateLocator(element, language) {\n    if (!(element instanceof Element))\n      throw new Error(`Usage: playwright.locator(element).`);\n    const selector = this._injectedScript.generateSelectorSimple(element);\n    return asLocator(language || "javascript", selector);\n  }\n  _resume() {\n    this._injectedScript.window.__pw_resume().catch(() => {\n    });\n  }\n};\nvar consoleApi_default = ConsoleAPI;\n';
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  source
});
