{"version":3,"sources":["../src/express-useragent.ts","../src/index.ts"],"sourcesContent":["import type { IncomingHttpHeaders } from 'http';\n\n/**\n * Represents a single brand entry from User-Agent Client Hints\n * @see https://wicg.github.io/ua-client-hints/\n */\nexport interface ClientHintBrand {\n  brand: string;\n  version: string;\n}\n\n/**\n * Parsed User-Agent Client Hints data from HTTP headers\n * Maps to the NavigatorUAData interface exposed by browsers\n */\nexport interface ClientHints {\n  brands: ClientHintBrand[];\n  mobile: boolean;\n  platform: string;\n  platformVersion: string;\n  architecture: string;\n  bitness: string;\n  model: string;\n  fullVersionList: ClientHintBrand[];\n}\n\nconst BOTS = [\n  '\\\\+https:\\\\/\\\\/developers.google.com\\\\/\\\\+\\\\/web\\\\/snippet\\\\/',\n  'ad\\\\smonitoring',\n  'adsbot',\n  'apex',\n  'applebot',\n  'archive.org_bot',\n  'baiduspider',\n  'bingbot',\n  'chromeheadless',\n  'cloudflare',\n  'cloudinary',\n  'crawler',\n  'curl',\n  'discordbot',\n  'duckduckbot',\n  'embedly',\n  'exabot',\n  'facebookexternalhit',\n  'facebot',\n  'flipboard',\n  'google',\n  'googlebot',\n  'gsa-crawler',\n  'gurujibot',\n  'guzzlehttp',\n  'heritrix',\n  'ia_archiver',\n  'insights',\n  'linkedinbot',\n  'ltx71',\n  'mediapartners',\n  'msnbot',\n  'odklbot',\n  'phantom\\\\.js',\n  'phantomjs',\n  'pingdom',\n  'pinterest',\n  'python',\n  'rtlnieuws',\n  'skypeuripreview',\n  'slackbot',\n  'slurp',\n  'spbot',\n  'telegrambot',\n  'test\\\\scertificate',\n  'testing',\n  'tiabot',\n  'tumblr ',\n  'twitterbot',\n  'vkshare',\n  'web\\\\sscraper',\n  'wget',\n  'yandexbot',\n  'whatsapp',\n  'orangebot',\n  'smtbot',\n  'qwantify',\n  'mj12bot',\n  'ahrefsbot',\n  'seznambot',\n  'panscient\\\\.com',\n  'duckduckgo-favicons-bot',\n  'uptimerobot',\n  'semrushbot',\n  'postman',\n  'dotbot',\n  'zoominfobot',\n  'ifttt',\n  'sogou',\n  'ru_bot',\n  'researchscan',\n  'nimbostratus-bot',\n  'slack-imgproxy',\n  'node-superagent',\n  'go-http-client',\n  'jersey',\n  'dataprovider.com',\n  'github-camo',\n  'dispatch',\n  'checkmarknetwork',\n  'screaming frog',\n  'whatweb',\n  'daum',\n  'netcraftsurveyagent',\n  'mojeekbot',\n  'surdotlybot',\n  'springbot',\n] as const;\n\nconst IS_BOT_REGEXP = new RegExp(`(${BOTS.join('|')})`, 'i');\nconst SILK_REGEXP = /silk/i;\nconst SILK_ACCELERATED_REGEXP = /Silk-Accelerated=true/i;\nconst SMART_TV_REGEXP = /smart-tv|smarttv|googletv|appletv|hbbtv|pov_tv|netcast.tv/i;\nconst ANDROID_TABLET_REGEXP = /mobile/i;\nconst MOBILE_REGEXP = /mobile|^ios-/i;\nconst DALVIK_REGEXP = /dalvik/i;\nconst IOS_SCALE_REGEXP = /scale/i;\nconst OKHTTP_REGEXP = /okhttp/i;\nconst WEBKIT_REGEXP = /applewebkit/i;\nconst WECHAT_REGEXP = /micromessenger/i;\n\nexport interface AgentDetails extends Record<string, unknown> {\n  isYaBrowser: boolean;\n  isAuthoritative: boolean;\n  isMobile: boolean;\n  isMobileNative: boolean;\n  isTablet: boolean;\n  isiPad: boolean;\n  isiPod: boolean;\n  isiPhone: boolean;\n  isiPhoneNative: boolean;\n  isAndroid: boolean;\n  isAndroidNative: boolean;\n  isBlackberry: boolean;\n  isOpera: boolean;\n  isIE: boolean;\n  isEdge: boolean;\n  isIECompatibilityMode: boolean;\n  isSafari: boolean;\n  isFirefox: boolean;\n  isWebkit: boolean;\n  isChrome: boolean;\n  isKonqueror: boolean;\n  isOmniWeb: boolean;\n  isSeaMonkey: boolean;\n  isFlock: boolean;\n  isAmaya: boolean;\n  isPhantomJS: boolean;\n  isEpiphany: boolean;\n  isDesktop: boolean;\n  isWindows: boolean;\n  isLinux: boolean;\n  isLinux64: boolean;\n  isMac: boolean;\n  isChromeOS: boolean;\n  isBada: boolean;\n  isSamsung: boolean;\n  isRaspberry: boolean;\n  isBot: boolean;\n  botName: string;\n  isCurl: boolean;\n  isAndroidTablet: boolean;\n  isWinJs: boolean;\n  isKindleFire: boolean;\n  isSilk: boolean;\n  isCaptive: boolean;\n  isSmartTV: boolean;\n  isUC: boolean;\n  isFacebook: boolean;\n  isAlamoFire: boolean;\n  isElectron: boolean;\n  silkAccelerated: boolean;\n  browser: string;\n  version: string | number;\n  os: string;\n  platform: string;\n  geoIp: Record<string, string | string[]>;\n  source: string;\n  isWechat: boolean;\n  isWindowsPhone: boolean;\n  electronVersion: string;\n  SilkAccelerated?: boolean;\n  /** DuckDuckGo browser detected via Client Hints brand or WebKit UA pattern */\n  isDuckDuckGo: boolean;\n  /** Parsed User-Agent Client Hints when available */\n  clientHints: ClientHints | null;\n}\n\nexport type HeadersLike = Partial<Record<string, string | string[] | undefined>>;\n\nconst DEFAULT_AGENT: AgentDetails = {\n  isYaBrowser: false,\n  isAuthoritative: true,\n  isMobile: false,\n  isMobileNative: false,\n  isTablet: false,\n  isiPad: false,\n  isiPod: false,\n  isiPhone: false,\n  isiPhoneNative: false,\n  isAndroid: false,\n  isAndroidNative: false,\n  isBlackberry: false,\n  isOpera: false,\n  isIE: false,\n  isEdge: false,\n  isIECompatibilityMode: false,\n  isSafari: false,\n  isFirefox: false,\n  isWebkit: false,\n  isChrome: false,\n  isKonqueror: false,\n  isOmniWeb: false,\n  isSeaMonkey: false,\n  isFlock: false,\n  isAmaya: false,\n  isPhantomJS: false,\n  isEpiphany: false,\n  isDesktop: false,\n  isWindows: false,\n  isLinux: false,\n  isLinux64: false,\n  isMac: false,\n  isChromeOS: false,\n  isBada: false,\n  isSamsung: false,\n  isRaspberry: false,\n  isBot: false,\n  botName: '',\n  isCurl: false,\n  isAndroidTablet: false,\n  isWinJs: false,\n  isKindleFire: false,\n  isSilk: false,\n  isCaptive: false,\n  isSmartTV: false,\n  isUC: false,\n  isFacebook: false,\n  isAlamoFire: false,\n  isElectron: false,\n  silkAccelerated: false,\n  browser: 'unknown',\n  version: 'unknown',\n  os: 'unknown',\n  platform: 'unknown',\n  isWechat: false,\n  isWindowsPhone: false,\n  SilkAccelerated: false,\n  geoIp: {},\n  source: '',\n  electronVersion: '',\n  isDuckDuckGo: false,\n  clientHints: null,\n};\n\nfunction createDefaultAgent(): AgentDetails {\n  return {\n    ...DEFAULT_AGENT,\n    geoIp: {},\n    source: '',\n    electronVersion: '',\n    botName: '',\n    clientHints: null,\n  };\n}\n\ninterface ProductToken {\n  name: string;\n  version: string;\n}\n\nconst isProductTokenChar = (charCode: number): boolean =>\n  (charCode >= 48 && charCode <= 57) ||\n  (charCode >= 65 && charCode <= 90) ||\n  (charCode >= 97 && charCode <= 122) ||\n  charCode === 45 ||\n  charCode === 46 ||\n  charCode === 95;\n\nconst isDigit = (charCode: number): boolean => charCode >= 48 && charCode <= 57;\n\nconst readProductToken = (source: string, startIndex = 0): ProductToken | null => {\n  const slashIndex = source.indexOf('/', startIndex);\n  if (slashIndex <= startIndex) {\n    return null;\n  }\n\n  for (let index = startIndex; index < slashIndex; index += 1) {\n    if (!isProductTokenChar(source.charCodeAt(index))) {\n      return null;\n    }\n  }\n\n  let endIndex = slashIndex + 1;\n  while (endIndex < source.length && isProductTokenChar(source.charCodeAt(endIndex))) {\n    endIndex += 1;\n  }\n\n  if (endIndex === slashIndex + 1) {\n    return null;\n  }\n\n  return {\n    name: source.slice(startIndex, slashIndex),\n    version: source.slice(slashIndex + 1, endIndex),\n  };\n};\n\nconst readVersionAfterProduct = (source: string, productName: string): string | null => {\n  const token = readProductToken(source);\n  return token?.name.toLowerCase() === productName.toLowerCase() ? token.version : null;\n};\n\nconst readVersionAfterKnownPrefix = (\n  source: string,\n  prefixes: readonly string[],\n): string | null => {\n  const lowerSource = source.toLowerCase();\n  let bestStart = -1;\n  let bestPrefix = '';\n\n  for (const prefix of prefixes) {\n    const prefixStart = lowerSource.indexOf(prefix.toLowerCase());\n    if (prefixStart !== -1 && (bestStart === -1 || prefixStart < bestStart)) {\n      bestStart = prefixStart;\n      bestPrefix = prefix;\n    }\n  }\n\n  if (bestStart === -1) {\n    return null;\n  }\n\n  const versionStart = bestStart + bestPrefix.length;\n  let versionEnd = versionStart;\n  while (versionEnd < source.length && isProductTokenChar(source.charCodeAt(versionEnd))) {\n    versionEnd += 1;\n  }\n\n  return versionEnd > versionStart ? source.slice(versionStart, versionEnd) : null;\n};\n\nconst readVersionAfterKnownProduct = (\n  source: string,\n  productNames: readonly string[],\n): string | null =>\n  readVersionAfterKnownPrefix(\n    source,\n    productNames.map((productName) => `${productName}/`),\n  );\n\nconst readInternetExplorerVersion = (source: string): string | null => {\n  const lowerSource = source.toLowerCase();\n  const msieIndex = lowerSource.indexOf('msie');\n  if (msieIndex !== -1) {\n    let versionStart = msieIndex + 4;\n    while (source[versionStart] === ' ') {\n      versionStart += 1;\n    }\n\n    let versionEnd = versionStart;\n    while (versionEnd < source.length) {\n      const charCode = source.charCodeAt(versionEnd);\n      if (!isDigit(charCode) && charCode !== 46) {\n        break;\n      }\n      versionEnd += 1;\n    }\n\n    if (versionEnd > versionStart) {\n      return source.slice(versionStart, versionEnd);\n    }\n  }\n\n  const tridentIndex = lowerSource.indexOf('trident/');\n  if (tridentIndex === -1) {\n    return null;\n  }\n\n  const rvIndex = lowerSource.indexOf('rv:', tridentIndex + 8);\n  if (rvIndex === -1) {\n    return null;\n  }\n\n  const versionStart = rvIndex + 3;\n  let versionEnd = versionStart;\n  while (versionEnd < source.length) {\n    const charCode = source.charCodeAt(versionEnd);\n    if (!isDigit(charCode) && charCode !== 46) {\n      break;\n    }\n    versionEnd += 1;\n  }\n\n  return versionEnd > versionStart ? source.slice(versionStart, versionEnd) : null;\n};\n\nconst readTrailingProductToken = (source: string, requireClosingParen: boolean): string | null => {\n  let endIndex = source.length;\n  while (endIndex > 0 && source.charCodeAt(endIndex - 1) === 32) {\n    endIndex -= 1;\n  }\n\n  if (source[endIndex - 1] === ')') {\n    endIndex -= 1;\n  } else if (requireClosingParen) {\n    return null;\n  }\n\n  let startIndex = endIndex;\n  while (startIndex > 0 && isProductTokenChar(source.charCodeAt(startIndex - 1))) {\n    startIndex -= 1;\n  }\n\n  return startIndex < endIndex ? source.slice(startIndex, endIndex) : null;\n};\n\nconst readIOSDeviceOSMatch = (source: string, device: 'iPad' | 'iPhone'): string | null => {\n  const deviceLower = device.toLowerCase();\n  let searchFrom = 0;\n\n  while (searchFrom < source.length) {\n    const openIndex = source.indexOf('(', searchFrom);\n    if (openIndex === -1) {\n      return null;\n    }\n\n    const closeIndex = source.indexOf(')', openIndex + 1);\n    const segmentEnd = closeIndex === -1 ? source.length : closeIndex;\n    const segment = source.slice(openIndex + 1, segmentEnd);\n    const segmentLower = segment.toLowerCase();\n\n    if (segmentLower.startsWith(deviceLower)) {\n      let osSearchFrom = 0;\n      while (osSearchFrom < segmentLower.length) {\n        const osIndex = segmentLower.indexOf('os ', osSearchFrom);\n        if (osIndex === -1) {\n          break;\n        }\n\n        let versionStart = osIndex + 3;\n        while (segment[versionStart] === ' ') {\n          versionStart += 1;\n        }\n\n        let majorEnd = versionStart;\n        while (majorEnd < segment.length && isDigit(segment.charCodeAt(majorEnd))) {\n          majorEnd += 1;\n        }\n\n        const separator = segment[majorEnd];\n        if (majorEnd > versionStart && (separator === '.' || separator === '_')) {\n          let minorEnd = majorEnd + 1;\n          while (minorEnd < segment.length && isDigit(segment.charCodeAt(minorEnd))) {\n            minorEnd += 1;\n          }\n\n          if (minorEnd > majorEnd + 1) {\n            return `(${segment.slice(0, minorEnd)}`.replace('_', '.');\n          }\n        }\n\n        osSearchFrom = osIndex + 3;\n      }\n    }\n\n    searchFrom = segmentEnd + 1;\n  }\n\n  return null;\n};\n\n/** WebKit DuckDuckGo pattern: \" Ddg/X.Y.Z\" at end of UA string */\nconst DUCKDUCKGO_WEBKIT_REGEXP = /\\sDdg\\/\\d+(?:\\.\\d+)*$/;\n\nexport class UserAgent {\n  private readonly versions: Record<string, RegExp> = {\n    Edge: /(?:edge|edga|edgios|edg)\\/([A-Za-z0-9_.-]+)/i,\n    Firefox: /(?:firefox|fxios)\\/([A-Za-z0-9_.-]+)/i,\n    IE: /msie\\s(\\d+(?:\\.\\d+)?)|trident\\/\\d+(?:\\.\\d+)?;[^)]*\\brv:(\\d+(?:\\.\\d+)?)/i,\n    YaBrowser: /(?:yabrowser|yowser)\\/([A-Za-z0-9_.-]+)/i,\n    Chrome: /(?:chrome|crios)\\/([A-Za-z0-9_.-]+)/i,\n    Chromium: /chromium\\/([A-Za-z0-9_.-]+)/i,\n    Safari: /(version|safari)\\/([A-Za-z0-9_.-]+)/i,\n    Opera: /version\\/([A-Za-z0-9_.-]+)|OPR\\/([A-Za-z0-9_.-]+)/i,\n    Amaya: /amaya\\/([A-Za-z0-9_.-]+)/i,\n    SeaMonkey: /seamonkey\\/([A-Za-z0-9_.-]+)/i,\n    OmniWeb: /omniweb\\/v([A-Za-z0-9_.-]+)/i,\n    Flock: /flock\\/([A-Za-z0-9_.-]+)/i,\n    Epiphany: /epiphany\\/([A-Za-z0-9_.-]+)/i,\n    WinJs: /msapphost\\/([A-Za-z0-9_.-]+)/i,\n    PhantomJS: /phantomjs\\/([A-Za-z0-9_.-]+)/i,\n    AlamoFire: /alamofire\\/([A-Za-z0-9_.-]+)/i,\n    UC: /ucbrowser\\/([A-Za-z0-9_.]+)/i,\n    Facebook: /FBAV\\/([A-Za-z0-9_.]+)/i,\n    WebKit: /applewebkit\\/([A-Za-z0-9_.]+)/i,\n    Wechat: /micromessenger\\/([A-Za-z0-9_.]+)/i,\n    Electron: /Electron\\/([A-Za-z0-9_.]+)/i,\n    DuckDuckGo: /\\sDdg\\/(\\d+(?:\\.\\d+)*)$/i,\n  };\n\n  private readonly browsers: Record<string, RegExp> = {\n    YaBrowser: /yabrowser|yowser/i,\n    Edge: /edge|edga|edgios|edg/i,\n    Amaya: /amaya/i,\n    Konqueror: /konqueror/i,\n    Epiphany: /epiphany/i,\n    SeaMonkey: /seamonkey/i,\n    Flock: /flock/i,\n    OmniWeb: /omniweb/i,\n    Chromium: /chromium/i,\n    Chrome: /chrome|crios/i,\n    Safari: /safari/i,\n    IE: /msie|trident/i,\n    Opera: /opera|OPR\\//i,\n    PS3: /playstation 3/i,\n    PSP: /playstation portable/i,\n    Firefox: /firefox|fxios/i,\n    WinJs: /msapphost/i,\n    PhantomJS: /phantomjs/i,\n    AlamoFire: /alamofire/i,\n    UC: /UCBrowser/i,\n    Facebook: /FBA[NV]/,\n    DuckDuckGo: /\\sDdg\\/[\\d.]+$/i,\n  };\n\n  private readonly os: Record<string, RegExp> = {\n    Windows11: /\\bwindows(?:\\s|_|)11(?:\\.\\d+)?/i,\n    Windows10: /windows nt 10\\.0/i,\n    Windows81: /windows nt 6\\.3/i,\n    Windows8: /windows nt 6\\.2/i,\n    Windows7: /windows nt 6\\.1/i,\n    UnknownWindows: /windows nt 6\\.\\d+/i,\n    WindowsVista: /windows nt 6\\.0/i,\n    Windows2003: /windows nt 5\\.2/i,\n    WindowsXP: /windows nt 5\\.1/i,\n    Windows2000: /windows nt 5\\.0/i,\n    WindowsPhone81: /windows phone 8\\.1/i,\n    WindowsPhone80: /windows phone 8\\.0/i,\n    OSXCheetah: /os x 10[._]0/i,\n    OSXPuma: /os x 10[._]1(\\D|$)/i,\n    OSXJaguar: /os x 10[._]2/i,\n    OSXPanther: /os x 10[._]3/i,\n    OSXTiger: /os x 10[._]4/i,\n    OSXLeopard: /os x 10[._]5/i,\n    OSXSnowLeopard: /os x 10[._]6/i,\n    OSXLion: /os x 10[._]7/i,\n    OSXMountainLion: /os x 10[._]8/i,\n    OSXMavericks: /os x 10[._]9/i,\n    OSXYosemite: /os x 10[._]10/i,\n    OSXElCapitan: /os x 10[._]11/i,\n    MacOSSierra: /os x 10[._]12/i,\n    MacOSHighSierra: /os x 10[._]13/i,\n    MacOSMojave: /os x 10[._]14/i,\n    MacOSCatalina: /os x 10[._]15/i,\n    MacOSBigSur: /(mac os x 10[._]16(?:[._]\\d+)?|mac os (?:x )?11[._]\\d+)/i,\n    MacOSMonterey: /mac os (?:x )?12[._]\\d+/i,\n    MacOSVentura: /mac os (?:x )?13[._]\\d+/i,\n    MacOSSonoma: /mac os (?:x )?14[._]\\d+/i,\n    MacOSSequoia: /mac os (?:x )?15[._]\\d+/i,\n    MacOSTahoe: /mac os (?:x )?26[._]\\d+/i,\n    Mac: /os x/i,\n    Linux: /linux/i,\n    Linux64: /linux x86_64/i,\n    ChromeOS: /cros/i,\n    Wii: /wii/i,\n    PS3: /playstation 3/i,\n    PSP: /playstation portable/i,\n    iOS: /ios/i,\n    Bada: /Bada\\/(\\d+)\\.(\\d+)/i,\n    Curl: /curl\\/(\\d+)\\.(\\d+)\\.(\\d+)/i,\n    Electron: /Electron\\/(\\d+)\\.(\\d+)\\.(\\d+)/i,\n  };\n\n  private readonly platform: Record<string, RegExp> = {\n    Windows: /windows nt/i,\n    WindowsPhone: /windows phone/i,\n    Mac: /macintosh/i,\n    Linux: /linux/i,\n    Wii: /wii/i,\n    Playstation: /playstation/i,\n    iPad: /ipad/i,\n    iPod: /ipod/i,\n    iPhone: /iphone/i,\n    Android: /android/i,\n    Blackberry: /blackberry/i,\n    Samsung: /samsung/i,\n    Curl: /curl/i,\n    Electron: /Electron/i,\n    iOS: /^ios-/i,\n  };\n\n  public Agent: AgentDetails;\n\n  constructor() {\n    this.Agent = createDefaultAgent();\n  }\n\n  public reset(): this {\n    this.Agent = createDefaultAgent();\n    return this;\n  }\n\n  public testNginxGeoIP(headers: HeadersLike | IncomingHttpHeaders): this {\n    Object.entries(headers ?? {}).forEach(([key, value]) => {\n      if (/^GEOIP/i.test(key) && value !== undefined) {\n        this.Agent.geoIp[key] = Array.isArray(value) ? value.join(',') : value;\n      }\n    });\n    return this;\n  }\n\n  /** Maximum header length to process (prevents DoS from oversized headers) */\n  private static readonly MAX_HEADER_LENGTH = 2048;\n  /** Maximum number of brands to parse from a brand list */\n  private static readonly MAX_BRAND_COUNT = 20;\n\n  /**\n   * Parse User-Agent Client Hints from HTTP headers\n   * @see https://wicg.github.io/ua-client-hints/\n   */\n  public parseClientHints(headers: HeadersLike | IncomingHttpHeaders): ClientHints | null {\n    const resolveHeader = (value: string | string[] | undefined): string => {\n      try {\n        if (value === null || value === undefined) {\n          return '';\n        }\n        if (Array.isArray(value)) {\n          const first = value[0];\n          if (typeof first !== 'string') {\n            return '';\n          }\n          return first.slice(0, UserAgent.MAX_HEADER_LENGTH);\n        }\n        if (typeof value !== 'string') {\n          return '';\n        }\n        return value.slice(0, UserAgent.MAX_HEADER_LENGTH);\n      } catch {\n        return '';\n      }\n    };\n\n    // Validate headers input\n    if (headers === null || headers === undefined || typeof headers !== 'object') {\n      return null;\n    }\n\n    // Normalize header keys to lowercase for case-insensitive lookup\n    const normalizedHeaders: Record<string, string> = {};\n    try {\n      let headerCount = 0;\n      const maxHeaders = 50; // Limit iterations over headers object\n      for (const [key, value] of Object.entries(headers)) {\n        if (++headerCount > maxHeaders) break;\n        if (typeof key !== 'string') continue;\n        normalizedHeaders[key.toLowerCase()] = resolveHeader(value);\n      }\n    } catch {\n      return null;\n    }\n\n    const secChUa = normalizedHeaders['sec-ch-ua'];\n    // Return null if no client hints are present\n    if (!secChUa) {\n      return null;\n    }\n\n    const parseBrandList = (header: string): ClientHintBrand[] => {\n      try {\n        if (!header || typeof header !== 'string') return [];\n        const brands: ClientHintBrand[] = [];\n        // Match patterns like: \"Brand\";v=\"version\" or \"Brand\"; v=\"version\"\n        const brandRegex = /\"([^\"]{1,128})\";\\s*v=\"([^\"]{1,64})\"/g;\n        let match;\n        let iterations = 0;\n        while ((match = brandRegex.exec(header)) !== null) {\n          if (++iterations > UserAgent.MAX_BRAND_COUNT) break;\n          brands.push({ brand: match[1], version: match[2] });\n        }\n        return brands;\n      } catch {\n        return [];\n      }\n    };\n\n    const parseMobile = (header: string): boolean => {\n      try {\n        // ?1 = true, ?0 or empty = false\n        if (typeof header !== 'string') return false;\n        return header === '?1';\n      } catch {\n        return false;\n      }\n    };\n\n    const parseQuotedString = (header: string): string => {\n      try {\n        if (typeof header !== 'string') return '';\n        // Limit input length before regex\n        const truncated = header.slice(0, 256);\n        // Remove surrounding quotes if present\n        const match = /^\"([^\"]*)\"$/.exec(truncated);\n        return match ? match[1] : truncated;\n      } catch {\n        return '';\n      }\n    };\n\n    try {\n      const clientHints: ClientHints = {\n        brands: parseBrandList(secChUa),\n        mobile: parseMobile(normalizedHeaders['sec-ch-ua-mobile'] ?? ''),\n        platform: parseQuotedString(normalizedHeaders['sec-ch-ua-platform'] ?? ''),\n        platformVersion: parseQuotedString(normalizedHeaders['sec-ch-ua-platform-version'] ?? ''),\n        architecture: parseQuotedString(normalizedHeaders['sec-ch-ua-arch'] ?? ''),\n        bitness: parseQuotedString(normalizedHeaders['sec-ch-ua-bitness'] ?? ''),\n        model: parseQuotedString(normalizedHeaders['sec-ch-ua-model'] ?? ''),\n        fullVersionList: parseBrandList(normalizedHeaders['sec-ch-ua-full-version-list'] ?? ''),\n      };\n\n      this.Agent.clientHints = clientHints;\n      return clientHints;\n    } catch {\n      return null;\n    }\n  }\n\n  /**\n   * Test for DuckDuckGo browser using both Client Hints and UA string patterns\n   * - Chromium platforms (Android, Windows): Sec-CH-UA brand \"DuckDuckGo\"\n   * - WebKit platforms (iOS, macOS): UA string ends with \" Ddg/X.Y.Z\"\n   */\n  public testDuckDuckGo(): void {\n    // Check client hints brands first (Chromium-based DDG)\n    if (this.Agent.clientHints?.brands) {\n      const hasDdgBrand = this.Agent.clientHints.brands.some(\n        (brand) => brand.brand === 'DuckDuckGo',\n      );\n      if (hasDdgBrand) {\n        this.Agent.isDuckDuckGo = true;\n        this.Agent.browser = 'DuckDuckGo';\n        this.Agent.version = this.getDuckDuckGoVersion() ?? 'unknown';\n        return;\n      }\n    }\n\n    // Check full version list as well\n    if (this.Agent.clientHints?.fullVersionList) {\n      const hasDdgBrand = this.Agent.clientHints.fullVersionList.some(\n        (brand) => brand.brand === 'DuckDuckGo',\n      );\n      if (hasDdgBrand) {\n        this.Agent.isDuckDuckGo = true;\n        this.Agent.browser = 'DuckDuckGo';\n        this.Agent.version = this.getDuckDuckGoVersion() ?? 'unknown';\n        return;\n      }\n    }\n\n    // Fallback: check WebKit UA string pattern (iOS/macOS DDG)\n    if (DUCKDUCKGO_WEBKIT_REGEXP.test(this.Agent.source)) {\n      this.Agent.isDuckDuckGo = true;\n      this.Agent.browser = 'DuckDuckGo';\n      this.Agent.version = this.getDuckDuckGoVersion() ?? 'unknown';\n    }\n  }\n\n  public testBot(): void {\n    const source = this.Agent.source.toLowerCase();\n    const match = IS_BOT_REGEXP.exec(source);\n\n    if (match) {\n      const botIdentifier = match[1];\n\n      // Handle false positives - TikTok WebView contains \"googleplay\" but isn't a bot\n      if (\n        botIdentifier === 'google' &&\n        (source.includes('tiktok') || source.includes('trill') || source.includes('bytedance'))\n      ) {\n        this.Agent.isBot = false;\n        this.Agent.botName = '';\n        return;\n      }\n\n      // For all bots, return boolean true and store bot name (fixes issues #168, #138)\n      this.Agent.isBot = true;\n      this.Agent.botName = botIdentifier;\n    } else if (!this.Agent.isAuthoritative) {\n      this.Agent.isBot = /bot/i.test(this.Agent.source);\n      this.Agent.botName = this.Agent.isBot ? 'bot' : '';\n    } else {\n      this.Agent.isBot = false;\n      this.Agent.botName = '';\n    }\n  }\n\n  public testSmartTV(): void {\n    this.Agent.isSmartTV = SMART_TV_REGEXP.test(this.Agent.source.toLowerCase());\n  }\n\n  public testMobile(): void {\n    if (this.Agent.isWindows || this.Agent.isLinux || this.Agent.isMac || this.Agent.isChromeOS) {\n      this.Agent.isDesktop = true;\n    } else if (this.Agent.isAndroid || this.Agent.isSamsung) {\n      this.Agent.isMobile = true;\n    }\n\n    if (\n      this.Agent.isiPad ||\n      this.Agent.isiPod ||\n      this.Agent.isiPhone ||\n      this.Agent.isBada ||\n      this.Agent.isBlackberry ||\n      this.Agent.isAndroid ||\n      this.Agent.isWindowsPhone\n    ) {\n      this.Agent.isMobile = true;\n      this.Agent.isDesktop = false;\n    }\n\n    if (MOBILE_REGEXP.test(this.Agent.source)) {\n      this.Agent.isMobile = true;\n      this.Agent.isDesktop = false;\n    }\n\n    if (DALVIK_REGEXP.test(this.Agent.source)) {\n      this.Agent.isAndroidNative = true;\n      this.Agent.isMobileNative = true;\n    }\n\n    if (OKHTTP_REGEXP.test(this.Agent.source)) {\n      this.Agent.isAndroidNative = true;\n      this.Agent.isMobileNative = true;\n      this.Agent.isMobile = true;\n      this.Agent.isAndroid = true;\n      this.Agent.isDesktop = false;\n    }\n\n    if (IOS_SCALE_REGEXP.test(this.Agent.source)) {\n      this.Agent.isiPhoneNative = true;\n      this.Agent.isMobileNative = true;\n    }\n  }\n\n  public testAndroidTablet(): void {\n    if (this.Agent.isAndroid && !ANDROID_TABLET_REGEXP.test(this.Agent.source)) {\n      this.Agent.isAndroidTablet = true;\n    }\n  }\n\n  public testTablet(): void {\n    if (this.Agent.isiPad || this.Agent.isAndroidTablet || this.Agent.isKindleFire) {\n      this.Agent.isTablet = true;\n    }\n\n    if (/tablet/i.test(this.Agent.source)) {\n      this.Agent.isTablet = true;\n    }\n  }\n\n  public testCompatibilityMode(): void {\n    if (!this.Agent.isIE) {\n      return;\n    }\n\n    const tridentMatch = /Trident\\/(\\d)\\.0/i.exec(this.Agent.source);\n    if (!tridentMatch) {\n      return;\n    }\n\n    const tridentVersion = parseInt(tridentMatch[1], 10);\n    const version = parseInt(String(this.Agent.version), 10);\n\n    if (version === 7 && tridentVersion === 7) {\n      this.Agent.isIECompatibilityMode = true;\n      this.Agent.version = '11.0';\n    }\n    if (version === 7 && tridentVersion === 6) {\n      this.Agent.isIECompatibilityMode = true;\n      this.Agent.version = '10.0';\n    }\n    if (version === 7 && tridentVersion === 5) {\n      this.Agent.isIECompatibilityMode = true;\n      this.Agent.version = '9.0';\n    }\n    if (version === 7 && tridentVersion === 4) {\n      this.Agent.isIECompatibilityMode = true;\n      this.Agent.version = '8.0';\n    }\n  }\n\n  public testSilk(): string | false {\n    if (SILK_REGEXP.test(this.Agent.source)) {\n      this.Agent.isSilk = true;\n    }\n\n    if (SILK_ACCELERATED_REGEXP.test(this.Agent.source)) {\n      this.Agent.silkAccelerated = true;\n      this.Agent.SilkAccelerated = true;\n    }\n\n    return this.Agent.isSilk ? 'Silk' : false;\n  }\n\n  public testKindleFire(): string | false {\n    const { source } = this.Agent;\n    if (/KFOT/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire';\n    }\n    if (/KFTT/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire HD';\n    }\n    if (/KFJWI/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire HD 8.9';\n    }\n    if (/KFJWA/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire HD 8.9 4G';\n    }\n    if (/KFSOWI/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire HD 7';\n    }\n    if (/KFTHWI/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire HDX 7';\n    }\n    if (/KFTHWA/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire HDX 7 4G';\n    }\n    if (/KFAPWI/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire HDX 8.9';\n    }\n    if (/KFAPWA/gi.test(source)) {\n      this.Agent.isKindleFire = true;\n      return 'Kindle Fire HDX 8.9 4G';\n    }\n    return false;\n  }\n\n  public testCaptiveNetwork(): string | false {\n    if (/CaptiveNetwork/gi.test(this.Agent.source)) {\n      this.Agent.isCaptive = true;\n      this.Agent.isMac = true;\n      this.Agent.platform = 'Apple Mac';\n      return 'CaptiveNetwork';\n    }\n    return false;\n  }\n\n  public testWebkit(): void {\n    if (this.Agent.browser === 'unknown' && WEBKIT_REGEXP.test(this.Agent.source)) {\n      this.Agent.browser = 'Apple WebKit';\n      this.Agent.isWebkit = true;\n    }\n  }\n\n  public testWechat(): void {\n    if (WECHAT_REGEXP.test(this.Agent.source)) {\n      this.Agent.isWechat = true;\n      this.Agent.version = this.getWechatVersion(this.Agent.source);\n    }\n  }\n\n  public parse(source: string): AgentDetails {\n    return new UserAgent().hydrate(source).Agent;\n  }\n\n  /**\n   * Hydrate agent from UA string and HTTP headers (including Client Hints)\n   * This method should be preferred when headers are available as it enables\n   * detection of browsers that use Client Hints (e.g., DuckDuckGo on Chromium)\n   */\n  public hydrateFromHeaders(source: string, headers: HeadersLike | IncomingHttpHeaders): this {\n    this.hydrate(source);\n    this.parseClientHints(headers);\n    this.testDuckDuckGo();\n    return this;\n  }\n\n  public hydrate(source: string): this {\n    this.Agent = createDefaultAgent();\n    this.Agent.source = source.trim();\n    this.Agent.os = this.getOS(this.Agent.source);\n    this.Agent.platform = this.getPlatform(this.Agent.source);\n    this.Agent.browser = this.getBrowser(this.Agent.source);\n    this.Agent.version = this.getBrowserVersion(this.Agent.source);\n    this.Agent.electronVersion = this.getElectronVersion(this.Agent.source);\n    this.testBot();\n    this.testSmartTV();\n    this.testMobile();\n    this.testAndroidTablet();\n    this.testTablet();\n    this.testCompatibilityMode();\n    this.testSilk();\n    this.testKindleFire();\n    this.testCaptiveNetwork();\n    this.testWebkit();\n    this.testWechat();\n    return this;\n  }\n\n  private getBrowser(string: string): string {\n    const agent = this.Agent;\n    if (this.browsers.YaBrowser.test(string)) {\n      agent.isYaBrowser = true;\n      return 'YaBrowser';\n    }\n    if (this.browsers.AlamoFire.test(string)) {\n      agent.isAlamoFire = true;\n      return 'AlamoFire';\n    }\n    if (this.browsers.Edge.test(string)) {\n      agent.isEdge = true;\n      return 'Edge';\n    }\n    if (this.browsers.PhantomJS.test(string)) {\n      agent.isPhantomJS = true;\n      return 'PhantomJS';\n    }\n    if (this.browsers.Konqueror.test(string)) {\n      agent.isKonqueror = true;\n      return 'Konqueror';\n    }\n    if (this.browsers.Amaya.test(string)) {\n      agent.isAmaya = true;\n      return 'Amaya';\n    }\n    if (this.browsers.Epiphany.test(string)) {\n      agent.isEpiphany = true;\n      return 'Epiphany';\n    }\n    if (this.browsers.SeaMonkey.test(string)) {\n      agent.isSeaMonkey = true;\n      return 'SeaMonkey';\n    }\n    if (this.browsers.Flock.test(string)) {\n      agent.isFlock = true;\n      return 'Flock';\n    }\n    if (this.browsers.OmniWeb.test(string)) {\n      agent.isOmniWeb = true;\n      return 'OmniWeb';\n    }\n    if (this.browsers.Opera.test(string)) {\n      agent.isOpera = true;\n      return 'Opera';\n    }\n    if (this.browsers.Chromium.test(string)) {\n      agent.isChrome = true;\n      return 'Chromium';\n    }\n    if (this.browsers.Facebook.test(string)) {\n      agent.isFacebook = true;\n      return 'Facebook';\n    }\n    if (this.browsers.Chrome.test(string)) {\n      agent.isChrome = true;\n      return 'Chrome';\n    }\n    if (this.browsers.WinJs.test(string)) {\n      agent.isWinJs = true;\n      return 'WinJs';\n    }\n    if (this.browsers.IE.test(string)) {\n      agent.isIE = true;\n      return 'IE';\n    }\n    if (this.browsers.Firefox.test(string)) {\n      agent.isFirefox = true;\n      return 'Firefox';\n    }\n    // Android Browser: stock AOSP browser - has Android + Version/ + Mobile Safari/ but no Chrome or other browser tokens (Bug #80)\n    if (\n      /android/i.test(string) &&\n      /version\\//i.test(string) &&\n      /mobile safari\\//i.test(string) &&\n      !/chrome/i.test(string) &&\n      !/silk/i.test(string)\n    ) {\n      agent.isAndroid = true;\n      return 'Android Browser';\n    }\n    if (this.browsers.Safari.test(string)) {\n      agent.isSafari = true;\n      return 'Safari';\n    }\n    if (this.browsers.PS3.test(string)) {\n      return 'ps3';\n    }\n    if (this.browsers.PSP.test(string)) {\n      return 'psp';\n    }\n    if (this.browsers.UC.test(string)) {\n      agent.isUC = true;\n      return 'UCBrowser';\n    }\n\n    if (string.includes('Dalvik')) {\n      return 'unknown';\n    }\n\n    if (!string.startsWith('Mozilla')) {\n      const guess = readProductToken(string);\n      if (guess) {\n        agent.isAuthoritative = false;\n        return guess.name;\n      }\n    }\n\n    return 'unknown';\n  }\n\n  private getBrowserVersion(string: string): string {\n    const agent = this.Agent;\n    const browser = agent.browser;\n\n    switch (browser) {\n      case 'Edge':\n        return readVersionAfterKnownProduct(string, ['edge', 'edga', 'edgios', 'edg']) ?? 'unknown';\n      case 'PhantomJS':\n        return readVersionAfterKnownProduct(string, ['phantomjs']) ?? 'unknown';\n      case 'YaBrowser':\n        return readVersionAfterKnownProduct(string, ['yabrowser', 'yowser']) ?? 'unknown';\n      case 'Chrome':\n        return readVersionAfterKnownProduct(string, ['chrome', 'crios']) ?? 'unknown';\n      case 'Chromium':\n        return readVersionAfterKnownProduct(string, ['chromium']) ?? 'unknown';\n      case 'Safari':\n        return readVersionAfterKnownProduct(string, ['version', 'safari']) ?? 'unknown';\n      case 'Opera':\n        return readVersionAfterKnownProduct(string, ['version', 'OPR']) ?? 'unknown';\n      case 'Firefox':\n        return readVersionAfterKnownProduct(string, ['firefox', 'fxios']) ?? 'unknown';\n      case 'WinJs':\n        return readVersionAfterKnownProduct(string, ['msapphost']) ?? 'unknown';\n      case 'IE':\n        return readInternetExplorerVersion(string) ?? 'unknown';\n      case 'ps3':\n        return readTrailingProductToken(string, true) ?? 'unknown';\n      case 'psp':\n        return readTrailingProductToken(string, false) ?? 'unknown';\n      case 'Amaya':\n        return readVersionAfterKnownProduct(string, ['amaya']) ?? 'unknown';\n      case 'Epiphany':\n        return readVersionAfterKnownProduct(string, ['epiphany']) ?? 'unknown';\n      case 'SeaMonkey':\n        return readVersionAfterKnownProduct(string, ['seamonkey']) ?? 'unknown';\n      case 'Flock':\n        return readVersionAfterKnownProduct(string, ['flock']) ?? 'unknown';\n      case 'OmniWeb':\n        return readVersionAfterKnownPrefix(string, ['omniweb/v']) ?? 'unknown';\n      case 'UCBrowser':\n        return readVersionAfterKnownProduct(string, ['ucbrowser']) ?? 'unknown';\n      case 'Facebook':\n        return readVersionAfterKnownProduct(string, ['FBAV']) ?? 'unknown';\n      case 'Android Browser':\n        // Android Browser reports version via Version/X.X token (Bug #80)\n        return readVersionAfterKnownProduct(string, ['version', 'safari']) ?? 'unknown';\n      case 'DuckDuckGo':\n        return this.getDuckDuckGoVersion() ?? 'unknown';\n      default:\n        if (browser !== 'unknown') {\n          return readVersionAfterProduct(string, browser) ?? 'unknown';\n        } else {\n          this.testWebkit();\n          if (this.Agent.isWebkit) {\n            return readVersionAfterKnownProduct(string, ['applewebkit']) ?? 'unknown';\n          }\n        }\n    }\n\n    return 'unknown';\n  }\n\n  private getWechatVersion(string: string): string {\n    const match = string.match(this.versions.Wechat);\n    return match ? match[1] : 'unknown';\n  }\n\n  private getDuckDuckGoVersion(): string | null {\n    // Try client hints first\n    const hints = this.Agent.clientHints;\n    if (hints) {\n      // Check fullVersionList first for more precise version\n      const fullBrand = hints.fullVersionList.find((b) => b.brand === 'DuckDuckGo');\n      if (fullBrand) {\n        return fullBrand.version;\n      }\n      // Fall back to brands\n      const brand = hints.brands.find((b) => b.brand === 'DuckDuckGo');\n      if (brand) {\n        return brand.version;\n      }\n    }\n    // Fall back to UA string pattern\n    const match = this.Agent.source.match(this.versions.DuckDuckGo);\n    return match ? match[1] : null;\n  }\n\n  private getElectronVersion(string: string): string {\n    const match = string.match(this.versions.Electron);\n    if (match) {\n      this.Agent.isElectron = true;\n      return match[1];\n    }\n    return '';\n  }\n\n  private getOS(string: string): string {\n    if (this.os.WindowsVista.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows Vista';\n    }\n    if (this.os.Windows7.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows 7';\n    }\n    if (this.os.Windows8.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows 8';\n    }\n    if (this.os.Windows81.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows 8.1';\n    }\n    if (this.os.Windows11.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows 11';\n    }\n    if (this.os.Windows10.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows 10.0';\n    }\n    if (this.os.Windows2003.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows 2003';\n    }\n    if (this.os.WindowsXP.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows XP';\n    }\n    if (this.os.Windows2000.test(string)) {\n      this.Agent.isWindows = true;\n      return 'Windows 2000';\n    }\n    if (this.os.WindowsPhone81.test(string)) {\n      this.Agent.isWindowsPhone = true;\n      return 'Windows Phone 8.1';\n    }\n    if (this.os.WindowsPhone80.test(string)) {\n      this.Agent.isWindowsPhone = true;\n      return 'Windows Phone 8.0';\n    }\n    if (this.os.Linux64.test(string)) {\n      this.Agent.isLinux = true;\n      this.Agent.isLinux64 = true;\n      return 'Linux 64';\n    }\n    if (this.os.Linux.test(string)) {\n      this.Agent.isLinux = true;\n      return 'Linux';\n    }\n    if (this.os.ChromeOS.test(string)) {\n      this.Agent.isChromeOS = true;\n      return 'Chrome OS';\n    }\n    if (this.os.Wii.test(string)) {\n      return 'Wii';\n    }\n    if (this.os.PS3.test(string)) {\n      return 'Playstation';\n    }\n    if (this.os.PSP.test(string)) {\n      return 'Playstation';\n    }\n    if (this.os.OSXCheetah.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Cheetah';\n    }\n    if (this.os.OSXPuma.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Puma';\n    }\n    if (this.os.OSXJaguar.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Jaguar';\n    }\n    if (this.os.OSXPanther.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Panther';\n    }\n    if (this.os.OSXTiger.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Tiger';\n    }\n    if (this.os.OSXLeopard.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Leopard';\n    }\n    if (this.os.OSXSnowLeopard.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Snow Leopard';\n    }\n    if (this.os.OSXLion.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Lion';\n    }\n    if (this.os.OSXMountainLion.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Mountain Lion';\n    }\n    if (this.os.OSXMavericks.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Mavericks';\n    }\n    if (this.os.OSXYosemite.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X Yosemite';\n    }\n    if (this.os.OSXElCapitan.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X El Capitan';\n    }\n    if (this.os.MacOSSierra.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Sierra';\n    }\n    if (this.os.MacOSHighSierra.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS High Sierra';\n    }\n    if (this.os.MacOSMojave.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Mojave';\n    }\n    if (this.os.MacOSCatalina.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Catalina';\n    }\n    if (this.os.MacOSBigSur.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Big Sur';\n    }\n    if (this.os.MacOSMonterey.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Monterey';\n    }\n    if (this.os.MacOSVentura.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Ventura';\n    }\n    if (this.os.MacOSSonoma.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Sonoma';\n    }\n    if (this.os.MacOSSequoia.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Sequoia';\n    }\n    if (this.os.MacOSTahoe.test(string)) {\n      this.Agent.isMac = true;\n      return 'macOS Tahoe';\n    }\n    if (this.os.Mac.test(string)) {\n      this.Agent.isMac = true;\n      return 'OS X';\n    }\n    const iPadMatch = readIOSDeviceOSMatch(string, 'iPad');\n    if (iPadMatch) {\n      this.Agent.isiPad = true;\n      return iPadMatch;\n    }\n    const iPhoneMatch = readIOSDeviceOSMatch(string, 'iPhone');\n    if (iPhoneMatch) {\n      this.Agent.isiPhone = true;\n      return iPhoneMatch;\n    }\n    if (this.os.Bada.test(string)) {\n      this.Agent.isBada = true;\n      return 'Bada';\n    }\n    if (this.os.Curl.test(string)) {\n      this.Agent.isCurl = true;\n      return 'Curl';\n    }\n    if (this.os.iOS.test(string)) {\n      this.Agent.isiPhone = true;\n      return 'iOS';\n    }\n    if (this.os.Electron.test(string)) {\n      this.Agent.isElectron = true;\n      return 'Electron';\n    }\n    return 'unknown';\n  }\n\n  private getPlatform(string: string): string {\n    if (this.platform.Windows.test(string)) {\n      return 'Microsoft Windows';\n    }\n    if (this.platform.WindowsPhone.test(string)) {\n      this.Agent.isWindowsPhone = true;\n      return 'Microsoft Windows Phone';\n    }\n    if (this.platform.Mac.test(string)) {\n      return 'Apple Mac';\n    }\n    if (this.platform.Curl.test(string)) {\n      return 'Curl';\n    }\n    if (this.platform.Electron.test(string)) {\n      this.Agent.isElectron = true;\n      return 'Electron';\n    }\n    if (this.platform.Android.test(string)) {\n      this.Agent.isAndroid = true;\n      // Also detect Samsung devices within Android platform (Bug #104)\n      if (this.platform.Samsung.test(string)) {\n        this.Agent.isSamsung = true;\n      }\n      return 'Android';\n    }\n    if (this.platform.Blackberry.test(string)) {\n      this.Agent.isBlackberry = true;\n      return 'Blackberry';\n    }\n    if (this.platform.Linux.test(string)) {\n      return 'Linux';\n    }\n    if (this.platform.Wii.test(string)) {\n      return 'Wii';\n    }\n    if (this.platform.Playstation.test(string)) {\n      return 'Playstation';\n    }\n    if (this.platform.iPad.test(string)) {\n      this.Agent.isiPad = true;\n      return 'iPad';\n    }\n    if (this.platform.iPod.test(string)) {\n      this.Agent.isiPod = true;\n      return 'iPod';\n    }\n    if (this.platform.iPhone.test(string)) {\n      this.Agent.isiPhone = true;\n      return 'iPhone';\n    }\n    if (this.platform.Samsung.test(string)) {\n      this.Agent.isSamsung = true;\n      return 'Samsung';\n    }\n    if (this.platform.iOS.test(string)) {\n      return 'Apple iOS';\n    }\n    return 'unknown';\n  }\n}\n","import type { NextFunction, Request, Response } from 'express';\nimport type { IncomingHttpHeaders } from 'http';\nimport { UserAgent } from './express-useragent';\nimport type { AgentDetails } from './express-useragent';\n\nexport type { AgentDetails, HeadersLike, ClientHints, ClientHintBrand } from './express-useragent';\nexport { UserAgent } from './express-useragent';\n\n// Declaration merging for Express Request\n// This allows TypeScript users to access req.useragent without type errors\ndeclare global {\n  // eslint-disable-next-line @typescript-eslint/no-namespace\n  namespace Express {\n    interface Request {\n      useragent?: AgentDetails;\n    }\n  }\n}\n\nexport interface UserAgentAugmentedRequest extends Request {\n  useragent?: ReturnType<UserAgent['parse']>;\n  headers: IncomingHttpHeaders & Record<string, string | string[] | undefined>;\n}\n\nexport const useragent = new UserAgent();\n\nexport type UserAgentMiddleware = (req: Request, res: Response, next: NextFunction) => void;\n\nexport const express = (): UserAgentMiddleware => {\n  return (req: UserAgentAugmentedRequest, res: Response, next: NextFunction) => {\n    const headers = req.headers || {};\n    const resolveHeader = (value: string | string[] | undefined): string => {\n      if (Array.isArray(value)) {\n        return value.join(' ');\n      }\n      return value ?? '';\n    };\n\n    const uaHeader = resolveHeader(headers['user-agent']);\n    const ucHeader = resolveHeader(headers['x-ucbrowser-ua']);\n    const source = (ucHeader || uaHeader || 'unknown').trim() || 'unknown';\n\n    const parser = new UserAgent().hydrateFromHeaders(source, headers);\n    parser.testNginxGeoIP(headers);\n    // middleware duplicates tests to match legacy behaviour\n    parser.testBot();\n    parser.testMobile();\n    parser.testAndroidTablet();\n    parser.testTablet();\n    parser.testCompatibilityMode();\n    parser.testSilk();\n    parser.testKindleFire();\n    parser.testWechat();\n\n    req.useragent = parser.Agent;\n    res.locals.useragent = parser.Agent;\n\n    next();\n  };\n};\nexport const useragentMiddleware = express;\n\n// Export a default instance for easier usage\n// Also attach the express middleware and UserAgent class to the default export\n// to maintain compatibility with documented ESM usage (issue #177)\nconst defaultExport = Object.assign(useragent, {\n  express,\n  UserAgent,\n});\n\nexport default defaultExport;\n"],"mappings":"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","names":["versionStart","versionEnd"]}