From 088383b9bd75003b9aeb1b67b5d2f4eabd8bac03 Mon Sep 17 00:00:00 2001
From: Faisal Salman
Date: Mon, 21 Jul 2025 11:43:26 +0700
Subject: [PATCH 01/30] Add new CPU architecture: alpha
---
src/enums/ua-parser-enums.d.ts | 1 +
src/enums/ua-parser-enums.js | 1 +
src/main/ua-parser.js | 12 ++++++------
test/data/ua/cpu/cpu-all.json | 16 ++++++++++++++++
4 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts
index e8d3615..a8070fe 100644
--- a/src/enums/ua-parser-enums.d.ts
+++ b/src/enums/ua-parser-enums.d.ts
@@ -166,6 +166,7 @@ export const BrowserType: Readonly<{
}>;
export const CPU: Readonly<{
'68K': "68k";
+ ALPHA: "alpha";
ARM: "arm";
ARM_64: "arm64";
ARM_HF: "armhf";
diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js
index 174d787..ecedb6d 100644
--- a/src/enums/ua-parser-enums.js
+++ b/src/enums/ua-parser-enums.js
@@ -175,6 +175,7 @@ const BrowserType = Object.freeze({
const CPU = Object.freeze({
'68K': '68k',
+ ALPHA: 'alpha',
ARM : 'arm',
ARM_64: 'arm64',
ARM_HF: 'armhf',
diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js
index b325e7b..7d8c28c 100755
--- a/src/main/ua-parser.js
+++ b/src/main/ua-parser.js
@@ -536,15 +536,15 @@
/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
], [[ARCHITECTURE, 'arm']], [
- /((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC
- ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
-
/ sun4\w[;\)]/i // SPARC
], [[ARCHITECTURE, 'sparc']], [
-
- /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
- ], [[ARCHITECTURE, lowerize]]
+ /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,
+ /((ppc|powerpc)(64)?)( mac|;|\))/i, // PowerPC
+ /(?:osf1|[freopnt]{3,4}bsd) (alpha)/i // Alpha
+ ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
+ /winnt.+\[axp/i
+ ], [[ARCHITECTURE, 'alpha']]
],
device : [[
diff --git a/test/data/ua/cpu/cpu-all.json b/test/data/ua/cpu/cpu-all.json
index a4f68b1..e9b749e 100644
--- a/test/data/ua/cpu/cpu-all.json
+++ b/test/data/ua/cpu/cpu-all.json
@@ -87,6 +87,22 @@
"architecture" : "amd64"
}
},
+ {
+ "desc" : "Alpha",
+ "ua" : "Mozilla/3.01 (WinNT; I) [AXP]",
+ "expect" :
+ {
+ "architecture" : "alpha"
+ }
+ },
+ {
+ "desc" : "Alpha",
+ "ua" : "Mozilla/5.0 (X11; OpenBSD alpha; rv:78.0) Gecko/20100101 Firefox/78.0",
+ "expect" :
+ {
+ "architecture" : "alpha"
+ }
+ },
{
"desc" : "ARM",
"ua" : "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 635) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537",
From a19977ce4c99a03e7b89c6c8d5b579bd4c6370ce Mon Sep 17 00:00:00 2001
From: Faisal Salman
Date: Mon, 21 Jul 2025 11:53:03 +0700
Subject: [PATCH 02/30] Fix #796: Improve device detection for Pico Neo 3
---
src/main/ua-parser.js | 2 +-
test/data/ua/device/pico.json | 18 ++++++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js
index 7d8c28c..0d5eb3d 100755
--- a/src/main/ua-parser.js
+++ b/src/main/ua-parser.js
@@ -883,7 +883,7 @@
/droid.+; (glass) \d/i // Google Glass
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
- /(pico) (4|neo3(?: link|pro)?)/i // Pico
+ /(pico) ([\w ]+) os\d/i // Pico
], [VENDOR, MODEL, [TYPE, XR]], [
/(quest( \d| pro)?s?).+vr/i // Meta Quest
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
diff --git a/test/data/ua/device/pico.json b/test/data/ua/device/pico.json
index 2f28212..029a7c1 100644
--- a/test/data/ua/device/pico.json
+++ b/test/data/ua/device/pico.json
@@ -25,5 +25,23 @@
"model": "Neo3 Link",
"type": "xr"
}
+ },
+ {
+ "desc": "Pico Neo 3",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo 3 OS5.12.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.48 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0",
+ "expect": {
+ "vendor": "Pico",
+ "model": "Neo 3",
+ "type": "xr"
+ }
+ },
+ {
+ "desc": "Pico Neo 3 Pro",
+ "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo 3 Pro OS5.9.9.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.46 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0",
+ "expect": {
+ "vendor": "Pico",
+ "model": "Neo 3 Pro",
+ "type": "xr"
+ }
}
]
\ No newline at end of file
From 0bb6e24837aec7aec10d8cd1c2491128e058e21a Mon Sep 17 00:00:00 2001
From: Faisal Salman
Date: Tue, 22 Jul 2025 12:29:01 +0700
Subject: [PATCH 03/30] [extensions] Add new bots: Blueno,
BufferLinkPreviewBot, Claude-SearchBot, Claude-User, Coveobot, CriteoBot
---
src/extensions/ua-parser-extensions.js | 13 +++++++-----
src/helpers/ua-parser-helpers.js | 4 ++++
test/data/ua/extension/crawler.json | 28 ++++++++++++++++++++++----
test/data/ua/extension/fetcher.json | 20 ++++++++++++++++++
4 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js
index 4cd644f..06ef90f 100644
--- a/src/extensions/ua-parser-extensions.js
+++ b/src/extensions/ua-parser-extensions.js
@@ -44,6 +44,8 @@ const Crawlers = Object.freeze({
// Amazonbot - https://developer.amazon.com/amazonbot
// Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
// CCBot - https://commoncrawl.org/faq
+ // Coveobot - https://connect.coveo.com/s/article/19648
+ // CriteoBot - https://www.criteo.com/criteo-crawler/
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
@@ -56,7 +58,7 @@ const Crawlers = Object.freeze({
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot
// SeznamBot - http://napoveda.seznam.cz/seznambot-intro
- /((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|iask|linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i,
+ /((?:adidx|ahrefs|amazon|bing|cc|coveo|criteo|dot|duckduck|exa|facebook|gpt|iask|linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i,
// Applebot - http://apple.com/go/applebot
/(applebot(?:-extended)?)\/?([\w\.]*)/i,
@@ -65,7 +67,7 @@ const Crawlers = Object.freeze({
/(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i,
// ClaudeBot (Anthropic)
- /(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i,
+ /(claude(?:bot|-searchbot|-web)|anthropic-ai)\/?([\w\.]*)/i,
// Coc Coc Bot - https://help.coccoc.com/en/search-engine
/(coccocbot-(?:image|web))\/([\w\.]+)/i,
@@ -235,15 +237,16 @@ const Fetchers = Object.freeze({
browser : [
[
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
+ // Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
- // Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
+ // Better Uptime / BingPreview / Blueno / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
// Google Site Verifier / Meta / Yahoo! Japan
// Iframely - https://iframely.com/docs/about
// Perplexity-User - https://docs.perplexity.ai/guides/bots
// MistralAI-User - https://docs.mistral.ai/robots/
// Yandex Bots - https://yandex.com/bots
- /(ahrefssiteaudit|(?:bing|microsoft)preview|(?:chatgpt|mistralai|perplexity)-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|iframely|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
+ /(ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|mastodon|(?:bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|iframely|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
// Bluesky
/(bluesky) cardyb\/([\w\.]+)/i,
@@ -404,8 +407,8 @@ const Vehicles = Object.freeze({
const Bots = Object.freeze({
browser : [
...CLIs.browser,
- ...Crawlers.browser,
...Fetchers.browser,
+ ...Crawlers.browser,
...Libraries.browser
],
os : [
diff --git a/src/helpers/ua-parser-helpers.js b/src/helpers/ua-parser-helpers.js
index 8f79fe8..c00e49b 100644
--- a/src/helpers/ua-parser-helpers.js
+++ b/src/helpers/ua-parser-helpers.js
@@ -52,6 +52,7 @@ const isAIBot = (resultOrUA) => [
// Anthropic
'anthropic-ai',
'claude-web',
+ 'claude-searchbot',
'claudebot',
// Apple
@@ -63,6 +64,9 @@ const isAIBot = (resultOrUA) => [
// Common Crawl
'ccbot',
+
+ // Coveo
+ 'coveobot',
// DataForSeo
'dataforseobot',
diff --git a/test/data/ua/extension/crawler.json b/test/data/ua/extension/crawler.json
index 918ee98..ac580fc 100644
--- a/test/data/ua/extension/crawler.json
+++ b/test/data/ua/extension/crawler.json
@@ -269,6 +269,16 @@
"type" : "crawler"
}
},
+ {
+ "desc" : "ClaudeWeb",
+ "ua" : "Claude-Web/1.0 (web crawler; +https://www.anthropic.com/; bots@anthropic.com)",
+ "expect" :
+ {
+ "name" : "Claude-Web",
+ "version" : "1.0",
+ "type" : "crawler"
+ }
+ },
{
"desc" : "Coc Coc Bot (web)",
"ua" : "Mozilla/5.0 (compatible; coccocbot-web/1.0; +http://help.coccoc.com/searchengine)",
@@ -290,12 +300,22 @@
}
},
{
- "desc" : "ClaudeWeb",
- "ua" : "Claude-Web/1.0 (web crawler; +https://www.anthropic.com/; bots@anthropic.com)",
+ "desc" : "Coveobot",
+ "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) (compatible; Coveobot/2.0;+http://www.coveo.com/bot.html)",
"expect" :
{
- "name" : "Claude-Web",
- "version" : "1.0",
+ "name" : "Coveobot",
+ "version" : "2.0",
+ "type" : "crawler"
+ }
+ },
+ {
+ "desc" : "CriteoBot",
+ "ua" : "CriteoBot/0.1 (+https://www.criteo.com/criteo-crawler/)",
+ "expect" :
+ {
+ "name" : "CriteoBot",
+ "version" : "0.1",
"type" : "crawler"
}
},
diff --git a/test/data/ua/extension/fetcher.json b/test/data/ua/extension/fetcher.json
index 4a05393..19b05bb 100644
--- a/test/data/ua/extension/fetcher.json
+++ b/test/data/ua/extension/fetcher.json
@@ -29,6 +29,16 @@
"type" : "fetcher"
}
},
+ {
+ "desc" : "Blueno",
+ "ua" : "acebookexternalhit/1.1 (compatible; Blueno/1.0; +http://naver.me/scrap)",
+ "expect" :
+ {
+ "name" : "Blueno",
+ "version" : "1.0",
+ "type" : "fetcher"
+ }
+ },
{
"desc" : "Bluesky",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app) Chrome/100.0.0.0 Safari/537.36",
@@ -39,6 +49,16 @@
"type" : "fetcher"
}
},
+ {
+ "desc" : "BufferLinkPreviewBot",
+ "ua" : "BufferLinkPreviewBot/1.0 (+https://scraper.buffer.com/about/bots/link-preview-bot)",
+ "expect" :
+ {
+ "name" : "BufferLinkPreviewBot",
+ "version" : "1.0",
+ "type" : "fetcher"
+ }
+ },
{
"desc" : "ChatGPT-User",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ChatGPT-User/1.0; +https://openai.com/bot",
From 3fe137e533cb79dd24ba47dccf31c102ee316e54 Mon Sep 17 00:00:00 2001
From: undefined
Date: Fri, 1 Aug 2025 19:33:10 +0800
Subject: [PATCH 04/30] chore: move node-fetch to devDeps (#784)
---
package-lock.json | 10 +++++++---
package.json | 2 +-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7dd00ea..8fb1f5e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,7 +26,6 @@
"@types/node-fetch": "^2.6.12",
"detect-europe-js": "^0.1.2",
"is-standalone-pwa": "^0.1.1",
- "node-fetch": "^2.7.0",
"ua-is-frozen": "^0.1.2"
},
"bin": {
@@ -38,6 +37,7 @@
"@playwright/test": "^1.49.0",
"jshint": "~2.13.6",
"mocha": "~8.2.0",
+ "node-fetch": "^2.7.0",
"requirejs": "2.3.2",
"safe-regex": "^2.1.1",
"tsd": "^0.29.0",
@@ -1967,6 +1967,7 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
@@ -2716,7 +2717,8 @@
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "dev": true
},
"node_modules/trim-newlines": {
"version": "3.0.1",
@@ -2809,12 +2811,14 @@
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
diff --git a/package.json b/package.json
index 4ca4f0b..b39f0b0 100755
--- a/package.json
+++ b/package.json
@@ -227,7 +227,6 @@
"detect-europe-js": "^0.1.2",
"is-standalone-pwa": "^0.1.1",
"ua-is-frozen": "^0.1.2",
- "node-fetch": "^2.7.0",
"@types/node-fetch": "^2.6.12"
},
"devDependencies": {
@@ -236,6 +235,7 @@
"@playwright/test": "^1.49.0",
"jshint": "~2.13.6",
"mocha": "~8.2.0",
+ "node-fetch": "^2.7.0",
"requirejs": "2.3.2",
"safe-regex": "^2.1.1",
"tsd": "^0.29.0",
From ab299a23b7bc75d50ab0b02205809cca274ba63d Mon Sep 17 00:00:00 2001
From: Suryaansh Chawla
Date: Fri, 1 Aug 2025 17:03:52 +0530
Subject: [PATCH 05/30] Zalo integration in UAParser (#1) (#792)
---
src/enums/ua-parser-enums.d.ts | 1 +
src/enums/ua-parser-enums.js | 3 ++-
src/main/ua-parser.js | 2 ++
test/data/ua/browser/browser-all.json | 22 ++++++++++++++++++++++
4 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts
index a8070fe..933bccb 100644
--- a/src/enums/ua-parser-enums.d.ts
+++ b/src/enums/ua-parser-enums.d.ts
@@ -154,6 +154,7 @@ export const Browser: Readonly<{
WHALE: "Whale";
WOLVIC: "Wolvic";
YANDEX: "Yandex";
+ ZALO: "Zalo";
}>;
export const BrowserType: Readonly<{
CRAWLER: "crawler";
diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js
index ecedb6d..828e9e8 100644
--- a/src/enums/ua-parser-enums.js
+++ b/src/enums/ua-parser-enums.js
@@ -158,7 +158,8 @@ const Browser = Object.freeze({
WEIBO: 'Weibo',
WHALE: 'Whale',
WOLVIC: 'Wolvic',
- YANDEX: 'Yandex'
+ YANDEX: 'Yandex',
+ ZALO: 'Zalo'
// TODO : test!
});
diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js
index 0d5eb3d..4051869 100755
--- a/src/main/ua-parser.js
+++ b/src/main/ua-parser.js
@@ -455,6 +455,8 @@
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME, [TYPE, INAPP]], [
+ /(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i // Zalo
+ ], [[NAME, /(.+)/, 'Zalo'], VERSION, [TYPE, INAPP]], [
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
], [NAME, VERSION], [
diff --git a/test/data/ua/browser/browser-all.json b/test/data/ua/browser/browser-all.json
index 9f39de9..a2a6379 100644
--- a/test/data/ua/browser/browser-all.json
+++ b/test/data/ua/browser/browser-all.json
@@ -2695,5 +2695,27 @@
"major" : "10",
"type" : "inapp"
}
+ },
+ {
+ "desc" : "Zalo on iOS",
+ "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Zalo/20.05.01 Mobile/15E148",
+ "expect" :
+ {
+ "name" : "Zalo",
+ "version" : "20.05.01",
+ "major" : "20",
+ "type" : "inapp"
+ }
+ },
+ {
+ "desc" : "Zalo on Android",
+ "ua" : "Mozilla/5.0 (Linux; Android 10; Vsmart Live Build/QKQ1.190918.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 Zalo/20.04.02.r1",
+ "expect" :
+ {
+ "name" : "Zalo",
+ "version" : "20.04.02.r1",
+ "major" : "20",
+ "type" : "inapp"
+ }
}
]
\ No newline at end of file
From ecbc0336b644604b8483530ba0daacafd96cbdc3 Mon Sep 17 00:00:00 2001
From: Aidan Nulman
Date: Fri, 1 Aug 2025 07:34:36 -0400
Subject: [PATCH 06/30] Fix #797: Iterate over `brands` as an array (#798)
---
dist/ua-parser.min.js | 2 +-
dist/ua-parser.min.mjs | 2 +-
dist/ua-parser.pack.js | 2 +-
dist/ua-parser.pack.mjs | 2 +-
src/main/ua-parser.js | 4 +++-
src/main/ua-parser.mjs | 4 +++-
test/unit/main.js | 30 +++++++++++++++++++++++++++++-
7 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js
index 7d65516..22782df 100644
--- a/dist/ua-parser.min.js
+++ b/dist/ua-parser.min.js
@@ -1,4 +1,4 @@
/* UAParser.js v2.0.4
Copyright © 2012-2025 Faisal Salman
AGPLv3 License */
-(function(window,undefined){"use strict";var LIBVERSION="2.0.4",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(defaultRgx,extensions){var mergedRgx={};var extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i in extensions){for(var j in extensions[i]){extraRgx[j]=extensions[i][j].concat(extraRgx[j]?extraRgx[j]:[])}}}for(var k in defaultRgx){mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k]}return mergedRgx},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str2)==lowerize(str1[i]))return true}return false}return isString(str1)?lowerize(str2)==lowerize(str1):false},isExtensions=function(obj,deep){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):false)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;var i=0,j,k,p,q,matches,match;while(i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length>=3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){if(q.length>3){this[q[0]]=match?q[1].apply(this,q.slice(2)):undefined}else{this[q[0]]=match?q[1].call(this,match,q[2]):undefined}}else{if(q.length==3){this[q[0]]=match?match.replace(q[1],q[2]):undefined}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}else if(q.length>4){this[q[0]]=match?q[3].apply(this,[match.replace(q[1],q[2])].concat(q.slice(4))):undefined}}}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j
# UAParser.js
-The most comprehensive, compact, & up-to-date isomorphic JavaScript library to detect
-user's Browser, Engine, OS, CPU, and Device type/model. Runs either in browser
-(client-side) or node.js (server-side).
+The most comprehensive, compact, and up-to-date JavaScript library to detect user's browser, OS, CPU, and device type/model. Also detect bots, apps, and more. Runs seamlessly in the browser (client-side) or Node.js (server-side).
# Demo
@@ -33,7 +32,7 @@ user's Browser, Engine, OS, CPU, and Device type/model. Runs either in browser
Before upgrading from `v0.7` / `v1.0`, please read [CHANGELOG](CHANGELOG.md) to
see what's new & breaking.
-# License Options
+# Package & Pricing
@@ -46,8 +45,8 @@ see what's new & breaking.
License options |
- MIT (v0.7~v1.0) |
- AGPL (>=v2.0) |
+ MIT (v1.x) |
+ AGPL (v2.x) |
PRO Personal |
PRO Business |
PRO Enterprise |
@@ -148,14 +147,6 @@ see what's new & breaking.
✅ |
✅ |
-
- npm module |
- ✅ |
- ✅ |
- ✅ |
- ✅ |
- ✅ |
-
TypeScript declarations |
⚠️ |
@@ -165,7 +156,23 @@ see what's new & breaking.
✅ |
- Allows commercial use |
+ npm module available |
+ ✅ |
+ ✅ |
+ ✅ |
+ ✅ |
+ ✅ |
+
+
+ Direct downloads available |
+ ✅ |
+ ✅ |
+ ✅ |
+ ✅ |
+ ✅ |
+
+
+ Allows commercial usage |
✅ |
✅ |
❌ |
@@ -181,11 +188,27 @@ see what's new & breaking.
✅ |
- Unlimited use per 1 license |
+ No open-source obligations |
+ ✅ |
+ ❌ |
✅ |
✅ |
✅ |
- ❌ |
+
+
+ Unlimited end-products |
+ ✅ |
+ ✅ |
+ ✅ |
+ ❌ |
+ ✅ |
+
+
+ Unlimited deployments |
+ ✅ |
+ ✅ |
+ ✅ |
+ ❌ |
✅ |
@@ -206,8 +229,8 @@ see what's new & breaking.
Price |
- FREE (License) |
- FREE (License) |
+ FREE* (License) |
+ FREE* (License) |
$14 (License) |
$29 (License) |
$599 (License) |
@@ -236,10 +259,7 @@ Made with [contributors-img](https://contrib.rocks).
## Backers & Sponsors
-
-
-
-You can support the open-source editions of UAParser.js through one of the following options:
+Support the **open-source editions** of UAParser.js through one of the following options:
[](https://opencollective.com/ua-parser-js)
@@ -248,4 +268,7 @@ You can support the open-source editions of UAParser.js through one of the follo
[](https://paypal.me/faisalman)
[](https://store.faisalman.com/buy/3d71f2f3-cf4d-473c-892a-9d4497c890be)
\ No newline at end of file
+)](https://store.faisalman.com/buy/3d71f2f3-cf4d-473c-892a-9d4497c890be)
+
+
+
\ No newline at end of file
diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js
index 22782df..98f9ad6 100644
--- a/dist/ua-parser.min.js
+++ b/dist/ua-parser.min.js
@@ -1,4 +1,4 @@
-/* UAParser.js v2.0.4
+/* UAParser.js v2.0.5
Copyright © 2012-2025 Faisal Salman
AGPLv3 License */
-(function(window,undefined){"use strict";var LIBVERSION="2.0.4",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(defaultRgx,extensions){var mergedRgx={};var extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i in extensions){for(var j in extensions[i]){extraRgx[j]=extensions[i][j].concat(extraRgx[j]?extraRgx[j]:[])}}}for(var k in defaultRgx){mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k]}return mergedRgx},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str2)==lowerize(str1[i]))return true}return false}return isString(str1)?lowerize(str2)==lowerize(str1):false},isExtensions=function(obj,deep){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):false)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){if(!arr.hasOwnProperty(i))continue;var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;var i=0,j,k,p,q,matches,match;while(i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length>=3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){if(q.length>3){this[q[0]]=match?q[1].apply(this,q.slice(2)):undefined}else{this[q[0]]=match?q[1].call(this,match,q[2]):undefined}}else{if(q.length==3){this[q[0]]=match?match.replace(q[1],q[2]):undefined}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}else if(q.length>4){this[q[0]]=match?q[3].apply(this,[match.replace(q[1],q[2])].concat(q.slice(4))):undefined}}}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:case UA_ENGINE:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i=0;i=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}if(this.get(NAME)==WINDOWS&&uaCH[MODEL]=="Xbox"){this.set(NAME,"Xbox").set(VERSION,undefined)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua,true)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions,true)){headers=extensions;extensions=undefined}if(headers&&typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[k]=v});headers=kv}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(isString(ua))userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);return this}UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else if(isWindow){window.UAParser=UAParser}}var $=isWindow&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(ua){parser.setUA(ua);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this);
\ No newline at end of file
+(function(window,undefined){"use strict";var LIBVERSION="2.0.5",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(defaultRgx,extensions){var mergedRgx={};var extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i in extensions){for(var j in extensions[i]){extraRgx[j]=extensions[i][j].concat(extraRgx[j]?extraRgx[j]:[])}}}for(var k in defaultRgx){mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k]}return mergedRgx},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str2)==lowerize(str1[i]))return true}return false}return isString(str1)?lowerize(str2)==lowerize(str1):false},isExtensions=function(obj,deep){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):false)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){if(!arr.hasOwnProperty(i))continue;var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;var i=0,j,k,p,q,matches,match;while(i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length>=3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){if(q.length>3){this[q[0]]=match?q[1].apply(this,q.slice(2)):undefined}else{this[q[0]]=match?q[1].call(this,match,q[2]):undefined}}else{if(q.length==3){this[q[0]]=match?match.replace(q[1],q[2]):undefined}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}else if(q.length>4){this[q[0]]=match?q[3].apply(this,[match.replace(q[1],q[2])].concat(q.slice(4))):undefined}}}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:case UA_ENGINE:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i=0;i=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}if(this.get(NAME)==WINDOWS&&uaCH[MODEL]=="Xbox"){this.set(NAME,"Xbox").set(VERSION,undefined)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua,true)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions,true)){headers=extensions;extensions=undefined}if(headers){if(typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[String(k).toLowerCase()]=v});headers=kv}else{var normalized={};for(var header in headers){if(headers.hasOwnProperty(header)){normalized[String(header).toLowerCase()]=headers[header]}}headers=normalized}}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(isString(ua))userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);return this}UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else if(isWindow){window.UAParser=UAParser}}var $=isWindow&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(ua){parser.setUA(ua);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this);
\ No newline at end of file
diff --git a/dist/ua-parser.min.mjs b/dist/ua-parser.min.mjs
index c8afed4..ce5f6d4 100644
--- a/dist/ua-parser.min.mjs
+++ b/dist/ua-parser.min.mjs
@@ -1,4 +1,4 @@
-/* UAParser.js v2.0.4
+/* UAParser.js v2.0.5
Copyright © 2012-2025 Faisal Salman
AGPLv3 License */
-var LIBVERSION="2.0.4",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(defaultRgx,extensions){var mergedRgx={};var extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i in extensions){for(var j in extensions[i]){extraRgx[j]=extensions[i][j].concat(extraRgx[j]?extraRgx[j]:[])}}}for(var k in defaultRgx){mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k]}return mergedRgx},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str2)==lowerize(str1[i]))return true}return false}return isString(str1)?lowerize(str2)==lowerize(str1):false},isExtensions=function(obj,deep){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):false)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){if(!arr.hasOwnProperty(i))continue;var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;var i=0,j,k,p,q,matches,match;while(i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length>=3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){if(q.length>3){this[q[0]]=match?q[1].apply(this,q.slice(2)):undefined}else{this[q[0]]=match?q[1].call(this,match,q[2]):undefined}}else{if(q.length==3){this[q[0]]=match?match.replace(q[1],q[2]):undefined}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}else if(q.length>4){this[q[0]]=match?q[3].apply(this,[match.replace(q[1],q[2])].concat(q.slice(4))):undefined}}}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:case UA_ENGINE:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i=0;i=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}if(this.get(NAME)==WINDOWS&&uaCH[MODEL]=="Xbox"){this.set(NAME,"Xbox").set(VERSION,undefined)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua,true)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions,true)){headers=extensions;extensions=undefined}if(headers&&typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[k]=v});headers=kv}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(isString(ua))userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);return this}UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);export{UAParser};
\ No newline at end of file
+var LIBVERSION="2.0.5",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(defaultRgx,extensions){var mergedRgx={};var extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i in extensions){for(var j in extensions[i]){extraRgx[j]=extensions[i][j].concat(extraRgx[j]?extraRgx[j]:[])}}}for(var k in defaultRgx){mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k]}return mergedRgx},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str2)==lowerize(str1[i]))return true}return false}return isString(str1)?lowerize(str2)==lowerize(str1):false},isExtensions=function(obj,deep){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):false)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){if(!arr.hasOwnProperty(i))continue;var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;var i=0,j,k,p,q,matches,match;while(i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length>=3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){if(q.length>3){this[q[0]]=match?q[1].apply(this,q.slice(2)):undefined}else{this[q[0]]=match?q[1].call(this,match,q[2]):undefined}}else{if(q.length==3){this[q[0]]=match?match.replace(q[1],q[2]):undefined}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}else if(q.length>4){this[q[0]]=match?q[3].apply(this,[match.replace(q[1],q[2])].concat(q.slice(4))):undefined}}}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:case UA_ENGINE:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i=0;i=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}if(this.get(NAME)==WINDOWS&&uaCH[MODEL]=="Xbox"){this.set(NAME,"Xbox").set(VERSION,undefined)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua,true)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions,true)){headers=extensions;extensions=undefined}if(headers){if(typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[String(k).toLowerCase()]=v});headers=kv}else{var normalized={};for(var header in headers){if(headers.hasOwnProperty(header)){normalized[String(header).toLowerCase()]=headers[header]}}headers=normalized}}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(isString(ua))userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);return this}UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);export{UAParser};
\ No newline at end of file
diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js
index fec42a7..cd05ecb 100644
--- a/dist/ua-parser.pack.js
+++ b/dist/ua-parser.pack.js
@@ -1,4 +1,4 @@
-/* UAParser.js v2.0.4
+/* UAParser.js v2.0.5
Copyright © 2012-2025 Faisal Salman
AGPLv3 License */
-((i,c)=>{function I(i){for(var e={},t=0;t{var t,o={},r=e;if(!Ti(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(t in i)o[t]=r[t]&&r[t].length%2==0?r[t].concat(i[t]):i[t];return o})(Ui,e):Ui,M.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Gi(i,r,s,a).set("ua",r).set(u,this.getBrowser()).set(h,this.getCPU()).set(p,this.getDevice()).set(m,this.getEngine()).set(f,this.getOS()).get()}:function(){return new Gi(i,r,s[i],a).parseUA().get()}})(u)],["getCPU",n(h)],["getDevice",n(p)],["getEngine",n(m)],["getOS",n(f)],["getResult",n(g)],["getUA",function(){return r}],["setUA",function(i){return H(i)&&(r=i.length>P?Mi(i,P):i),this}]]).setUA(r),this):new V(i,e,t).getResult()}V.VERSION="2.0.4",V.BROWSER=I([v,y,G,k]),V.CPU=I([C]),V.DEVICE=I([S,x,k,W,_,e,r,t,F]),V.ENGINE=V.OS=I([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=V:exports).UAParser=V:typeof define===R&&define.amd?define(function(){return V}):qi&&(i.UAParser=V);var Wi,Ni=qi&&(i.jQuery||i.Zepto);Ni&&!Ni.ua&&(Wi=new V,Ni.ua=Wi.getResult(),Ni.ua.get=function(){return Wi.getUA()},Ni.ua.set=function(i){Wi.setUA(i);var e,t=Wi.getResult();for(e in t)Ni.ua[e]=t[e]})})("object"==typeof window?window:this);
\ No newline at end of file
+((i,c)=>{function V(i){for(var e={},t=0;t{var t,o={},r=e;if(!zi(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(t in i)o[t]=r[t]&&r[t].length%2==0?r[t].concat(i[t]):i[t];return o})(Ui,e):Ui,M.call(this,[["getBrowser",(b=function(i){return i==g?function(){return new Gi(i,s,w,n).set("ua",s).set(u,this.getBrowser()).set(h,this.getCPU()).set(p,this.getDevice()).set(m,this.getEngine()).set(f,this.getOS()).get()}:function(){return new Gi(i,s,w[i],n).parseUA().get()}})(u)],["getCPU",b(h)],["getDevice",b(p)],["getEngine",b(m)],["getOS",b(f)],["getResult",b(g)],["getUA",function(){return s}],["setUA",function(i){return Oi(i)&&(s=i.length>I?Mi(i,I):i),this}]]).setUA(s),this):new P(i,e,t).getResult()}P.VERSION="2.0.5",P.BROWSER=V([v,y,G,k]),P.CPU=V([C]),P.DEVICE=V([S,x,k,W,_,e,r,t,F]),P.ENGINE=P.OS=V([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=P:exports).UAParser=P:typeof define===L&&define.amd?define(function(){return P}):_i&&(i.UAParser=P);var Wi,Ni=_i&&(i.jQuery||i.Zepto);Ni&&!Ni.ua&&(Wi=new P,Ni.ua=Wi.getResult(),Ni.ua.get=function(){return Wi.getUA()},Ni.ua.set=function(i){Wi.setUA(i);var e,t=Wi.getResult();for(e in t)Ni.ua[e]=t[e]})})("object"==typeof window?window:this);
\ No newline at end of file
diff --git a/dist/ua-parser.pack.mjs b/dist/ua-parser.pack.mjs
index 8ab1e0e..d8b552f 100644
--- a/dist/ua-parser.pack.mjs
+++ b/dist/ua-parser.pack.mjs
@@ -1,4 +1,4 @@
-/* UAParser.js v2.0.4
+/* UAParser.js v2.0.5
Copyright © 2012-2025 Faisal Salman
AGPLv3 License */
-function I(i){for(var e={},o=0;o{var o,t={},r=e;if(!zi(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(o in i)t[o]=r[o]&&r[o].length%2==0?r[o].concat(i[o]):i[o];return t})(Ii,e):Ii,A.call(this,[["getBrowser",(n=function(i){return i==f?function(){return new Li(i,r,s,a).set("ua",r).set(c,this.getBrowser()).set(h,this.getCPU()).set(u,this.getDevice()).set(p,this.getEngine()).set(m,this.getOS()).get()}:function(){return new Li(i,r,s[i],a).parseUA().get()}})(c)],["getCPU",n(h)],["getDevice",n(u)],["getEngine",n(p)],["getOS",n(m)],["getResult",n(f)],["getUA",function(){return r}],["setUA",function(i){return H(i)&&(r=i.length>P?Mi(i,P):i),this}]]).setUA(r),this):new V(i,e,o).getResult()}V.VERSION="2.0.4",V.BROWSER=I([g,x,C,v]),V.CPU=I([y]),V.DEVICE=I([S,k,v,G,_,i,r,e,N]),V.ENGINE=V.OS=I([g,x]);export{V as UAParser};
\ No newline at end of file
+function I(i){for(var e={},o=0;o{var o,t={},r=e;if(!zi(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(o in i)t[o]=r[o]&&r[o].length%2==0?r[o].concat(i[o]):i[o];return t})(Ii,e):Ii,A.call(this,[["getBrowser",(d=function(i){return i==f?function(){return new Li(i,s,w,n).set("ua",s).set(c,this.getBrowser()).set(h,this.getCPU()).set(u,this.getDevice()).set(p,this.getEngine()).set(m,this.getOS()).get()}:function(){return new Li(i,s,w[i],n).parseUA().get()}})(c)],["getCPU",d(h)],["getDevice",d(u)],["getEngine",d(p)],["getOS",d(m)],["getResult",d(f)],["getUA",function(){return s}],["setUA",function(i){return H(i)&&(s=i.length>P?Mi(i,P):i),this}]]).setUA(s),this):new V(i,e,o).getResult()}V.VERSION="2.0.5",V.BROWSER=I([g,x,G,v]),V.CPU=I([y]),V.DEVICE=I([C,k,v,W,S,i,r,e,F]),V.ENGINE=V.OS=I([g,x]);export{V as UAParser};
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 1265e3d..b9334f2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ua-parser-js",
- "version": "2.0.4",
+ "version": "2.0.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ua-parser-js",
- "version": "2.0.4",
+ "version": "2.0.5",
"funding": [
{
"type": "opencollective",
@@ -1889,26 +1889,6 @@
"node": "^10 || ^12 || >=13.7"
}
},
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "dev": true,
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
"node_modules/normalize-package-data": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
@@ -2640,12 +2620,6 @@
"node": ">=8.0"
}
},
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "dev": true
- },
"node_modules/trim-newlines": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
@@ -2738,22 +2712,6 @@
"spdx-expression-parse": "^3.0.0"
}
},
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "dev": true
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "dev": true,
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index e1477d8..580bbcc 100755
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"title": "UAParser.js",
"name": "ua-parser-js",
- "version": "2.0.4",
+ "version": "2.0.5",
"author": "Faisal Salman (http://faisalman.com)",
"description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment",
"keywords": [
diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts
index b748ea9..c19cd80 100644
--- a/src/enums/ua-parser-enums.d.ts
+++ b/src/enums/ua-parser-enums.d.ts
@@ -3,7 +3,7 @@
// Source: /src/enums/ua-parser-enums.js
///////////////////////////////////////////////
-/* Enums for UAParser.js v2.0.4
+/* Enums for UAParser.js v2.0.5
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman
AGPLv3 License */
@@ -285,7 +285,7 @@ export const DeviceVendor: Readonly<{
SPRINT: 'Sprint',
TCL: 'TCL',
TECHNISAT: 'TechniSAT',
- TECNO: 'Tecno',
+ TECNO: 'TECNO',
TESLA: 'Tesla',
ULEFONE: 'Ulefone',
VIVO: 'Vivo',
@@ -437,15 +437,14 @@ export const OS: typeof OSName;
export const Extension: Readonly<{
BrowserName: {
- CLIs: {
+ CLI: {
CURL: 'curl',
ELINKS: 'ELinks',
HTTPIE: 'HTTPie',
LYNX: 'Lynx',
- WGET: 'wget'
+ WGET: 'Wget'
},
- Crawlers: {
- '360_SPIDER': '360Spider',
+ Crawler: {
AHREFS_BOT: 'AhrefsBot',
AI2_BOT: 'AI2Bot',
AIHIT_BOT: 'aiHitBot',
@@ -472,9 +471,9 @@ export const Extension: Readonly<{
BLEX_BOT: 'BLEXBot',
BOTIFY: 'botify',
BRAVE_BOT: 'Bravebot',
- BYTEDANCE_SPIDER: 'Bytespider',
- CC_BOT: 'CCBot',
- CHATGLM_SPIDER: 'ChatGLM-Spider',
+ BYTEDANCE_BYTESPIDER: 'Bytespider',
+ BYTEDANCE_TIKTOKSPIDER: 'TikTokSpider',
+ COMMON_CRAWL_CCBOT: 'CCBot',
COCCOC_BOT_WEB: 'coccocbot-web',
COCCOC_BOT_IMAGE: 'coccocbot-image',
COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',
@@ -496,10 +495,13 @@ export const Extension: Readonly<{
GOOGLE_ADSBOT: 'AdsBot-Google',
GOOGLE_ADSBOT_MOBILE: 'Adsbot-Google-Mobile',
GOOGLE_ADSENSE: 'AdSense',
+ GOOGLE_APIS: 'APIs-Google',
GOOGLE_BOT: 'Googlebot',
GOOGLE_BOT_IMAGE: 'Googlebot-Image',
GOOGLE_BOT_NEWS: 'Googlebot-News',
GOOGLE_BOT_VIDEO: 'Googlebot-Video',
+ GOOGLE_CLOUDVERTEXBOT: 'Google-CloudVertexBot',
+ GOOGLE_EXTENDED: 'Google-Extended',
GOOGLE_INSPECTIONTOOL: 'Google-InspectionTool',
GOOGLE_OTHER: 'GoogleOther',
GOOGLE_OTHER_IMAGE: 'GoogleOther-Image',
@@ -529,16 +531,16 @@ export const Extension: Readonly<{
MICROSOFT_ADIDXBOT: 'adidxbot',
MOJEEK_BOT: 'MojeekBot',
MOZ_DOTBOT: 'DotBot',
- OMGILI: 'omgili',
- OMGILI_BOT: 'omgilibot',
ONCRAWL: 'OnCrawl',
ONESPOT_SCRAPERBOT: 'Onespot-ScraperBot',
OPENAI_GPTBOT: 'GPTBot',
- OPENAI_SEARCH: 'OAI-SearchBot',
+ OPENAI_SEARCH_BOT: 'OAI-SearchBot',
PERPLEXITY_BOT: 'PerplexityBot',
+ QIHOO_360_SPIDER: '360Spider',
QWANT_BOT: 'Qwantbot',
REPLICATE_BOT: 'Replicate-Bot',
RUNPOD_BOT: 'RunPod-Bot',
+ SB_INTUITIONS_BOT: 'SBIntuitionsBot',
SEEKPORT_BOT: 'SeekportBot',
SEMRUSH_BOT: 'SemrushBot',
SEMRUSH_BOT_BACKLINK: 'SemrushBot-BA',
@@ -553,18 +555,51 @@ export const Extension: Readonly<{
TOGETHER_BOT: 'Together-Bot',
TURNITIN_BOT: 'TurnitinBot',
TWIN_AGENT: 'TwinAgent',
- XAI_BOT: 'xAI-Bot',
VERCEL_V0BOT: 'v0bot',
+ WEBZIO: 'webzio',
+ WEBZIO_EXTENDED: 'Webzio-Extended',
+ WEBZIO_OMGILI: 'omgili',
+ WEBZIO_OMGILI_BOT: 'omgilibot',
+ XAI_BOT: 'xAI-Bot',
YAHOO_JAPAN: 'Y!J-BRW',
YAHOO_SLURP: 'Yahoo! Slurp',
+ YANDEX_ACCESSIBILITY_BOT: 'YandexAccessibilityBot',
+ YANDEX_ADDITIONAL_BOT: 'YandexAdditionalBot',
+ YANDEX_ADNET: 'YandexAdNet',
+ YANDEX_BLOGS: 'YandexBlogs',
YANDEX_BOT: 'YandexBot',
+ YANDEX_BOT_MIRRORDETECTOR: 'YandexBot MirrorDetector',
+ YANDEX_COMBOT: 'YandexComBot',
+ YANDEX_FAVICONS: 'YandexFavicons',
+ YANDEX_IMAGE_RESIZER: 'YandexImageResizer',
+ YANDEX_IMAGES: 'YandexImages',
+ YANDEX_MARKET: 'YandexMarket',
+ YANDEX_MEDIA: 'YandexMedia',
+ YANDEX_METRIKA: 'YandexMetrika',
+ YANDEX_MOBILE_BOT: 'YandexMobileBot',
+ YANDEX_MOBILE_SCREENSHOT_BOT: 'YandexMobileScreenShotBot',
+ YANDEX_NEWS: 'YandexNews',
+ YANDEX_ONTODB: 'YandexOntoDB',
+ YANDEX_ONTODB_API: 'YandexOntoDBAPI',
+ YANDEX_PARTNER: 'YandexPartner',
+ YANDEX_RCA: 'YandexRCA',
+ YANDEX_RENDERRESOURCES_BOT: 'YandexRenderResourcesBot',
+ YANDEX_SCREENSHOT_BOT: 'YandexScreenshotBot',
+ YANDEX_SPRAV_BOT: 'YandexSpravBot',
+ YANDEX_TRACKER: 'YandexTracker',
+ YANDEX_VERTICALS: 'YandexVerticals',
+ YANDEX_VERTIS: 'YandexVertis',
+ YANDEX_VIDEO: 'YandexVideo',
+ YANDEX_VIDEO_PARSER: 'YandexVideoParser',
+ YANDEX_WEBMASTER: 'YandexWebmaster',
YEP_BOT: 'YepBot',
YETI: 'Yeti',
YISOU_SPIDER: 'YisouSpider',
YOU_BOT: 'YouBot',
+ ZHIPU_CHATGLM_SPIDER: 'ChatGLM-Spider',
ZUM_BOT: 'ZumBot'
},
- Emails: {
+ Email: {
AIRMAIL: 'Airmail',
APPLE_MAIL: 'Mail',
BLUEMAIL: 'BlueMail',
@@ -587,7 +622,7 @@ export const Extension: Readonly<{
ZIMBRA: 'Zimbra',
ZOHO_MAIL: 'ZohoMail-Desktop'
},
- Fetchers: {
+ Fetcher: {
AHREFS_SITEAUDIT: 'AhrefsSiteAudit',
ANTHROPIC_CLAUDE_USER: 'Claude-User',
ASANA: 'Asana',
@@ -600,7 +635,7 @@ export const Extension: Readonly<{
GOOGLE_CHROME_LIGHTHOUSE: 'Chrome-Lighthouse',
GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',
GOOGLE_GEMINI_DEEP_RESEARCH: 'Gemini-Deep-Research',
- GOOGLE_IMAGE_PROXY: 'GoogleImageProxy',
+ GOOGLE_IMAGEPROXY: 'GoogleImageProxy',
GOOGLE_PAGERENDERER: 'Google-PageRenderer',
GOOGLE_READ_ALOUD: 'Google-Read-Aloud',
GOOGLE_PRODUCER: 'GoogleProducer',
@@ -609,6 +644,7 @@ export const Extension: Readonly<{
IFRAMELY: 'Iframely',
KAKAOTALK_SCRAP: 'kakaotalk-scrap',
META_EXTERNALFETCHER: 'meta-externalfetcher',
+ META_WHATSAPP: 'WhatsApp',
MICROSOFT_BINGPREVIEW: 'BingPreview',
MICROSOFT_PREVIEW: 'MicrosoftPreview',
MISTRALAI_USER: 'MistralAI-User',
@@ -621,17 +657,24 @@ export const Extension: Readonly<{
SNAP_URL_PREVIEW: 'Snap URL Preview',
SKYPE_URIPREVIEW: 'SkypeUriPreview',
TELEGRAM_BOT: 'TelegramBot',
- TIKTOK_SPIDER: 'TikTokSpider',
UPTIMEROBOT: 'UptimeRobot',
VERCEL_FAVICON_BOT: 'vercel-favicon-bot',
VERCEL_SCREENSHOT_BOT: 'vercel-screenshot-bot',
VERCEL_BOT: 'Vercelbot',
VERCEL_FLAGS: 'vercelflags',
VERCEL_TRACING: 'verceltracing',
- WHATSAPP: 'WhatsApp',
+ YANDEX_CALENDAR: 'YandexCalendar',
+ YANDEX_DIRECT: 'YandexDirect',
+ YANDEX_DIRECTDYN: 'YandexDirectDyn',
+ YANDEX_DIRECTFETCHER: 'YaDirectFetcher',
+ YANDEX_FORDOMAIN: 'YandexForDomain',
+ YANDEX_PAGECHECKER: 'YandexPagechecker',
+ YANDEX_SEARCHSHOP: 'YandexSearchShop',
+ YANDEX_SITELINKS: 'YandexSitelinks',
+ YANDEX_USERPROXY: 'YandexUserproxy',
ZOOMINFO_BOT: 'Zoombot'
},
- InApps: {
+ InApp: {
DISCORD: 'Discord',
EVERNOTE: 'Evernote',
FIGMA: 'Figma',
@@ -647,7 +690,7 @@ export const Extension: Readonly<{
VSCODE: 'VS Code',
YAHOO_JAPAN: 'Yahoo! Japan'
},
- Libraries: {
+ Library: {
ADOBE_AIR: 'AdobeAIR',
AIOHTTP: 'aiohttp',
APACHE_HTTPCLIENT: 'Apache-HttpClient',
@@ -675,7 +718,7 @@ export const Extension: Readonly<{
}
},
DeviceVendor: {
- Vehicles: {
+ Vehicle: {
BMW: 'BMW',
BYD: 'BYD',
JEEP: 'Jeep',
diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js
index dad31da..1dd8d9f 100644
--- a/src/enums/ua-parser-enums.js
+++ b/src/enums/ua-parser-enums.js
@@ -1,5 +1,5 @@
///////////////////////////////////////////////
-/* Enums for UAParser.js v2.0.4
+/* Enums for UAParser.js v2.0.5
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman
AGPLv3 License */
@@ -640,6 +640,7 @@ const Extension = Object.freeze({
IFRAMELY: 'Iframely',
KAKAOTALK_SCRAP: 'kakaotalk-scrap',
META_EXTERNALFETCHER: 'meta-externalfetcher',
+ META_WHATSAPP: 'WhatsApp',
MICROSOFT_BINGPREVIEW: 'BingPreview',
MICROSOFT_PREVIEW: 'MicrosoftPreview',
MISTRALAI_USER: 'MistralAI-User',
@@ -652,7 +653,6 @@ const Extension = Object.freeze({
SNAP_URL_PREVIEW: 'Snap URL Preview',
SKYPE_URIPREVIEW: 'SkypeUriPreview',
TELEGRAM_BOT: 'TelegramBot',
- TIKTOK_SPIDER: 'TikTokSpider',
UPTIMEROBOT: 'UptimeRobot',
VERCEL_FAVICON_BOT: 'vercel-favicon-bot',
VERCEL_SCREENSHOT_BOT: 'vercel-screenshot-bot',
@@ -668,7 +668,6 @@ const Extension = Object.freeze({
YANDEX_SEARCHSHOP: 'YandexSearchShop',
YANDEX_SITELINKS: 'YandexSitelinks',
YANDEX_USERPROXY: 'YandexUserproxy',
- WHATSAPP: 'WhatsApp',
ZOOMINFO_BOT: 'Zoombot'
},
InApp: {
diff --git a/src/enums/ua-parser-enums.mjs b/src/enums/ua-parser-enums.mjs
index 089af95..9c1f3f1 100644
--- a/src/enums/ua-parser-enums.mjs
+++ b/src/enums/ua-parser-enums.mjs
@@ -3,7 +3,7 @@
// Source: /src/enums/ua-parser-enums.js
///////////////////////////////////////////////
-/* Enums for UAParser.js v2.0.4
+/* Enums for UAParser.js v2.0.5
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman
AGPLv3 License */
@@ -11,7 +11,7 @@
/*jshint esversion: 6 */
-const Browser = Object.freeze({
+const BrowserName = Object.freeze({
'115': '115',
'2345': '2345',
'360': '360',
@@ -162,10 +162,15 @@ const Browser = Object.freeze({
WEIBO: 'Weibo',
WHALE: 'Whale',
WOLVIC: 'Wolvic',
- YANDEX: 'Yandex'
+ YANDEX: 'Yandex',
+ ZALO: 'Zalo'
// TODO : test!
});
+/**
+ * @deprecated Use `BrowserName` instead
+ */
+const Browser = BrowserName;
const BrowserType = Object.freeze({
CRAWLER: 'crawler',
@@ -177,8 +182,9 @@ const BrowserType = Object.freeze({
LIBRARY: 'library'
});
-const CPU = Object.freeze({
+const CPUArch = Object.freeze({
'68K': '68k',
+ ALPHA: 'alpha',
ARM : 'arm',
ARM_64: 'arm64',
ARM_HF: 'armhf',
@@ -196,8 +202,12 @@ const CPU = Object.freeze({
X86: 'ia32',
X86_64: 'amd64'
});
+/**
+ * @deprecated Use `CPUArch` instead
+ */
+const CPU = CPUArch;
-const Device = Object.freeze({
+const DeviceType = Object.freeze({
CONSOLE: 'console',
DESKTOP: 'desktop',
EMBEDDED: 'embedded',
@@ -207,8 +217,12 @@ const Device = Object.freeze({
WEARABLE: 'wearable',
XR: 'xr'
});
+/**
+ * @deprecated Use `DeviceType` instead
+ */
+const Device = DeviceType;
-const Vendor = Object.freeze({
+const DeviceVendor = Object.freeze({
ACER: 'Acer',
ADVAN: 'Advan',
ALCATEL: 'Alcatel',
@@ -256,6 +270,7 @@ const Vendor = Object.freeze({
PALM: 'Palm',
PANASONIC: 'Panasonic',
PEBBLE: 'Pebble',
+ PHILIPS: 'Philips',
PICO: 'Pico',
POLYTRON: 'Polytron',
REALME: 'Realme',
@@ -270,7 +285,7 @@ const Vendor = Object.freeze({
SPRINT: 'Sprint',
TCL: 'TCL',
TECHNISAT: 'TechniSAT',
- TECNO: 'Tecno',
+ TECNO: 'TECNO',
TESLA: 'Tesla',
ULEFONE: 'Ulefone',
VIVO: 'Vivo',
@@ -283,8 +298,12 @@ const Vendor = Object.freeze({
// TODO : test!
});
+/**
+ * @deprecated Use `DeviceVendor` instead
+ */
+const Vendor = DeviceVendor;
-const Engine = Object.freeze({
+const EngineName = Object.freeze({
AMAYA: 'Amaya',
ARKWEB: 'ArkWeb',
BLINK: 'Blink',
@@ -306,8 +325,12 @@ const Engine = Object.freeze({
W3M: 'w3m',
WEBKIT: 'WebKit'
});
+/**
+ * @deprecated Use `EngineName` instead
+ */
+const Engine = EngineName;
-const OS = Object.freeze({
+const OSName = Object.freeze({
AIX: 'AIX',
AMIGA_OS: 'Amiga OS',
ANDROID: 'Android',
@@ -403,13 +426,322 @@ const OS = Object.freeze({
// TODO : test!
});
+/**
+ * @deprecated Use `OSName` instead
+ */
+const OS = OSName;
+
+/*////////////////////////////////
+ * Enums for Extensions submodule
+ *///////////////////////////////
+
+const Extension = Object.freeze({
+ BrowserName: {
+ CLI: {
+ CURL: 'curl',
+ ELINKS: 'ELinks',
+ HTTPIE: 'HTTPie',
+ LYNX: 'Lynx',
+ WGET: 'Wget'
+ },
+ Crawler: {
+ AHREFS_BOT: 'AhrefsBot',
+ AI2_BOT: 'AI2Bot',
+ AIHIT_BOT: 'aiHitBot',
+ ALGOLIA_CRAWLER: 'Algolia Crawler',
+ APPLE_BOT: 'Applebot',
+ APPLE_BOT_EXTENDED: 'Applebot-Extended',
+ ASK_TEOMA: 'Teoma',
+ AMAZON_BOT: 'Amazonbot',
+ AMAZON_CONTXBOT: 'contxbot',
+ ANTHROPIC_AI: 'anthropic-ai',
+ ANTHROPIC_CLAUDE_BOT: 'ClaudeBot',
+ ANTHROPIC_CLAUDE_SEARCHBOT: 'Claude-SearchBot',
+ ANTHROPIC_CLAUDE_WEB: 'Claude-Web',
+ ARCHIVEORG_BOT: 'archive.org_bot',
+ BAIDU_ADS: 'Baidu-ADS',
+ BAIDU_SPIDER: 'Baiduspider',
+ BAIDU_SPIDER_ADS: 'Baiduspider-ads',
+ BAIDU_SPIDER_CPRO: 'Baiduspider-cpro',
+ BAIDU_SPIDER_FAVO: 'Baiduspider-favo',
+ BAIDU_SPIDER_IMAGE: 'Baiduspider-image',
+ BAIDU_SPIDER_NEWS: 'Baiduspider-news',
+ BAIDU_SPIDER_RENDER: 'Baiduspider-render',
+ BAIDU_SPIDER_VIDEO: 'Baiduspider-video',
+ BLEX_BOT: 'BLEXBot',
+ BOTIFY: 'botify',
+ BRAVE_BOT: 'Bravebot',
+ BYTEDANCE_BYTESPIDER: 'Bytespider',
+ BYTEDANCE_TIKTOKSPIDER: 'TikTokSpider',
+ COMMON_CRAWL_CCBOT: 'CCBot',
+ COCCOC_BOT_WEB: 'coccocbot-web',
+ COCCOC_BOT_IMAGE: 'coccocbot-image',
+ COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',
+ COTOYOGI: 'Cotoyogi',
+ COVEO_BOT: 'Coveobot',
+ CRITEO_BOT: 'CriteoBot',
+ DATAFORSEO_BOT: 'DataForSeoBot',
+ DAUM: 'Daum',
+ DAUM_DAUMOA: 'Daumoa',
+ DAUM_DAUMOA_IMAGE: 'Daumoa-image',
+ DEEPSEEK_BOT: 'DeepSeekBot',
+ DIFFBOT: 'Diffbot',
+ DUCKDUCKGO_BOT: 'DuckDuckBot',
+ DUCKDUCKGO_FAVICONS_BOT: 'DuckDuckGo-Favicons-Bot',
+ ELASTIC: 'Elastic',
+ EXALEAD_EXABOT: 'Exabot',
+ FIRECRAWL_AGENT: 'FirecrawlAgent',
+ FREESPOKE: 'Freespoke',
+ GOOGLE_ADSBOT: 'AdsBot-Google',
+ GOOGLE_ADSBOT_MOBILE: 'Adsbot-Google-Mobile',
+ GOOGLE_ADSENSE: 'AdSense',
+ GOOGLE_APIS: 'APIs-Google',
+ GOOGLE_BOT: 'Googlebot',
+ GOOGLE_BOT_IMAGE: 'Googlebot-Image',
+ GOOGLE_BOT_NEWS: 'Googlebot-News',
+ GOOGLE_BOT_VIDEO: 'Googlebot-Video',
+ GOOGLE_CLOUDVERTEXBOT: 'Google-CloudVertexBot',
+ GOOGLE_EXTENDED: 'Google-Extended',
+ GOOGLE_INSPECTIONTOOL: 'Google-InspectionTool',
+ GOOGLE_OTHER: 'GoogleOther',
+ GOOGLE_OTHER_IMAGE: 'GoogleOther-Image',
+ GOOGLE_OTHER_VIDEO: 'GoogleOther-Video',
+ GOOGLE_SAFETY: 'Google-Safety',
+ GOOGLE_STOREBOT: 'Storebot-Google',
+ HIVE_IMAGESIFTBOT: 'ImagesiftBot',
+ HUAWEI_PANGUBOT: 'PanguBot',
+ HUAWEI_PETALBOT: 'PetalBot',
+ HUGGINGFACE_BOT: 'HuggingFace-Bot',
+ HUNTER_VELENPUBLICWEBCRAWLER: 'VelenPublicWebCrawler',
+ IA_ARCHIVER: 'ia_archiver',
+ IASK_BOT: 'iAskBot',
+ KAGI_BOT: 'Kagibot',
+ KANGAROO_BOT: 'Kangaroo Bot',
+ LINE_SPIDER: 'Linespider',
+ LINKEDIN_BOT: 'LinkedInBot',
+ MAGPIE_CRAWLER: 'magpie-crawler',
+ MARGINALIA: 'marginalia',
+ META_EXTERNALAGENT: 'meta-externalagent',
+ META_FACEBOOKBOT: 'FacebookBot',
+ META_FACEBOOKCATALOG: 'facebookcatalog',
+ META_FACEBOOKEXTERNALHIT: 'facebookexternalhit',
+ MAJESTIC_MJ12BOT: 'MJ12bot',
+ MICROSOFT_BINGBOT: 'Bingbot',
+ MICROSOFT_MSNBOT: 'msnbot',
+ MICROSOFT_ADIDXBOT: 'adidxbot',
+ MOJEEK_BOT: 'MojeekBot',
+ MOZ_DOTBOT: 'DotBot',
+ ONCRAWL: 'OnCrawl',
+ ONESPOT_SCRAPERBOT: 'Onespot-ScraperBot',
+ OPENAI_GPTBOT: 'GPTBot',
+ OPENAI_SEARCH_BOT: 'OAI-SearchBot',
+ PERPLEXITY_BOT: 'PerplexityBot',
+ QIHOO_360_SPIDER: '360Spider',
+ QWANT_BOT: 'Qwantbot',
+ REPLICATE_BOT: 'Replicate-Bot',
+ RUNPOD_BOT: 'RunPod-Bot',
+ SB_INTUITIONS_BOT: 'SBIntuitionsBot',
+ SEEKPORT_BOT: 'SeekportBot',
+ SEMRUSH_BOT: 'SemrushBot',
+ SEMRUSH_BOT_BACKLINK: 'SemrushBot-BA',
+ SEMRUSH_BOT_CONTENTSHAKE: 'SemrushBot-OCOB',
+ SEMRUSH_BOT_SEO_CHECKER: 'SemrushBot-SI',
+ SEZNAM_BOT: 'SeznamBot',
+ SITEIMPROVE: 'Siteimprove',
+ SOGOU_PIC_SPIDER: 'Sogou Pic Spider',
+ SOGOU_WEB_SPIDER: 'Sogou web spider',
+ STARTPAGE: 'Startpage',
+ TIMPI_BOT: 'Timpibot',
+ TOGETHER_BOT: 'Together-Bot',
+ TURNITIN_BOT: 'TurnitinBot',
+ TWIN_AGENT: 'TwinAgent',
+ VERCEL_V0BOT: 'v0bot',
+ WEBZIO: 'webzio',
+ WEBZIO_EXTENDED: 'Webzio-Extended',
+ WEBZIO_OMGILI: 'omgili',
+ WEBZIO_OMGILI_BOT: 'omgilibot',
+ XAI_BOT: 'xAI-Bot',
+ YAHOO_JAPAN: 'Y!J-BRW',
+ YAHOO_SLURP: 'Yahoo! Slurp',
+ YANDEX_ACCESSIBILITY_BOT: 'YandexAccessibilityBot',
+ YANDEX_ADDITIONAL_BOT: 'YandexAdditionalBot',
+ YANDEX_ADNET: 'YandexAdNet',
+ YANDEX_BLOGS: 'YandexBlogs',
+ YANDEX_BOT: 'YandexBot',
+ YANDEX_BOT_MIRRORDETECTOR: 'YandexBot MirrorDetector',
+ YANDEX_COMBOT: 'YandexComBot',
+ YANDEX_FAVICONS: 'YandexFavicons',
+ YANDEX_IMAGE_RESIZER: 'YandexImageResizer',
+ YANDEX_IMAGES: 'YandexImages',
+ YANDEX_MARKET: 'YandexMarket',
+ YANDEX_MEDIA: 'YandexMedia',
+ YANDEX_METRIKA: 'YandexMetrika',
+ YANDEX_MOBILE_BOT: 'YandexMobileBot',
+ YANDEX_MOBILE_SCREENSHOT_BOT: 'YandexMobileScreenShotBot',
+ YANDEX_NEWS: 'YandexNews',
+ YANDEX_ONTODB: 'YandexOntoDB',
+ YANDEX_ONTODB_API: 'YandexOntoDBAPI',
+ YANDEX_PARTNER: 'YandexPartner',
+ YANDEX_RCA: 'YandexRCA',
+ YANDEX_RENDERRESOURCES_BOT: 'YandexRenderResourcesBot',
+ YANDEX_SCREENSHOT_BOT: 'YandexScreenshotBot',
+ YANDEX_SPRAV_BOT: 'YandexSpravBot',
+ YANDEX_TRACKER: 'YandexTracker',
+ YANDEX_VERTICALS: 'YandexVerticals',
+ YANDEX_VERTIS: 'YandexVertis',
+ YANDEX_VIDEO: 'YandexVideo',
+ YANDEX_VIDEO_PARSER: 'YandexVideoParser',
+ YANDEX_WEBMASTER: 'YandexWebmaster',
+ YEP_BOT: 'YepBot',
+ YETI: 'Yeti',
+ YISOU_SPIDER: 'YisouSpider',
+ YOU_BOT: 'YouBot',
+ ZHIPU_CHATGLM_SPIDER: 'ChatGLM-Spider',
+ ZUM_BOT: 'ZumBot'
+ },
+ Email: {
+ AIRMAIL: 'Airmail',
+ APPLE_MAIL: 'Mail',
+ BLUEMAIL: 'BlueMail',
+ DAUM_MAIL: 'DaumMail',
+ EVOLUTION: 'Evolution',
+ EM_CLIENT: 'eM Client',
+ FOXMAIL: 'Foxmail',
+ KMAIL: 'KMail',
+ KMAIL2: 'kmail2',
+ KONTACT: 'Kontact',
+ MICROSOFT_OUTLOOK: 'Microsoft Outlook',
+ MICROSOFT_OUTLOOK_MAC: 'MacOutlook',
+ NAVER_MAILAPP: 'NaverMailApp',
+ POLYMAIL: 'Polymail',
+ PROTON_MAIL: 'ProtonMail',
+ SPARK_MAIL: 'SparkDesktop',
+ SPARROW: 'Sparrow',
+ THUNDERBIRD: 'Thunderbird',
+ YAHOO_MAIL: 'Yahoo',
+ ZIMBRA: 'Zimbra',
+ ZOHO_MAIL: 'ZohoMail-Desktop'
+ },
+ Fetcher: {
+ AHREFS_SITEAUDIT: 'AhrefsSiteAudit',
+ ANTHROPIC_CLAUDE_USER: 'Claude-User',
+ ASANA: 'Asana',
+ BETTER_UPTIME_BOT: 'Better Uptime Bot',
+ BITLY_BOT: 'bitlybot',
+ BLUESKY: 'Bluesky',
+ BUFFER_LINKPREVIEWBOT: 'BufferLinkPreviewBot',
+ COHERE_AI: 'Cohere-AI',
+ DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',
+ GOOGLE_CHROME_LIGHTHOUSE: 'Chrome-Lighthouse',
+ GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',
+ GOOGLE_GEMINI_DEEP_RESEARCH: 'Gemini-Deep-Research',
+ GOOGLE_IMAGEPROXY: 'GoogleImageProxy',
+ GOOGLE_PAGERENDERER: 'Google-PageRenderer',
+ GOOGLE_READ_ALOUD: 'Google-Read-Aloud',
+ GOOGLE_PRODUCER: 'GoogleProducer',
+ GOOGLE_SITE_VERIFICATION: 'Google-Site-Verification',
+ HUBSPOT_PAGE_FETCHER: 'HubSpot Page Fetcher',
+ IFRAMELY: 'Iframely',
+ KAKAOTALK_SCRAP: 'kakaotalk-scrap',
+ META_EXTERNALFETCHER: 'meta-externalfetcher',
+ META_WHATSAPP: 'WhatsApp',
+ MICROSOFT_BINGPREVIEW: 'BingPreview',
+ MICROSOFT_PREVIEW: 'MicrosoftPreview',
+ MISTRALAI_USER: 'MistralAI-User',
+ NAVER_BLUENO: 'Blueno',
+ ONCRAWL_ROGERBOT: 'rogerbot',
+ OPENAI_CHATGPT_USER: 'ChatGPT-User',
+ PERPLEXITY_USER: 'Perplexity-User',
+ PINTEREST_BOT: 'Pinterestbot',
+ SEMRUSH_SITEAUDITBOT: 'SiteAuditBot',
+ SNAP_URL_PREVIEW: 'Snap URL Preview',
+ SKYPE_URIPREVIEW: 'SkypeUriPreview',
+ TELEGRAM_BOT: 'TelegramBot',
+ UPTIMEROBOT: 'UptimeRobot',
+ VERCEL_FAVICON_BOT: 'vercel-favicon-bot',
+ VERCEL_SCREENSHOT_BOT: 'vercel-screenshot-bot',
+ VERCEL_BOT: 'Vercelbot',
+ VERCEL_FLAGS: 'vercelflags',
+ VERCEL_TRACING: 'verceltracing',
+ YANDEX_CALENDAR: 'YandexCalendar',
+ YANDEX_DIRECT: 'YandexDirect',
+ YANDEX_DIRECTDYN: 'YandexDirectDyn',
+ YANDEX_DIRECTFETCHER: 'YaDirectFetcher',
+ YANDEX_FORDOMAIN: 'YandexForDomain',
+ YANDEX_PAGECHECKER: 'YandexPagechecker',
+ YANDEX_SEARCHSHOP: 'YandexSearchShop',
+ YANDEX_SITELINKS: 'YandexSitelinks',
+ YANDEX_USERPROXY: 'YandexUserproxy',
+ ZOOMINFO_BOT: 'Zoombot'
+ },
+ InApp: {
+ DISCORD: 'Discord',
+ EVERNOTE: 'Evernote',
+ FIGMA: 'Figma',
+ FLIPBOARD: 'Flipboard',
+ MATTERMOST: 'Mattermost',
+ TEAMS: 'Teams',
+ NOTION: 'Notion',
+ POSTMAN: 'Postman',
+ RAMBOX: 'Rambox',
+ ROCKETCHAT: 'Rocket.Chat',
+ SLACK: 'Slack',
+ TIKTOK_LITE: 'TikTok Lite',
+ VSCODE: 'VS Code',
+ YAHOO_JAPAN: 'Yahoo! Japan'
+ },
+ Library: {
+ ADOBE_AIR: 'AdobeAIR',
+ AIOHTTP: 'aiohttp',
+ APACHE_HTTPCLIENT: 'Apache-HttpClient',
+ AXIOS: 'axios',
+ GO_HTTP_CLIENT: 'go-http-client',
+ GOT: 'got',
+ GUZZLEHTTP: 'GuzzleHttp',
+ JAVA: 'Java',
+ JAVA_HTTPCLIENT: 'Java-http-client',
+ JSDOM: 'jsdom',
+ LIBWWW_PERL: 'libwww-perl',
+ LUA_RESTY_HTTP: 'lua-resty-http',
+ NEEDLE: 'Needle',
+ NUTCH: 'Nutch',
+ OKHTTP: 'OkHttp',
+ NODE_FETCH: 'node-fetch',
+ NODE_SUPERAGENT: 'node-superagent',
+ PHP_SOAP: 'PHP-SOAP',
+ POSTMAN_RUNTIME: 'PostmanRuntime',
+ PYTHON_HTTPX: 'python-httpx',
+ PYTHON_URLLIB: 'python-urllib',
+ PYTHON_URLLIB3: 'python-urllib3',
+ PYTHON_REQUESTS: 'python-requests',
+ SCRAPY: 'Scrapy'
+ }
+ },
+ DeviceVendor: {
+ Vehicle: {
+ BMW: 'BMW',
+ BYD: 'BYD',
+ JEEP: 'Jeep',
+ RIVIAN: 'Rivian',
+ TESLA: 'Tesla',
+ VOLVO: 'Volvo'
+ }
+ }
+});
export {
- Browser,
+ Browser,// deprecated
+ CPU, // deprecated
+ Device, // deprecated
+ Vendor, // deprecated
+ Engine, // deprecated
+ OS, // deprecated
+ BrowserName,
BrowserType,
- CPU,
- Device,
- Vendor,
- Engine,
- OS
+ CPUArch,
+ DeviceType,
+ DeviceVendor,
+ EngineName,
+ OSName,
+ Extension
};
\ No newline at end of file
diff --git a/src/extensions/ua-parser-extensions.d.ts b/src/extensions/ua-parser-extensions.d.ts
index 4ee31dd..3438970 100644
--- a/src/extensions/ua-parser-extensions.d.ts
+++ b/src/extensions/ua-parser-extensions.d.ts
@@ -1,4 +1,4 @@
-// Type definitions for Helpers submodule of UAParser.js v2.0.4
+// Type definitions for Helpers submodule of UAParser.js v2.0.5
// Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman
diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js
index cc6f8d0..2caf129 100644
--- a/src/extensions/ua-parser-extensions.js
+++ b/src/extensions/ua-parser-extensions.js
@@ -1,5 +1,5 @@
///////////////////////////////////////////////
-/* Extensions for UAParser.js v2.0.4
+/* Extensions for UAParser.js v2.0.5
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman
AGPLv3 License */
@@ -283,8 +283,8 @@ const Fetchers = Object.freeze({
[NAME, VERSION, [TYPE, FETCHER]],
[
- // Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / Snapchat / TikTokSpider / Vercelbot / Yandex Bots
- /((?:better uptime |telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|tiktokspider|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
+ // Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / Snapchat / Vercelbot / Yandex Bots
+ /((?:better uptime |telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
],
[NAME, [TYPE, FETCHER]],
],
diff --git a/src/extensions/ua-parser-extensions.mjs b/src/extensions/ua-parser-extensions.mjs
index 9401493..2260057 100644
--- a/src/extensions/ua-parser-extensions.mjs
+++ b/src/extensions/ua-parser-extensions.mjs
@@ -3,7 +3,7 @@
// Source: /src/extensions/ua-parser-extensions.js
///////////////////////////////////////////////
-/* Extensions for UAParser.js v2.0.4
+/* Extensions for UAParser.js v2.0.5
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman
AGPLv3 License */
@@ -47,20 +47,31 @@ const Crawlers = Object.freeze({
// AhrefsBot - https://ahrefs.com/robot
// Amazonbot - https://developer.amazon.com/amazonbot
// Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
+ // Bravebot - https://search.brave.com/help/brave-search-crawler
// CCBot - https://commoncrawl.org/faq
+ // contxbot - https://affiliate-program.amazon.com/help/node/topic/GT98G5PPRERNVZ2C
+ // Coveobot - https://connect.coveo.com/s/article/19648
+ // CriteoBot - https://www.criteo.com/criteo-crawler/
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot
// iAskBot - https://iask.ai
+ // Kagibot - https://kagi.com/bot
+ // Kangaroo Bot - https://kangaroollm.com.au/kangaroo-bot/
// LinkedInBot - http://www.linkedin.com
// MJ12bot - https://mj12bot.com/
// MojeekBot - https://www.mojeek.com/bot.html
// Onespot - https://www.onespot.com/identifying-traffic.html
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot
+ // SBIntuitionsBot - https://www.sbintuitions.co.jp/bot/
// SeznamBot - http://napoveda.seznam.cz/seznambot-intro
- /((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|iask|linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i,
+ // YepBot - https://yep.com/yepbot/
+ /((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|yep)bot)\/([\w\.-]+)/i,
+
+ // Algolia Crawler
+ /(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
// Applebot - http://apple.com/go/applebot
/(applebot(?:-extended)?)\/?([\w\.]*)/i,
@@ -69,7 +80,7 @@ const Crawlers = Object.freeze({
/(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i,
// ClaudeBot (Anthropic)
- /(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i,
+ /(claude(?:bot|-searchbot|-web)|anthropic-ai)\/?([\w\.]*)/i,
// Coc Coc Bot - https://help.coccoc.com/en/search-engine
/(coccocbot-(?:image|web))\/([\w\.]+)/i,
@@ -87,6 +98,9 @@ const Crawlers = Object.freeze({
// Internet Archive (archive.org)
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
+ // OnCrawl
+ /(oncrawl) mobile\/([\w\.]+)/i,
+
// Qwantbot - https://help.qwant.com/bot
/(qwantbot)[-\w]*\/?([\w\.]*)/i,
@@ -100,30 +114,38 @@ const Crawlers = Object.freeze({
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots
- /(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
+ /(yandex(?:(?:mobile)?(?:accessibility|additional|com|renderresources|screenshot|sprav)?bot(?!.+mirror)|image(?:s|resizer)|adnet|blogs|favicons|market|media|metrika|news|ontodb(?:api)?|partner|rca|tracker|turbo|verti(?:cal)?s|webmaster|video(?:parser)?))\/([\w\.]+)/i,
// Yeti (Naver)
/(yeti)\/([\w\.]+)/i,
- // aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot
- /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|startpageprivateimageproxy|webzio-extended|(?:chatglm-|line|screaming frog seo |yisou)spider)\/?([\w\.]*)/i
+ // aiHitBot / Algolia Crawler / BLEXBot / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot
+ // Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/
+ // Freespoke - https://docs.freespoke.com/search/bot/
+ /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cotoyogi|firecrawlagent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|twinagent|webzio-extended)\/?([\w\.]*)/i
],
-
[NAME, VERSION, [TYPE, CRAWLER]],
+ [
+ // YandexBot MirrorDetector
+ /(yandexbot\/([\w\.]+); mirrordetector)/i
+ ],
+ [[NAME, /\/.+;/ig, ''], VERSION, [TYPE, CRAWLER]],
+
[
// Google Bots
/((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
// AI2Bot - https://allenai.org/crawler
- // Bytespider
// DataForSeoBot - https://dataforseo.com/dataforseo-bot
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
// ImagesiftBot - https://imagesift.com/about
- // Qihoo 360Spider
+ // Siteimprove - https://help.siteimprove.com/support/solutions/articles/80000448553
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
+ // v0bot - https://vercel.com/docs/bot-management
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
- /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i
+ // Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider
+ /\b((ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
],
[NAME, [TYPE, CRAWLER]]
]
@@ -238,16 +260,17 @@ const Emails = Object.freeze({
const Fetchers = Object.freeze({
browser : [
[
+ // Asana / Bitlybot / Better Uptime / BingPreview / Blueno / Cohere-AI / HubSpot Page Fetcher / kakaotalk-scrap / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
+ // Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
- // Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
// Google Site Verifier / Meta / Yahoo! Japan
// Iframely - https://iframely.com/docs/about
// Perplexity-User - https://docs.perplexity.ai/guides/bots
// MistralAI-User - https://docs.mistral.ai/robots/
// Yandex Bots - https://yandex.com/bots
- /(ahrefssiteaudit|(?:bing|microsoft)preview|(?:chatgpt|mistralai|perplexity)-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|iframely|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
+ /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
// Bluesky
/(bluesky) cardyb\/([\w\.]+)/i,
@@ -264,8 +287,8 @@ const Fetchers = Object.freeze({
[NAME, VERSION, [TYPE, FETCHER]],
[
- // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots
- /((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i
+ // Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / Snapchat / Vercelbot / Yandex Bots
+ /((?:better uptime |telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
],
[NAME, [TYPE, FETCHER]],
],
@@ -408,8 +431,8 @@ const Vehicles = Object.freeze({
const Bots = Object.freeze({
browser : [
...CLIs.browser,
- ...Crawlers.browser,
...Fetchers.browser,
+ ...Crawlers.browser,
...Libraries.browser
],
os : [
diff --git a/src/helpers/ua-parser-helpers.d.ts b/src/helpers/ua-parser-helpers.d.ts
index c860fd2..caee9cb 100644
--- a/src/helpers/ua-parser-helpers.d.ts
+++ b/src/helpers/ua-parser-helpers.d.ts
@@ -1,4 +1,4 @@
-// Type definitions for Helpers submodule of UAParser.js v2.0.4
+// Type definitions for Helpers submodule of UAParser.js v2.0.5
// Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman
diff --git a/src/helpers/ua-parser-helpers.js b/src/helpers/ua-parser-helpers.js
index 54ce86f..b19d0bf 100644
--- a/src/helpers/ua-parser-helpers.js
+++ b/src/helpers/ua-parser-helpers.js
@@ -1,5 +1,5 @@
///////////////////////////////////////////////
-/* Helpers for UAParser.js v2.0.4
+/* Helpers for UAParser.js v2.0.5
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman
AGPLv3 License */
diff --git a/src/helpers/ua-parser-helpers.mjs b/src/helpers/ua-parser-helpers.mjs
index 3530e7d..5cdcdf0 100644
--- a/src/helpers/ua-parser-helpers.mjs
+++ b/src/helpers/ua-parser-helpers.mjs
@@ -3,7 +3,7 @@
// Source: /src/helpers/ua-parser-helpers.js
///////////////////////////////////////////////
-/* Helpers for UAParser.js v2.0.4
+/* Helpers for UAParser.js v2.0.5
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman
AGPLv3 License */
@@ -12,11 +12,12 @@
/*jshint esversion: 6 */
import { UAParser } from '../main/ua-parser.mjs';
-import { CPU, OS, Engine } from '../enums/ua-parser-enums.mjs';
-import { Bots } from '../extensions/ua-parser-extensions.mjs';
+import { CPUArch, OSName, EngineName, Extension, BrowserType } from '../enums/ua-parser-enums.mjs';
+import { Bots, Crawlers } from '../extensions/ua-parser-extensions.mjs';
import { isFromEU } from 'detect-europe-js';
import { isFrozenUA } from 'ua-is-frozen';
import { isStandalonePWA } from 'is-standalone-pwa';
+const { Crawler } = Extension.BrowserName;
const toResult = (value, head, ext) => typeof value === 'string' ? UAParser(value, head, ext) : value;
@@ -24,8 +25,8 @@ const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${m
const isAppleSilicon = (resultOrUA) => {
const res = toResult(resultOrUA);
- if (res.os.is(OS.MACOS)) {
- if (res.cpu.is(CPU.ARM)) {
+ if (res.os.is(OSName.MACOS)) {
+ if (res.cpu.is(CPUArch.ARM)) {
return true;
}
if (typeof resultOrUA !== 'string' && typeof window !== 'undefined') {
@@ -48,88 +49,129 @@ const isAppleSilicon = (resultOrUA) => {
const isAIBot = (resultOrUA) => [
// AI2
- 'ai2bot',
+ Crawler.AI2_BOT,
// Amazon
- 'amazonbot',
+ Crawler.AMAZON_BOT,
// Anthropic
- 'anthropic-ai',
- 'claude-web',
- 'claudebot',
+ Crawler.ANTHROPIC_AI,
+ Crawler.ANTHROPIC_CLAUDE_BOT,
+ Crawler.ANTHROPIC_CLAUDE_SEARCHBOT,
+ Crawler.ANTHROPIC_CLAUDE_WEB,
// Apple
- 'applebot',
- 'applebot-extended',
+ Crawler.APPLE_BOT,
+ Crawler.APPLE_BOT_EXTENDED,
+
+ // Brave
+ Crawler.BRAVE_BOT,
// ByteDance
- 'bytespider',
+ Crawler.BYTEDANCE_BYTESPIDER,
+ Crawler.BYTEDANCE_TIKTOKSPIDER,
+
+ // Cohere
+ Crawler.COHERE_TRAINING_DATA_CRAWLER,
// Common Crawl
- 'ccbot',
+ Crawler.COMMON_CRAWL_CCBOT,
+
+ // Coveo
+ Crawler.COVEO_BOT,
// DataForSeo
- 'dataforseobot',
+ Crawler.DATAFORSEO_BOT,
+
+ // DeepSeek
+ Crawler.DEEPSEEK_BOT,
// Diffbot
- 'diffbot',
+ Crawler.DIFFBOT,
// Google
- 'googleother',
- 'googleother-image',
- 'googleother-video',
- 'google-extended',
+ Crawler.GOOGLE_EXTENDED,
+ Crawler.GOOGLE_OTHER,
+ Crawler.GOOGLE_OTHER_IMAGE,
+ Crawler.GOOGLE_OTHER_VIDEO,
+ Crawler.GOOGLE_CLOUDVERTEXBOT,
// Hive AI
- 'imagesiftbot',
+ Crawler.HIVE_IMAGESIFTBOT,
// Huawei
- 'petalbot',
+ Crawler.HUAWEI_PETALBOT,
+ Crawler.HUAWEI_PANGUBOT,
+
+ // Hugging Face
+ Crawler.HUGGINGFACE_BOT,
+
+ // Kangaroo
+ Crawler.KANGAROO_BOT,
+
+ // Mendable.ai
+ Crawler.FIRECRAWL_AGENT,
// Meta
- 'facebookbot',
- 'meta-externalagent',
+ Crawler.META_FACEBOOKBOT,
+ Crawler.META_EXTERNALAGENT,
// OpenAI
- 'gptbot',
- 'oai-searchbot',
+ Crawler.OPENAI_GPTBOT,
+ Crawler.OPENAI_SEARCH_BOT,
// Perplexity
- 'perplexitybot',
+ Crawler.PERPLEXITY_BOT,
+
+ // Replicate
+ Crawler.REPLICATE_BOT,
+
+ // Runpod
+ Crawler.RUNPOD_BOT,
+
+ // SB Intuitions
+ Crawler.SB_INTUITIONS_BOT,
// Semrush
- 'semrushbot-ocob',
+ Crawler.SEMRUSH_BOT_CONTENTSHAKE,
// Timpi
- 'timpibot',
+ Crawler.TIMPI_BOT,
+
+ // Together AI
+ Crawler.TOGETHER_BOT,
// Velen.io
- 'velenpublicwebcrawler',
+ Crawler.HUNTER_VELENPUBLICWEBCRAWLER,
+
+ // Vercel
+ Crawler.VERCEL_V0BOT,
// Webz.io
- 'omgili',
- 'omgilibot',
- 'webzio-extended',
+ Crawler.WEBZIO_OMGILI,
+ Crawler.WEBZIO_OMGILI_BOT,
+ Crawler.WEBZIO_EXTENDED,
+
+ // X
+ Crawler.XAI_BOT,
// You.com
- 'youbot',
+ Crawler.YOU_BOT,
// Zhipu AI
- 'chatglm-spider',
-
- // Zyte
- 'scrapy'
-
- ].includes(String(toResult(resultOrUA, Bots).browser.name).toLowerCase());
+ Crawler.ZHIPU_CHATGLM_SPIDER
+ ]
+ .map((s) => s.toLowerCase())
+ .includes(String(toResult(resultOrUA, Crawlers).browser.name).toLowerCase());
const isBot = (resultOrUA) => [
- 'cli',
- 'crawler',
- 'fetcher',
- 'library'
+ BrowserType.CLI,
+ BrowserType.CRAWLER,
+ BrowserType.FETCHER,
+ BrowserType.LIBRARY
].includes(toResult(resultOrUA, Bots).browser.type);
-const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(Engine.BLINK);
+const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(EngineName.BLINK);
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
/ electron\//i.test(navigator?.userAgent)); // browser
diff --git a/src/main/ua-parser.d.ts b/src/main/ua-parser.d.ts
index 6fd0ef5..09c11ee 100644
--- a/src/main/ua-parser.d.ts
+++ b/src/main/ua-parser.d.ts
@@ -1,4 +1,4 @@
-// Type definitions for UAParser.js v2.0.4
+// Type definitions for UAParser.js v2.0.5
// Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman
diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js
index 2030ae8..bc0ef93 100755
--- a/src/main/ua-parser.js
+++ b/src/main/ua-parser.js
@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////////
-/* UAParser.js v2.0.4
+/* UAParser.js v2.0.5
Copyright © 2012-2025 Faisal Salman
AGPLv3 License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@@ -19,7 +19,7 @@
// Constants
/////////////
- var LIBVERSION = '2.0.4',
+ var LIBVERSION = '2.0.5',
UA_MAX_LENGTH = 500,
USER_AGENT = 'user-agent',
EMPTY = '',
diff --git a/src/main/ua-parser.mjs b/src/main/ua-parser.mjs
index 2b45cda..04545da 100644
--- a/src/main/ua-parser.mjs
+++ b/src/main/ua-parser.mjs
@@ -3,7 +3,7 @@
// Source: /src/main/ua-parser.js
/////////////////////////////////////////////////////////////////////////////////
-/* UAParser.js v2.0.4
+/* UAParser.js v2.0.5
Copyright © 2012-2025 Faisal Salman
AGPLv3 License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@@ -21,7 +21,7 @@
// Constants
/////////////
- var LIBVERSION = '2.0.4',
+ var LIBVERSION = '2.0.5',
UA_MAX_LENGTH = 500,
USER_AGENT = 'user-agent',
EMPTY = '',
@@ -459,6 +459,8 @@
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME, [TYPE, INAPP]], [
+ /(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i // Zalo
+ ], [[NAME, /(.+)/, 'Zalo'], VERSION, [TYPE, INAPP]], [
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
], [NAME, VERSION], [
@@ -540,15 +542,15 @@
/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
], [[ARCHITECTURE, 'arm']], [
- /((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC
- ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
-
/ sun4\w[;\)]/i // SPARC
], [[ARCHITECTURE, 'sparc']], [
-
- /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
- ], [[ARCHITECTURE, lowerize]]
+ /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,
+ /((ppc|powerpc)(64)?)( mac|;|\))/i, // PowerPC
+ /(?:osf1|[freopnt]{3,4}bsd) (alpha)/i // Alpha
+ ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
+ /winnt.+\[axp/i
+ ], [[ARCHITECTURE, 'alpha']]
],
device : [[
@@ -772,7 +774,8 @@
/; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL
/(hp) ([\w ]+\w)/i, // HP iPAQ
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
- /(oppo) ?([\w ]+) bui/i // OPPO
+ /(oppo) ?([\w ]+) bui/i, // OPPO
+ /droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i // Philips
], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(kobo)\s(ereader|touch)/i, // Kobo
@@ -799,6 +802,7 @@
// SMARTTVS
///////////////////
+ /(philips)[\w ]+tv/i, // Philips
/smart-tv.+(samsung)/i // Samsung
], [VENDOR, [TYPE, SMARTTV]], [
/hbbtv.+maple;(\d+)/i
@@ -836,11 +840,6 @@
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [
- // SmartTV from Unidentified Vendors
- /droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i
- ], [MODEL, [TYPE, SMARTTV]], [
- /\b(android tv|smart[- ]?tv|opera tv|tv; rv:|large screen[\w ]+safari)\b/i
- ], [[TYPE, SMARTTV]], [
///////////////////
// CONSOLES
@@ -887,7 +886,7 @@
/droid.+; (glass) \d/i // Google Glass
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
- /(pico) (4|neo3(?: link|pro)?)/i // Pico
+ /(pico) ([\w ]+) os\d/i // Pico
], [VENDOR, MODEL, [TYPE, XR]], [
/(quest( \d| pro)?s?).+vr/i // Meta Quest
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
@@ -911,6 +910,10 @@
// MIXED (GENERIC)
///////////////////
+ /droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i // Unidentifiable SmartTV
+ ], [MODEL, [TYPE, SMARTTV]], [
+ /\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
+ ], [[TYPE, SMARTTV]], [
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i
], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
@@ -1389,11 +1392,22 @@
extensions = undefined;
}
- // Convert Headers object into a plain object
- if (headers && typeof headers.append === FUNC_TYPE) {
- var kv = {};
- headers.forEach(function (v, k) { kv[k] = v; });
- headers = kv;
+ if (headers) {
+ if (typeof headers.append === FUNC_TYPE) {
+ // Convert Headers object into a plain object
+ var kv = {};
+ headers.forEach(function (v, k) { kv[String(k).toLowerCase()] = v; });
+ headers = kv;
+ } else {
+ // Normalize headers field name into lowercase
+ var normalized = {};
+ for (var header in headers) {
+ if (headers.hasOwnProperty(header)) {
+ normalized[String(header).toLowerCase()] = headers[header];
+ }
+ }
+ headers = normalized;
+ }
}
if (!(this instanceof UAParser)) {
diff --git a/test/data/ua/extension/fetcher.json b/test/data/ua/extension/fetcher.json
index 7b0bd4e..373b402 100644
--- a/test/data/ua/extension/fetcher.json
+++ b/test/data/ua/extension/fetcher.json
@@ -339,16 +339,6 @@
"type" : "fetcher"
}
},
- {
- "desc" : "TikTokSpider",
- "ua" : "Mozilla/5.0 (Linux; Android 5.0) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; TikTokSpider; ttspider-feedback@tiktok.com)",
- "expect" :
- {
- "name" : "TikTokSpider",
- "version" : "undefined",
- "type" : "fetcher"
- }
- },
{
"desc" : "UptimeRobot",
"ua" : "Mozilla/5.0 (compatible; UptimeRobot/2.0; http://www.uptimerobot.com/)",