ua-parser-js 2.0.9 → 2.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -10
- package/dist/ua-parser.min.js +2 -2
- package/dist/ua-parser.min.mjs +2 -2
- package/dist/ua-parser.pack.js +2 -2
- package/dist/ua-parser.pack.mjs +2 -2
- package/package.json +19 -2
- package/src/bot-detection/bot-detection.d.ts +6 -4
- package/src/bot-detection/bot-detection.js +2 -1
- package/src/bot-detection/bot-detection.mjs +2 -1
- package/src/browser-detection/browser-detection.d.ts +1 -1
- package/src/browser-detection/browser-detection.js +6 -3
- package/src/browser-detection/browser-detection.mjs +6 -3
- package/src/device-detection/device-detection.d.ts +1 -1
- package/src/device-detection/device-detection.js +1 -1
- package/src/device-detection/device-detection.mjs +1 -1
- package/src/enums/ua-parser-enums.d.ts +29 -4
- package/src/enums/ua-parser-enums.js +29 -4
- package/src/enums/ua-parser-enums.mjs +29 -4
- package/src/extensions/ua-parser-extensions.d.ts +1 -1
- package/src/extensions/ua-parser-extensions.js +22 -11
- package/src/extensions/ua-parser-extensions.mjs +22 -11
- package/src/helpers/ua-parser-helpers.d.ts +1 -1
- package/src/helpers/ua-parser-helpers.js +2 -2
- package/src/helpers/ua-parser-helpers.mjs +2 -2
- package/src/main/ua-parser.d.ts +11 -5
- package/src/main/ua-parser.js +53 -29
- package/src/main/ua-parser.mjs +53 -29
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Source: /src/extensions/ua-parser-extensions.js
|
|
4
4
|
|
|
5
5
|
///////////////////////////////////////////////
|
|
6
|
-
/* Extensions for UAParser.js v2.0.
|
|
6
|
+
/* Extensions for UAParser.js v2.0.10
|
|
7
7
|
https://github.com/faisalman/ua-parser-js
|
|
8
8
|
Author: Faisal Salman <f@faisalman.com>
|
|
9
9
|
AGPLv3 License */
|
|
@@ -59,6 +59,7 @@ const Crawlers = Object.freeze({
|
|
|
59
59
|
[
|
|
60
60
|
// AhrefsBot - https://ahrefs.com/robot
|
|
61
61
|
// Amazonbot - https://developer.amazon.com/amazonbot
|
|
62
|
+
// Awario - https://awario.com/bots.html
|
|
62
63
|
// Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
|
|
63
64
|
// Bravebot - https://search.brave.com/help/brave-search-crawler
|
|
64
65
|
// CCBot - https://commoncrawl.org/faq
|
|
@@ -83,7 +84,7 @@ const Crawlers = Object.freeze({
|
|
|
83
84
|
// SurdotlyBot - http://sur.ly/bot.html
|
|
84
85
|
// Swiftbot - https://swiftype.com/swiftbot
|
|
85
86
|
// YepBot - https://yep.com/yepbot/
|
|
86
|
-
/((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|
|
|
87
|
+
/((?:adidx|ahrefs|amazon|(?:amzn|oai)-search|awario(?:smart|rss)?|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i,
|
|
87
88
|
|
|
88
89
|
// Algolia Crawler
|
|
89
90
|
/(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
|
|
@@ -100,12 +101,12 @@ const Crawlers = Object.freeze({
|
|
|
100
101
|
// Coc Coc Bot - https://help.coccoc.com/en/search-engine
|
|
101
102
|
/(coccocbot-(?:image|web))\/([\w\.]+)/i,
|
|
102
103
|
|
|
103
|
-
// Daum
|
|
104
|
-
/(daum(?:oa)?(?:-image)
|
|
104
|
+
// Daum / HubSpot Crawler
|
|
105
|
+
/(daum(?:oa)?(?:-image)?|hubspot crawler)[ \/]([\w\.]+)/i,
|
|
105
106
|
|
|
106
107
|
// Facebook / Meta
|
|
107
108
|
// https://developers.facebook.com/docs/sharing/webmasters/web-crawlers
|
|
108
|
-
/(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,
|
|
109
|
+
/(facebook(?:externalhit|catalog)|meta-(?:externalagent|externalads|webindexer))\/([\w\.]+)/i,
|
|
109
110
|
|
|
110
111
|
// Googlebot - http://www.google.com/bot.html
|
|
111
112
|
/(google(?:bot|other|-inspectiontool)(?:-image|-video|-news)?|storebot-google)\/?([\w\.]*)/i,
|
|
@@ -134,13 +135,19 @@ const Crawlers = Object.freeze({
|
|
|
134
135
|
// Yeti (Naver)
|
|
135
136
|
/(yeti)\/([\w\.]+)/i,
|
|
136
137
|
|
|
137
|
-
// aiHitBot / Algolia Crawler / BLEXBot / Cloudflare AutoRAG / 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
|
|
138
|
+
// aiHitBot / Algolia Crawler / Audisto Crawler / BLEXBot / BrightEdge Crawler / Cloudflare AutoRAG / 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
|
|
138
139
|
// Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/
|
|
139
140
|
// Freespoke - https://docs.freespoke.com/search/bot/
|
|
140
|
-
/((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cloudflare-autorag|cotoyogi|(?:firecrawl|twin)agent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|webzio-extended)\/?([\w\.]*)/i
|
|
141
|
+
/((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:audisto |brightedge |magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cloudflare-autorag|cotoyogi|(?:firecrawl|twin)agent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|webzio-extended)\/?([\w\.]*)/i
|
|
141
142
|
],
|
|
142
143
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
|
143
144
|
|
|
145
|
+
[
|
|
146
|
+
// Headline - https://headline.com/legal/crawler
|
|
147
|
+
/(ev-crawler)\/([\w\.]+)/i
|
|
148
|
+
],
|
|
149
|
+
[[NAME, 'Headline'], VERSION, [TYPE, CRAWLER]],
|
|
150
|
+
|
|
144
151
|
[
|
|
145
152
|
// YandexBot MirrorDetector
|
|
146
153
|
/(yandexbot\/([\w\.]+); mirrordetector)/i
|
|
@@ -160,7 +167,7 @@ const Crawlers = Object.freeze({
|
|
|
160
167
|
// v0bot - https://vercel.com/docs/bot-management
|
|
161
168
|
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
|
|
162
169
|
// Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider
|
|
163
|
-
/\b((ai2|aspiegel|atlassian-|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
|
|
170
|
+
/\b((ai2|aspiegel|atlassian-|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0|yacy)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|proximic|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
|
|
164
171
|
],
|
|
165
172
|
[NAME, [TYPE, CRAWLER]]
|
|
166
173
|
]
|
|
@@ -310,17 +317,21 @@ const Fetchers = Object.freeze({
|
|
|
310
317
|
// Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
|
|
311
318
|
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot
|
|
312
319
|
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
|
|
320
|
+
// Feedly - https://feedly.com/fetcher.html
|
|
313
321
|
// FlipboardProxy - https://about.flipboard.com/proxy-service/
|
|
314
322
|
// Google Site Verifier / Meta / Yahoo! Japan
|
|
315
323
|
// Iframely - https://iframely.com/docs/about
|
|
316
324
|
// Perplexity-User - https://docs.perplexity.ai/guides/bots
|
|
317
325
|
// MistralAI-User - https://docs.mistral.ai/robots/
|
|
318
326
|
// Yandex Bots - https://yandex.com/bots
|
|
319
|
-
/(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|flipboardproxy|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|
|
|
327
|
+
/(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:amzn|chatgpt|claude|mistralai|perplexity)-user|cohere-ai|flipboardproxy|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptime(?:ro)?|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i,
|
|
320
328
|
|
|
321
329
|
// Bluesky
|
|
322
330
|
/(bluesky) cardyb\/([\w\.]+)/i,
|
|
323
331
|
|
|
332
|
+
// Feedly
|
|
333
|
+
/(feedly)(?:bot)?\/([\w\.]+)/i,
|
|
334
|
+
|
|
324
335
|
// Nova Act - https://github.com/aws/nova-act
|
|
325
336
|
/agent-(novaact)\/([\w\.]+)/i,
|
|
326
337
|
|
|
@@ -334,7 +345,7 @@ const Fetchers = Object.freeze({
|
|
|
334
345
|
|
|
335
346
|
[
|
|
336
347
|
// Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / KeybaseBot / Snapchat / Vercelbot / Yandex Bots
|
|
337
|
-
/((?:better uptime |keybase|telegram|vercel)bot|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
|
|
348
|
+
/((?:better uptime |keybase|telegram|vercel)bot|lighthouse$|feedfetcher-google|gemini-deep-research|google(?:docs|imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|virustotal(?=cloud)|yandex(?:sitelinks|userproxy))/i
|
|
338
349
|
],
|
|
339
350
|
[NAME, [TYPE, FETCHER]],
|
|
340
351
|
],
|
|
@@ -444,7 +455,7 @@ const Libraries = Object.freeze({
|
|
|
444
455
|
/(nutch)-([\w\.-]+)(\(|$)/i,
|
|
445
456
|
/\((java)\/([\w\.]+)/i
|
|
446
457
|
], [NAME, VERSION, [TYPE, LIBRARY]], [
|
|
447
|
-
/(node-fetch|undici)/i
|
|
458
|
+
/(node-fetch|phpcrawl|undici)/i
|
|
448
459
|
], [NAME, [TYPE, LIBRARY]]
|
|
449
460
|
]
|
|
450
461
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
///////////////////////////////////////////////
|
|
2
|
-
/* Helpers for UAParser.js v2.0.
|
|
2
|
+
/* Helpers for UAParser.js v2.0.10
|
|
3
3
|
https://github.com/faisalman/ua-parser-js
|
|
4
4
|
Author: Faisal Salman <f@faisalman.com>
|
|
5
5
|
AGPLv3 License */
|
|
@@ -41,7 +41,7 @@ const isChromeFamily = _isChromeFamily;
|
|
|
41
41
|
/**
|
|
42
42
|
* @deprecated Moved to `browser-detection` submodule
|
|
43
43
|
*/
|
|
44
|
-
const isElectron =
|
|
44
|
+
const isElectron = _isElectron;
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* @deprecated Moved to `browser-detection` submodule
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Source: /src/helpers/ua-parser-helpers.js
|
|
4
4
|
|
|
5
5
|
///////////////////////////////////////////////
|
|
6
|
-
/* Helpers for UAParser.js v2.0.
|
|
6
|
+
/* Helpers for UAParser.js v2.0.10
|
|
7
7
|
https://github.com/faisalman/ua-parser-js
|
|
8
8
|
Author: Faisal Salman <f@faisalman.com>
|
|
9
9
|
AGPLv3 License */
|
|
@@ -45,7 +45,7 @@ const isChromeFamily = _isChromeFamily;
|
|
|
45
45
|
/**
|
|
46
46
|
* @deprecated Moved to `browser-detection` submodule
|
|
47
47
|
*/
|
|
48
|
-
const isElectron =
|
|
48
|
+
const isElectron = _isElectron;
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* @deprecated Moved to `browser-detection` submodule
|
package/src/main/ua-parser.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
// Type definitions for UAParser.js v2.0.
|
|
1
|
+
// Type definitions for UAParser.js v2.0.10
|
|
2
2
|
// Project: https://github.com/faisalman/ua-parser-js
|
|
3
3
|
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
|
4
4
|
|
|
5
5
|
import { BrowserType, CPUArch, DeviceType, EngineName } from "../enums/ua-parser-enums";
|
|
6
6
|
|
|
7
7
|
declare namespace UAParser {
|
|
8
|
+
|
|
9
|
+
type BrowserTypes = typeof BrowserType[keyof typeof BrowserType];
|
|
10
|
+
type CPUArchs = typeof CPUArch[keyof typeof CPUArch];
|
|
11
|
+
type DeviceTypes = typeof DeviceType[keyof typeof DeviceType];
|
|
12
|
+
type EngineNames = typeof EngineName[keyof typeof EngineName];
|
|
8
13
|
|
|
9
14
|
interface IData<T> {
|
|
10
15
|
is(val: string): boolean;
|
|
@@ -17,21 +22,21 @@ declare namespace UAParser {
|
|
|
17
22
|
name?: string;
|
|
18
23
|
version?: string;
|
|
19
24
|
major?: string;
|
|
20
|
-
type?:
|
|
25
|
+
type?: BrowserTypes;
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
interface ICPU extends IData<ICPU> {
|
|
24
|
-
architecture?:
|
|
29
|
+
architecture?: CPUArchs;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
interface IDevice extends IData<IDevice> {
|
|
28
|
-
type?:
|
|
33
|
+
type?: DeviceTypes;
|
|
29
34
|
vendor?: string;
|
|
30
35
|
model?: string;
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
interface IEngine extends IData<IEngine> {
|
|
34
|
-
name?:
|
|
39
|
+
name?: EngineNames;
|
|
35
40
|
version?: string;
|
|
36
41
|
}
|
|
37
42
|
|
|
@@ -105,6 +110,7 @@ declare namespace UAParser {
|
|
|
105
110
|
getOS(): IOS;
|
|
106
111
|
getResult(): IResult;
|
|
107
112
|
setUA(uastring: string): UAParser;
|
|
113
|
+
useExtension(extensions: UAParserExt): UAParser;
|
|
108
114
|
}
|
|
109
115
|
}
|
|
110
116
|
|
package/src/main/ua-parser.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
/* UAParser.js v2.0.
|
|
2
|
+
/* UAParser.js v2.0.10
|
|
3
3
|
Copyright © 2012-2026 Faisal Salman <f@faisalman.com>
|
|
4
4
|
AGPLv3 License *//*
|
|
5
5
|
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
// Constants
|
|
20
20
|
/////////////
|
|
21
21
|
|
|
22
|
-
var LIBVERSION = '2.0.
|
|
22
|
+
var LIBVERSION = '2.0.10',
|
|
23
23
|
UA_MAX_LENGTH = 500,
|
|
24
24
|
USER_AGENT = 'user-agent',
|
|
25
25
|
EMPTY = '',
|
|
@@ -170,7 +170,7 @@
|
|
|
170
170
|
itemListToArray = function (header) {
|
|
171
171
|
if (!header) return undefined;
|
|
172
172
|
var arr = [];
|
|
173
|
-
var tokens =
|
|
173
|
+
var tokens = normalizeHeaderValue(header).split(',');
|
|
174
174
|
for (var i = 0; i < tokens.length; i++) {
|
|
175
175
|
if (tokens[i].indexOf(';') > -1) {
|
|
176
176
|
var token = trim(tokens[i]).split(';v=');
|
|
@@ -187,6 +187,9 @@
|
|
|
187
187
|
majorize = function (version) {
|
|
188
188
|
return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
|
|
189
189
|
},
|
|
190
|
+
normalizeHeaderValue = function (str) {
|
|
191
|
+
return isString(str) ? trim(strip(/\\?\"/g, str), UA_MAX_LENGTH) : undefined;
|
|
192
|
+
},
|
|
190
193
|
setProps = function (arr) {
|
|
191
194
|
for (var i in arr) {
|
|
192
195
|
if (!arr.hasOwnProperty(i)) continue;
|
|
@@ -203,9 +206,6 @@
|
|
|
203
206
|
strip = function (pattern, str) {
|
|
204
207
|
return isString(str) ? str.replace(pattern, EMPTY) : str;
|
|
205
208
|
},
|
|
206
|
-
stripQuotes = function (str) {
|
|
207
|
-
return strip(/\\?\"/g, str);
|
|
208
|
-
},
|
|
209
209
|
trim = function (str, len) {
|
|
210
210
|
str = strip(/^\s\s*/, String(str));
|
|
211
211
|
return typeof len === TYPEOF.UNDEFINED ? str : str.substring(0, len);
|
|
@@ -278,6 +278,10 @@
|
|
|
278
278
|
}
|
|
279
279
|
},
|
|
280
280
|
|
|
281
|
+
strTest = function (str, map) {
|
|
282
|
+
return map.test.test(str) ? map.ifTrue : map.ifFalse;
|
|
283
|
+
},
|
|
284
|
+
|
|
281
285
|
strMapper = function (str, map) {
|
|
282
286
|
|
|
283
287
|
for (var i in map) {
|
|
@@ -348,7 +352,7 @@
|
|
|
348
352
|
/\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
|
|
349
353
|
], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
|
|
350
354
|
/webview.+edge\/([\w\.]+)/i // Microsoft Edge
|
|
351
|
-
], [VERSION, [NAME, EDGE+' WebView']], [
|
|
355
|
+
], [VERSION, [NAME, EDGE+' WebView'], [TYPE, INAPP]], [
|
|
352
356
|
/edg(?:e|ios|a)?\/([\w\.]+)/i
|
|
353
357
|
], [VERSION, [NAME, 'Edge']], [
|
|
354
358
|
|
|
@@ -388,7 +392,7 @@
|
|
|
388
392
|
], [VERSION, [NAME, 'Quark']], [
|
|
389
393
|
/\bddg\/([\w\.]+)/i // DuckDuckGo
|
|
390
394
|
], [VERSION, [NAME, 'DuckDuckGo']], [
|
|
391
|
-
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i
|
|
395
|
+
/(?:\buc? ?browser|(?:juc.+)ucweb| ucpc)[\/ ]?([\w\.]+)/i // UCBrowser
|
|
392
396
|
], [VERSION, [NAME, 'UCBrowser']], [
|
|
393
397
|
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
|
394
398
|
/\bqbcore\/([\w\.]+).+microm/i,
|
|
@@ -427,7 +431,9 @@
|
|
|
427
431
|
/\b(qq)\/([\w\.]+)/i // QQ
|
|
428
432
|
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
|
|
429
433
|
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
|
|
430
|
-
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/
|
|
434
|
+
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/VivoBrowser/PicoBrowser
|
|
435
|
+
/ HBPC\/([\w\.]+)/ // Huawei Browser
|
|
436
|
+
], [VERSION, [NAME, HUAWEI + SUFFIX_BROWSER]], [
|
|
431
437
|
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
|
|
432
438
|
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
|
|
433
439
|
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
|
|
@@ -475,10 +481,10 @@
|
|
|
475
481
|
], [VERSION, [NAME, CHROME+' Headless']], [
|
|
476
482
|
|
|
477
483
|
/wv\).+chrome\/([\w\.]+).+edgw\//i // Edge WebView2
|
|
478
|
-
], [VERSION, [NAME, EDGE+' WebView2']], [
|
|
484
|
+
], [VERSION, [NAME, EDGE+' WebView2'], [TYPE, INAPP]], [
|
|
479
485
|
|
|
480
|
-
|
|
481
|
-
], [[NAME, CHROME+' WebView'], VERSION], [
|
|
486
|
+
/; wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
|
|
487
|
+
], [[NAME, CHROME+' WebView'], VERSION, [TYPE, INAPP]], [
|
|
482
488
|
|
|
483
489
|
/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
|
|
484
490
|
], [VERSION, [NAME, 'Android' + SUFFIX_BROWSER]], [
|
|
@@ -612,7 +618,7 @@
|
|
|
612
618
|
/oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,
|
|
613
619
|
// Xiaomi Mi
|
|
614
620
|
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,
|
|
615
|
-
|
|
621
|
+
/; ([\w ]+) miui\/v?\d/i
|
|
616
622
|
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
|
617
623
|
|
|
618
624
|
// OnePlus
|
|
@@ -767,10 +773,19 @@
|
|
|
767
773
|
/; (ac[3-6]\d\w{2,8})( b|\))/i
|
|
768
774
|
], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [
|
|
769
775
|
|
|
776
|
+
// Blackview
|
|
777
|
+
/blackview ([-\w ]+)( b|\))/i,
|
|
778
|
+
/; (bv\d{4}[-\w ]*)( b|\))/i
|
|
779
|
+
], [MODEL, [VENDOR, 'Blackview'], [TYPE, MOBILE]], [
|
|
780
|
+
|
|
770
781
|
// HMD
|
|
771
782
|
/; (n159v)/i
|
|
772
783
|
], [MODEL, [VENDOR, 'HMD'], [TYPE, MOBILE]], [
|
|
773
784
|
|
|
785
|
+
// T-Mobile
|
|
786
|
+
/((revvl[ \w\+]+|tm(?:rv|af)\w*[45]g(?:tb)?))( b|\))/i
|
|
787
|
+
], [MODEL, [TYPE, strTest, { 'test': /ta?b/i, 'ifTrue': TABLET, 'ifFalse': MOBILE }], [VENDOR, 'T-Mobile']], [
|
|
788
|
+
|
|
774
789
|
// MIXED
|
|
775
790
|
/(imo) (tab \w+)/i, // IMO
|
|
776
791
|
/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i // Infinix XPad / Tecno
|
|
@@ -778,8 +793,8 @@
|
|
|
778
793
|
|
|
779
794
|
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
|
|
780
795
|
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan
|
|
781
|
-
// BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
|
|
782
|
-
/; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([
|
|
796
|
+
// BLU/Coolpad/CUBOT/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
|
|
797
|
+
/; (blu|coolpad|cubot|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([-\w\+ ]+?)(?: bui|\)|; r)/i,
|
|
783
798
|
/(hp) ([\w ]+\w)/i, // HP iPAQ
|
|
784
799
|
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
|
|
785
800
|
/(oppo) ?([\w ]+) bui/i, // OPPO
|
|
@@ -1187,12 +1202,12 @@
|
|
|
1187
1202
|
[BRANDS, itemListToArray(uach[CH])],
|
|
1188
1203
|
[FULLVERLIST, itemListToArray(uach[CH_FULL_VER_LIST])],
|
|
1189
1204
|
[MOBILE, /\?1/.test(uach[CH_MOBILE])],
|
|
1190
|
-
[MODEL,
|
|
1191
|
-
[PLATFORM,
|
|
1192
|
-
[PLATFORMVER,
|
|
1193
|
-
[ARCHITECTURE,
|
|
1205
|
+
[MODEL, normalizeHeaderValue(uach[CH_MODEL])],
|
|
1206
|
+
[PLATFORM, normalizeHeaderValue(uach[CH_PLATFORM])],
|
|
1207
|
+
[PLATFORMVER, normalizeHeaderValue(uach[CH_PLATFORM_VER])],
|
|
1208
|
+
[ARCHITECTURE, normalizeHeaderValue(uach[CH_ARCH])],
|
|
1194
1209
|
[FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])],
|
|
1195
|
-
[BITNESS,
|
|
1210
|
+
[BITNESS, normalizeHeaderValue(uach[CH_BITNESS])]
|
|
1196
1211
|
]);
|
|
1197
1212
|
} else {
|
|
1198
1213
|
for (var prop in uach) {
|
|
@@ -1280,11 +1295,17 @@
|
|
|
1280
1295
|
this.set(MAJOR, majorize(this.get(VERSION)));
|
|
1281
1296
|
break;
|
|
1282
1297
|
case OS:
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1298
|
+
// Since iOS 26, Safari's UA reports the OS version as frozen at 18:
|
|
1299
|
+
// https://webkit.org/blog/17333/webkit-features-in-safari-26-0/#update-to-ua-string
|
|
1300
|
+
if (this.get(NAME) == 'iOS' && this.get(VERSION)) {
|
|
1301
|
+
// Only perform this if iOS version is 18/19
|
|
1302
|
+
if (/^1[89][^\d]/.exec(this.get(VERSION))) {
|
|
1303
|
+
// Based on the assumption that "iOS" version is tightly coupled with "Safari" version
|
|
1304
|
+
var realVersion = /\) Version\/((\d+)[\d\.]*)/.exec(this.ua);
|
|
1305
|
+
if (realVersion && parseInt(realVersion[2], 10) >= 26) {
|
|
1306
|
+
// iOS version = Safari version
|
|
1307
|
+
this.set(VERSION, realVersion[1]);
|
|
1308
|
+
}
|
|
1288
1309
|
}
|
|
1289
1310
|
}
|
|
1290
1311
|
break;
|
|
@@ -1440,9 +1461,7 @@
|
|
|
1440
1461
|
EMPTY)), // empty string
|
|
1441
1462
|
|
|
1442
1463
|
httpUACH = new UACHData(headers, true),
|
|
1443
|
-
regexMap =
|
|
1444
|
-
extend(defaultRegexes, extensions) :
|
|
1445
|
-
defaultRegexes,
|
|
1464
|
+
regexMap = defaultRegexes,
|
|
1446
1465
|
|
|
1447
1466
|
createItemFunc = function (itemType) {
|
|
1448
1467
|
if (itemType == RESULT) {
|
|
@@ -1477,9 +1496,14 @@
|
|
|
1477
1496
|
['setUA', function (ua) {
|
|
1478
1497
|
if (isString(ua)) userAgent = trim(ua, UA_MAX_LENGTH);
|
|
1479
1498
|
return this;
|
|
1499
|
+
}],
|
|
1500
|
+
['useExtension', function (exts) {
|
|
1501
|
+
if (exts) regexMap = extend(regexMap, exts);
|
|
1502
|
+
return this;
|
|
1480
1503
|
}]
|
|
1481
1504
|
])
|
|
1482
|
-
.setUA(userAgent)
|
|
1505
|
+
.setUA(userAgent)
|
|
1506
|
+
.useExtension(extensions);
|
|
1483
1507
|
|
|
1484
1508
|
return this;
|
|
1485
1509
|
}
|
package/src/main/ua-parser.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Source: /src/main/ua-parser.js
|
|
4
4
|
|
|
5
5
|
/////////////////////////////////////////////////////////////////////////////////
|
|
6
|
-
/* UAParser.js v2.0.
|
|
6
|
+
/* UAParser.js v2.0.10
|
|
7
7
|
Copyright © 2012-2026 Faisal Salman <f@faisalman.com>
|
|
8
8
|
AGPLv3 License *//*
|
|
9
9
|
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// Constants
|
|
22
22
|
/////////////
|
|
23
23
|
|
|
24
|
-
var LIBVERSION = '2.0.
|
|
24
|
+
var LIBVERSION = '2.0.10',
|
|
25
25
|
UA_MAX_LENGTH = 500,
|
|
26
26
|
USER_AGENT = 'user-agent',
|
|
27
27
|
EMPTY = '',
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
itemListToArray = function (header) {
|
|
173
173
|
if (!header) return undefined;
|
|
174
174
|
var arr = [];
|
|
175
|
-
var tokens =
|
|
175
|
+
var tokens = normalizeHeaderValue(header).split(',');
|
|
176
176
|
for (var i = 0; i < tokens.length; i++) {
|
|
177
177
|
if (tokens[i].indexOf(';') > -1) {
|
|
178
178
|
var token = trim(tokens[i]).split(';v=');
|
|
@@ -189,6 +189,9 @@
|
|
|
189
189
|
majorize = function (version) {
|
|
190
190
|
return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
|
|
191
191
|
},
|
|
192
|
+
normalizeHeaderValue = function (str) {
|
|
193
|
+
return isString(str) ? trim(strip(/\\?\"/g, str), UA_MAX_LENGTH) : undefined;
|
|
194
|
+
},
|
|
192
195
|
setProps = function (arr) {
|
|
193
196
|
for (var i in arr) {
|
|
194
197
|
if (!arr.hasOwnProperty(i)) continue;
|
|
@@ -205,9 +208,6 @@
|
|
|
205
208
|
strip = function (pattern, str) {
|
|
206
209
|
return isString(str) ? str.replace(pattern, EMPTY) : str;
|
|
207
210
|
},
|
|
208
|
-
stripQuotes = function (str) {
|
|
209
|
-
return strip(/\\?\"/g, str);
|
|
210
|
-
},
|
|
211
211
|
trim = function (str, len) {
|
|
212
212
|
str = strip(/^\s\s*/, String(str));
|
|
213
213
|
return typeof len === TYPEOF.UNDEFINED ? str : str.substring(0, len);
|
|
@@ -280,6 +280,10 @@
|
|
|
280
280
|
}
|
|
281
281
|
},
|
|
282
282
|
|
|
283
|
+
strTest = function (str, map) {
|
|
284
|
+
return map.test.test(str) ? map.ifTrue : map.ifFalse;
|
|
285
|
+
},
|
|
286
|
+
|
|
283
287
|
strMapper = function (str, map) {
|
|
284
288
|
|
|
285
289
|
for (var i in map) {
|
|
@@ -350,7 +354,7 @@
|
|
|
350
354
|
/\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
|
|
351
355
|
], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
|
|
352
356
|
/webview.+edge\/([\w\.]+)/i // Microsoft Edge
|
|
353
|
-
], [VERSION, [NAME, EDGE+' WebView']], [
|
|
357
|
+
], [VERSION, [NAME, EDGE+' WebView'], [TYPE, INAPP]], [
|
|
354
358
|
/edg(?:e|ios|a)?\/([\w\.]+)/i
|
|
355
359
|
], [VERSION, [NAME, 'Edge']], [
|
|
356
360
|
|
|
@@ -390,7 +394,7 @@
|
|
|
390
394
|
], [VERSION, [NAME, 'Quark']], [
|
|
391
395
|
/\bddg\/([\w\.]+)/i // DuckDuckGo
|
|
392
396
|
], [VERSION, [NAME, 'DuckDuckGo']], [
|
|
393
|
-
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i
|
|
397
|
+
/(?:\buc? ?browser|(?:juc.+)ucweb| ucpc)[\/ ]?([\w\.]+)/i // UCBrowser
|
|
394
398
|
], [VERSION, [NAME, 'UCBrowser']], [
|
|
395
399
|
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
|
396
400
|
/\bqbcore\/([\w\.]+).+microm/i,
|
|
@@ -429,7 +433,9 @@
|
|
|
429
433
|
/\b(qq)\/([\w\.]+)/i // QQ
|
|
430
434
|
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
|
|
431
435
|
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
|
|
432
|
-
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/
|
|
436
|
+
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/VivoBrowser/PicoBrowser
|
|
437
|
+
/ HBPC\/([\w\.]+)/ // Huawei Browser
|
|
438
|
+
], [VERSION, [NAME, HUAWEI + SUFFIX_BROWSER]], [
|
|
433
439
|
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
|
|
434
440
|
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
|
|
435
441
|
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
|
|
@@ -477,10 +483,10 @@
|
|
|
477
483
|
], [VERSION, [NAME, CHROME+' Headless']], [
|
|
478
484
|
|
|
479
485
|
/wv\).+chrome\/([\w\.]+).+edgw\//i // Edge WebView2
|
|
480
|
-
], [VERSION, [NAME, EDGE+' WebView2']], [
|
|
486
|
+
], [VERSION, [NAME, EDGE+' WebView2'], [TYPE, INAPP]], [
|
|
481
487
|
|
|
482
|
-
|
|
483
|
-
], [[NAME, CHROME+' WebView'], VERSION], [
|
|
488
|
+
/; wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
|
|
489
|
+
], [[NAME, CHROME+' WebView'], VERSION, [TYPE, INAPP]], [
|
|
484
490
|
|
|
485
491
|
/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
|
|
486
492
|
], [VERSION, [NAME, 'Android' + SUFFIX_BROWSER]], [
|
|
@@ -614,7 +620,7 @@
|
|
|
614
620
|
/oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,
|
|
615
621
|
// Xiaomi Mi
|
|
616
622
|
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,
|
|
617
|
-
|
|
623
|
+
/; ([\w ]+) miui\/v?\d/i
|
|
618
624
|
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
|
619
625
|
|
|
620
626
|
// OnePlus
|
|
@@ -769,10 +775,19 @@
|
|
|
769
775
|
/; (ac[3-6]\d\w{2,8})( b|\))/i
|
|
770
776
|
], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [
|
|
771
777
|
|
|
778
|
+
// Blackview
|
|
779
|
+
/blackview ([-\w ]+)( b|\))/i,
|
|
780
|
+
/; (bv\d{4}[-\w ]*)( b|\))/i
|
|
781
|
+
], [MODEL, [VENDOR, 'Blackview'], [TYPE, MOBILE]], [
|
|
782
|
+
|
|
772
783
|
// HMD
|
|
773
784
|
/; (n159v)/i
|
|
774
785
|
], [MODEL, [VENDOR, 'HMD'], [TYPE, MOBILE]], [
|
|
775
786
|
|
|
787
|
+
// T-Mobile
|
|
788
|
+
/((revvl[ \w\+]+|tm(?:rv|af)\w*[45]g(?:tb)?))( b|\))/i
|
|
789
|
+
], [MODEL, [TYPE, strTest, { 'test': /ta?b/i, 'ifTrue': TABLET, 'ifFalse': MOBILE }], [VENDOR, 'T-Mobile']], [
|
|
790
|
+
|
|
776
791
|
// MIXED
|
|
777
792
|
/(imo) (tab \w+)/i, // IMO
|
|
778
793
|
/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i // Infinix XPad / Tecno
|
|
@@ -780,8 +795,8 @@
|
|
|
780
795
|
|
|
781
796
|
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
|
|
782
797
|
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan
|
|
783
|
-
// BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
|
|
784
|
-
/; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([
|
|
798
|
+
// BLU/Coolpad/CUBOT/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
|
|
799
|
+
/; (blu|coolpad|cubot|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([-\w\+ ]+?)(?: bui|\)|; r)/i,
|
|
785
800
|
/(hp) ([\w ]+\w)/i, // HP iPAQ
|
|
786
801
|
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
|
|
787
802
|
/(oppo) ?([\w ]+) bui/i, // OPPO
|
|
@@ -1189,12 +1204,12 @@
|
|
|
1189
1204
|
[BRANDS, itemListToArray(uach[CH])],
|
|
1190
1205
|
[FULLVERLIST, itemListToArray(uach[CH_FULL_VER_LIST])],
|
|
1191
1206
|
[MOBILE, /\?1/.test(uach[CH_MOBILE])],
|
|
1192
|
-
[MODEL,
|
|
1193
|
-
[PLATFORM,
|
|
1194
|
-
[PLATFORMVER,
|
|
1195
|
-
[ARCHITECTURE,
|
|
1207
|
+
[MODEL, normalizeHeaderValue(uach[CH_MODEL])],
|
|
1208
|
+
[PLATFORM, normalizeHeaderValue(uach[CH_PLATFORM])],
|
|
1209
|
+
[PLATFORMVER, normalizeHeaderValue(uach[CH_PLATFORM_VER])],
|
|
1210
|
+
[ARCHITECTURE, normalizeHeaderValue(uach[CH_ARCH])],
|
|
1196
1211
|
[FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])],
|
|
1197
|
-
[BITNESS,
|
|
1212
|
+
[BITNESS, normalizeHeaderValue(uach[CH_BITNESS])]
|
|
1198
1213
|
]);
|
|
1199
1214
|
} else {
|
|
1200
1215
|
for (var prop in uach) {
|
|
@@ -1282,11 +1297,17 @@
|
|
|
1282
1297
|
this.set(MAJOR, majorize(this.get(VERSION)));
|
|
1283
1298
|
break;
|
|
1284
1299
|
case OS:
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1300
|
+
// Since iOS 26, Safari's UA reports the OS version as frozen at 18:
|
|
1301
|
+
// https://webkit.org/blog/17333/webkit-features-in-safari-26-0/#update-to-ua-string
|
|
1302
|
+
if (this.get(NAME) == 'iOS' && this.get(VERSION)) {
|
|
1303
|
+
// Only perform this if iOS version is 18/19
|
|
1304
|
+
if (/^1[89][^\d]/.exec(this.get(VERSION))) {
|
|
1305
|
+
// Based on the assumption that "iOS" version is tightly coupled with "Safari" version
|
|
1306
|
+
var realVersion = /\) Version\/((\d+)[\d\.]*)/.exec(this.ua);
|
|
1307
|
+
if (realVersion && parseInt(realVersion[2], 10) >= 26) {
|
|
1308
|
+
// iOS version = Safari version
|
|
1309
|
+
this.set(VERSION, realVersion[1]);
|
|
1310
|
+
}
|
|
1290
1311
|
}
|
|
1291
1312
|
}
|
|
1292
1313
|
break;
|
|
@@ -1442,9 +1463,7 @@
|
|
|
1442
1463
|
EMPTY)), // empty string
|
|
1443
1464
|
|
|
1444
1465
|
httpUACH = new UACHData(headers, true),
|
|
1445
|
-
regexMap =
|
|
1446
|
-
extend(defaultRegexes, extensions) :
|
|
1447
|
-
defaultRegexes,
|
|
1466
|
+
regexMap = defaultRegexes,
|
|
1448
1467
|
|
|
1449
1468
|
createItemFunc = function (itemType) {
|
|
1450
1469
|
if (itemType == RESULT) {
|
|
@@ -1479,9 +1498,14 @@
|
|
|
1479
1498
|
['setUA', function (ua) {
|
|
1480
1499
|
if (isString(ua)) userAgent = trim(ua, UA_MAX_LENGTH);
|
|
1481
1500
|
return this;
|
|
1501
|
+
}],
|
|
1502
|
+
['useExtension', function (exts) {
|
|
1503
|
+
if (exts) regexMap = extend(regexMap, exts);
|
|
1504
|
+
return this;
|
|
1482
1505
|
}]
|
|
1483
1506
|
])
|
|
1484
|
-
.setUA(userAgent)
|
|
1507
|
+
.setUA(userAgent)
|
|
1508
|
+
.useExtension(extensions);
|
|
1485
1509
|
|
|
1486
1510
|
return this;
|
|
1487
1511
|
}
|