From d1f691fbc775d4ee179788c674280e0286deea72 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 18 Nov 2024 16:06:23 +0700 Subject: [PATCH 01/73] Update README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index aa7e1c0..41f504f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,11 @@

- + + +

+[![https://uaparser.dev](https://github.com/user-attachments/assets/9f30f3d4-5cfe-441c-8f86-ead7c955f940)](https://uaparser.dev) +

@@ -23,6 +27,7 @@ user's Browser, Engine, OS, CPU, and Device type/model. Runs either in browser * Live demo: https://uaparser.dev + # Documentation * `version 1.x` : https://github.com/faisalman/ua-parser-js/tree/1.0.x#documentation From 8174330d27eeb84086e9d42e067ba98baad91fd0 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 18 Nov 2024 23:38:41 +0700 Subject: [PATCH 02/73] Update README.md (2) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 41f504f..f1f9b15 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@

[![https://uaparser.dev](https://github.com/user-attachments/assets/9f30f3d4-5cfe-441c-8f86-ead7c955f940)](https://uaparser.dev) + +[![https://uaparser.dev](https://github.com/user-attachments/assets/50da50fc-7c8a-46e3-a2bc-6a8249914372)](https://uaparser.dev)

From 5742ba68aea239413d78f60bc4328b1255b23e7e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 19 Nov 2024 10:18:08 +0700 Subject: [PATCH 03/73] Update README.md (3) --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f1f9b15..cd77728 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,7 @@ -

- - - -

- +[![https://uaparser.dev](https://raw.githubusercontent.com/faisalman/ua-parser-js/gh-pages/images/uap-header.png)](https://uaparser.dev) [![https://uaparser.dev](https://github.com/user-attachments/assets/9f30f3d4-5cfe-441c-8f86-ead7c955f940)](https://uaparser.dev) - [![https://uaparser.dev](https://github.com/user-attachments/assets/50da50fc-7c8a-46e3-a2bc-6a8249914372)](https://uaparser.dev) +[![https://uaparser.dev](https://github.com/user-attachments/assets/9f2aaff0-a9b4-4ac9-bdf3-eea8081a2582)](https://uaparser.dev)

From 41de949809b941fd35272f280541e8c04981fe3f Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 19 Nov 2024 23:41:43 +0700 Subject: [PATCH 04/73] Improve device detection for tablets: Honor, Huawei, Infinix --- src/main/ua-parser.js | 13 +- test/specs/device-all.json | 621 +++++++++++++++++++++++++++++++++++++ 2 files changed, 630 insertions(+), 4 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index b6feb1a..21021a5 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -529,11 +529,13 @@ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ // Honor - /(?:honor)([-\w ]+)[;\)]/i + /\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i + ], [MODEL, [VENDOR, HONOR], [TYPE, TABLET]], [ + /honor([-\w ]+)[;\)]/i ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [ // Huawei - /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i + /\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei)([-\w ]+)[;\)]/i, /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i @@ -685,9 +687,13 @@ ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [ // MIXED + /(imo) (tab \w+)/i, // IMO + /(infinix) (x1101b?)/i // Infinix XPad + ], [VENDOR, MODEL, [TYPE, TABLET]], [ + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan - /; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO + /; (imo) ([\w ]+?)(?: bui|\))/i, // IMO /(hp) ([\w ]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia @@ -696,7 +702,6 @@ /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(imo) (tab \w+)/i, // IMO /(kobo)\s(ereader|touch)/i, // Kobo /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad diff --git a/test/specs/device-all.json b/test/specs/device-all.json index f0898b9..ce131ef 100644 --- a/test/specs/device-all.json +++ b/test/specs/device-all.json @@ -350,6 +350,141 @@ "type": "mobile" } }, + { + "desc": "Honor MagicPad 13 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; GDI-W09 Build/HONORGDI-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "GDI-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 2", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; en-nz; JDN-W09 Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/6.0 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "JDN-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 2", + "ua": "Mozilla/5.0 (Linux; U; Android 9; zh-Hans-CN; JDN2-W09HN Build/HUAWEIJDN2-W09HN) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.6.6.164 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "JDN2-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 7 10.1", + "ua": "Mozilla/5.0 (Linux; Android 12; AGM3-AL09HN Build/HONORAGM3-AL09HN; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.46 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/490.0.0.63.82;IABMV/1;]", + "expect": { + "vendor": "Honor", + "model": "AGM3-AL09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 8 12.0", + "ua": "Mozilla/5.0 (Linux; Android 12; HEY-W09 Build/HONORHEY-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "HEY-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 9 12.1", + "ua": "Mozilla/5.0 (Linux; Android 13; HEY2-N09 Build/HONORHEY2-N09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 [FB_IAB/FB4A;FBAV/465.0.0.63.83;]", + "expect": { + "vendor": "Honor", + "model": "HEY2-N09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 9 12.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; HEY2-W09 Build/HONORHEY2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/129.0.6668.102 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", + "expect": { + "vendor": "Honor", + "model": "HEY2-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad V7 Pro 11", + "ua": "Mozilla/5.0 (Linux; Android 12; BRT-AN09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 EdgA/109.0.1518.53", + "expect": { + "vendor": "Honor", + "model": "BRT-AN09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad V7 Pro 11 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; BRT-W09 Build/HONORBRT-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.5.0.336 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "BRT-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X6", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09HN Build/HUAWEIAGR-W09HN; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.9 SP-engine/2.28.0 baiduboxapp/12.9.0.11 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Honor", + "model": "AGR-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X7 8 LTE", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-AL00HN; HMSCore 6.0.0.306) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.3.300 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "KOB2-AL00HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X7 8 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-W09HN; HMSCore 6.1.0.314) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 HuaweiBrowser/12.0.0.301 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "KOB2-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X8 Lite", + "ua": "Mozilla/5.0 (Linux; Android 12; AGM-W09HN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "AGM-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X9 11.5 LTE", + "ua": "Mozilla/5.0 (Linux; Android 13; ELN-L09 Build/HONORELN-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Mobile Safari/537.36[FBAN/EMA;FBLC/zh_CN;FBAV/432.0.0.9.110;FBCX/modulariab;]", + "expect": { + "vendor": "Honor", + "model": "ELN-L09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X9 11.5 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 13; ELN-W09 Build/HONORELN-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "ELN-W09", + "type": "tablet" + } + }, { "desc": "HTC Desire 820", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; HTC Desire 820 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", @@ -431,6 +566,60 @@ "type": "mobile" } }, + { + "desc": "HUAWEI MediaPad C5 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; MON-AL19B Build/HUAWEIMON-AL19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.83 Mobile Safari/537.36 T7/11.7 baiduboxapp/11.7.0.10 (Baidu; P1 7.0)", + "expect": { + "vendor": "Huawei", + "model": "MON-AL19B", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M2 10.1", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; HUAWEI M2-A01L Build/HUAWEIM2-A01L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/95.0.4638.74 Safari/537.36[FBAN/EMA;FBLC/fr_FR;FBAV/421.0.0.14.100;]", + "expect": { + "vendor": "Huawei", + "model": "M2-A01L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; en-US; BTV-DL09 Build/HUAWEIBEETHOVEN-DL09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11.5.0.1015 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTV-DL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; HUAWEI BTV-W09 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.96 Mobile Safari/537.36 AlohaBrowser/3.1.1", + "expect": { + "vendor": "Huawei", + "model": "BTV-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 Lite", + "ua": "Mozilla/5.0 (Linux; Android 7.0; CPN-L09 Build/HUAWEICPN-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36[FBAN/EMA;FBLC/ru_RU;FBAV/233.0.0.12.118;]", + "expect": { + "vendor": "Huawei", + "model": "CPN-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 Lite", + "ua": "Mozilla/5.0 (Linux; Android 7.0; CPN-W09 Build/HUAWEICPN-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.71 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/374.0.0.20.109;]", + "expect": { + "vendor": "Huawei", + "model": "CPN-W09", + "type": "tablet" + } + }, { "desc": "HUAWEI MediaPad M3 Lite 10", "ua": "Mozilla/5.0 (Linux; Android 7.0; BAH-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36", @@ -440,6 +629,15 @@ "type": "tablet" } }, + { + "desc": "HUAWEI MediaPad M5 10.8", + "ua": "Mozilla/5.0 (Linux; Android 9; CMR-W09 Build/HUAWEICMR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.102 Safari/537.36 Line/14.18.1/IAB", + "expect": { + "vendor": "Huawei", + "model": "CMR-W09", + "type": "tablet" + } + }, { "desc": "HUAWEI MediaPad M5 Lite", "ua": "Mozilla/5.0 (Linux; Android 8.0.0; BAH2-W19 Build/HUAWEIBAH2-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Safari/537.36", @@ -449,6 +647,33 @@ "type": "tablet" } }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; JDN2-W09 Build/HUAWEIJDN2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/90.0.4430.210 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/318.0.0.39.154;]", + "expect": { + "vendor": "Huawei", + "model": "JDN2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; JDN2-AL50 Build/HUAWEIJDN2-AL50; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.13.0 SP-engine/2.29.0 matrixstyle/0 lite baiduboxapp/5.8.0.10 (Baidu; P1 9) NABar/1.", + "expect": { + "vendor": "Huawei", + "model": "JDN2-AL50", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 8.4", + "ua": "Mozilla/5.0 (Linux; Android 9; SHT-W09 Build/HUAWEISHT-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.87 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SHT-W09", + "type": "tablet" + } + }, { "desc": "HUAWEI MediaPad M5", "ua": "Mozilla/5.0 (Linux; Android 9; SHT-AL09 Build/HUAWEISHT-AL09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Mobile Safari/537.36", @@ -458,6 +683,24 @@ "type": "tablet" } }, + { + "desc": "HUAWEI MediaPad M6 10.8", + "ua": "Mozilla/5.0 (Linux; Android 14; SCM-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6612.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SCM-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M6 8.4", + "ua": "Mozilla/5.0 (Linux; Android 9; VRD-W09; HMSCore 6.14.0.321; GMSCore 22.26.15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VRD-W09", + "type": "tablet" + } + }, { "desc": "HUAWEI MediaPad T5", "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-L09 Build/HUAWEIAGS2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.125 Safari/537.36", @@ -467,6 +710,15 @@ "type": "tablet" } }, + { + "desc": "HUAWEI MediaPad T10", + "ua": "Mozilla/5.0 (Linux; U; Android 10; en-US; AGR-L09 Build/HUAWEIAGR-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.3.8.1305 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-L09", + "type": "tablet" + } + }, { "desc": "HUAWEI MediaPad T10", "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09 Build/HUAWEIAGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", @@ -485,6 +737,339 @@ "type": "tablet" } }, + { + "desc": "HUAWEI MediaPad T 8.0", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-L09 Build/HUAWEIKOB2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/396.0.0.21.104;]", + "expect": { + "vendor": "Huawei", + "model": "KOB2-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T 8.0", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-W09 Build/HUAWEIKOB2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 Mobile Safari/537.36 HuaweiBrowser/15.0.4.312 HMSCore/6.14.0.301", + "expect": { + "vendor": "Huawei", + "model": "KOB2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; T1-A21w Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Safari/537.36 SputnikBrowser/1.2.8.161", + "expect": { + "vendor": "Huawei", + "model": "T1-A21w", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; T1-A23L Build/HuaweiMediaPad; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 BingWeb/6.9.10", + "expect": { + "vendor": "Huawei", + "model": "T1-A23L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; T1-A21L Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.93 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "T1-A21L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 7", + "ua": "Mozilla/5.0 (Linux; 4.4.2; T1-701u) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "T1-701u", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 8", + "ua": "Mozilla/5.0 (Linux; U; Android 9.0; MediaPad T1 8.0 Build/HuaweiMediaPad) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30 OPR/28.0.2254.119224", + "expect": { + "vendor": "Huawei", + "model": "MediaPad T1 8.0", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10 9.7", + "ua": "Mozilla/5.0 (Linux; U; Android 10; en-US; AGRK-L09 Build/HUAWEIAGRK-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.6.0.1315 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGRK-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10 9.7 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; AGRK-W09; HMSCore 6.14.0.321) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGRK-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s 10.1 LTE", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3K-L09 Build/HUAWEIAGS3K-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36 [FB_IAB/FB4A;FBAV/362.0.0.27.109;]", + "expect": { + "vendor": "Huawei", + "model": "AGS3K-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s 10.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3K-W09; HMSCore 6.14.0.321) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS3K-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T2 10.0 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; 605HW Build/HuaweiMediaPad; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.78 Safari/537.36 [FB_IAB/FB4A;FBAV/436.0.0.35.101;]", + "expect": { + "vendor": "Huawei", + "model": "605HW", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T2 7.0 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0; BGO-DL09 Build/HuaweiBAGGIO; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/407.0.0.30.97;]", + "expect": { + "vendor": "Huawei", + "model": "BGO-DL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; AGS-W09 Build/HUAWEIAGS-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.90 Safari/537.36 GSA/10.83.10.21.arm64", + "expect": { + "vendor": "Huawei", + "model": "AGS-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 7", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BG2-U03 Build/HUAWEIBG2-U03; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.111 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BG2-U03", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; KOB-W09 Build/HUAWEIKOB-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 Safari/537.36 [FB_IAB/Orca-Android;FBAV/354.0.0.10.113;]", + "expect": { + "vendor": "Huawei", + "model": "KOB-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T5 10", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-W09 Build/HUAWEIAGS2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Huawei", + "model": "AGS2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad X2", + "ua": "Mozilla/5.0 (Linux; Android 8.0; GEM-703L Build/HUAWEIGEM-703L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/043906 Mobile Safari/537.36 MicroMessenger/6.6.3.1260(0x26060339) NetType/WIFI Language/zh_", + "expect": { + "vendor": "Huawei", + "model": "GEM-703L", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH3-W09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH3-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH3-L09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH3-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; BAH3-W59 Build/HUAWEIBAH3-W59; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36HiSearch/22.0.6.315", + "expect": { + "vendor": "Huawei", + "model": "BAH3-W59", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 (2022)", + "ua": "Mozilla/5.0 (Linux; Android 10; BAH4-L09 Build/HUAWEIBAH4-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH4-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 (2022) WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH4-W09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH4-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 SE", + "ua": "Mozilla/5.0 (Linux; Android 12; AGS5-L09 Build/HUAWEIAGS5-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS5-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 SE WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; AGS5-W09 Build/HUAWEIAGS5-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Safari/537.36 [FB_IAB/FB4A;FBAV/480.0.0.54.88;]", + "expect": { + "vendor": "Huawei", + "model": "AGS5-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11 (2023) WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; DBR-W10 Build/HUAWEIDBR-W10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.9.6.501 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DBR-W10", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-cn; DBY-W09 Build/HUAWEIDBY-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.86 MQQBrowser/14.6 Mobile Safari/537.36 COVC/046801", + "expect": { + "vendor": "Huawei", + "model": "DBY-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 Air WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; DBY2-W00 Build/HUAWEIDBY2-W00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/7.3.8.663 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DBY2-W00", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 LTE", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; BTK-AL09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTK-AL09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 S WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; TGR-W09; HMSCore 6.14.0.322; GMSCore 0.3.3.1.240913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 HuaweiBrowser/14.0.2.317 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TGR-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; BTK-W09; HMSCore 6.14.0.322; GMSCore 214816056) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTK-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad C5 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; MON-W19 Build/HUAWEIMON-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Mobile Safari/537.36 [Pinterest/Android]", + "expect": { + "vendor": "Huawei", + "model": "MON-W19", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 12; GOT-AL09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 YaBrowser/23.5.5.60.01 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "GOT-AL09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 11 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; GOT-W09 Build/HUAWEIGOT-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/97.0.4692.98 Safari/537.36 T7/13.19 BDOS/1.0 (HarmonyOS 3.0.0) SP-engine/2.57.0 baiduboxapp/13.19.0.12 (Baidu; P1 12) NABar/1.0", + "expect": { + "vendor": "Huawei", + "model": "GOT-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 12.6 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; WGR-W09 Build/HUAWEIWGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/412.0.0.8.106;]", + "expect": { + "vendor": "Huawei", + "model": "WGR-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad SE 11 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; AGS6-W09; HMSCore 6.12.2.309) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.5.315 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS6-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 13.2", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; PCE-W29; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "PCE-W29", + "type": "tablet" + } + }, { "desc": "Huawei MatePad T 10", "ua": "Mozilla/5.0 (Linux; Android 10; AGR-L09; HMSCore 5.0.4.301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.3.304 Safari/537.36", @@ -494,6 +1079,33 @@ "type": "tablet" } }, + { + "desc": "Huawei MatePad T10s", + "ua": "Mozilla/5.0 (Linux; U; Android 10; zh-cn; AGS3-AL00 Build/HUAWEIAGS3-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/11.4 Mobile Safari/537.36 COVC/045530", + "expect": { + "vendor": "Huawei", + "model": "AGS3-AL00", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T10s WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/88.0.4324.93 Safari/537.36 OPR/60.0.2254.59405", + "expect": { + "vendor": "Huawei", + "model": "AGS3-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T8 8 LTE", + "ua": "Mozilla/5.0 (Linux; U; Android 10; KOB2K-L09 Build/HUAWEIKOB2K-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36 OPR/83.0.2254.73002", + "expect": { + "vendor": "Huawei", + "model": "KOB2K-L09", + "type": "tablet" + } + }, { "desc": "Huawei M3", "ua": "Mozilla/5.0 (Linux; Android 7.0; BTV-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", @@ -944,6 +1556,15 @@ "type": "mobile" } }, + { + "desc": "Infinix XPad", + "ua": "Mozilla/5.0 (Linux; Android 14; Infinix X1101B Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.99 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", + "expect": { + "vendor": "Infinix", + "model": "X1101B", + "type": "tablet" + } + }, { "desc": "Infinix Zero 5G", "ua": "Mozilla/5.0 (Linux; Android 12; Infinix X6815B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", From 29b76368fd5a28a2e703d83b3f28d919233a6800 Mon Sep 17 00:00:00 2001 From: Harald Reingruber <74898239+haraldreingruber-dedalus@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:11:31 +0100 Subject: [PATCH 05/73] Add missing 1.0.39 changes to CHANGELOG.md (#766) --- CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0be492a..5545baf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -166,6 +166,14 @@ --- +## Version 0.7.39 / 1.0.39 +- Add new feature: executable command using `npx ua-parser-js "[INSERT-UA-HERE]"` +- Add new browser: Helio, Pico Browser, Wolvic +- Add new device vendor: itel, Nothing, TCL +- Improve browser detection: ICEBrowser, Klar, QQBrowser, Quark, Rekonq, Sleipnir +- Improve device detection: Xiaomi Pro, Amazon Echo Show, Samsung Galaxy Watch +- Removed from browser: Viera + ## Version 0.7.38 / 1.0.38 - Fix error on getOS() when userAgentData.platform is undefined - Add new browser: Opera GX, Twitter @@ -251,4 +259,4 @@ Version 1.0.x is basically the equivalent of version 0.7.x (mirror/duplicate). S ## Version 0.8 -Version 0.8 was created by accident. This version is now deprecated and no longer maintained, please update to version 0.7 / 1.0. \ No newline at end of file +Version 0.8 was created by accident. This version is now deprecated and no longer maintained, please update to version 0.7 / 1.0. From 4c57a5a5672c98faf8fc8efbc81de6753ce7f1dd Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 20 Nov 2024 16:44:41 +0700 Subject: [PATCH 06/73] Improve device detection for tablets: OnePlus, Xiaomi --- src/main/ua-parser.js | 14 +-- test/specs/device-all.json | 171 +++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 6 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 21021a5..e915b24 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -76,6 +76,7 @@ LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', + OPPO = 'OPPO', SAMSUNG = 'Samsung', SHARP = 'Sharp', SONY = 'Sony', @@ -542,6 +543,10 @@ ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi + /oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i, + /\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i // Mi Pad tablets + ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ + /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi @@ -549,16 +554,13 @@ /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ - /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad - /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets - ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO /; (\w+) bui.+ oppo/i, /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i - ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ - /\b(opd2\d{3}a?) bui/i - ], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [ + ], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [ + /\b(opd2(\d{3}a?))(?: bui|\))/i + ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '203'], '*' : OPPO }], [TYPE, TABLET]], [ // Vivo /vivo (\w+)(?: bui|\))/i, diff --git a/test/specs/device-all.json b/test/specs/device-all.json index ce131ef..e0f2aee 100644 --- a/test/specs/device-all.json +++ b/test/specs/device-all.json @@ -2375,6 +2375,33 @@ "type": "mobile" } }, + { + "desc": "OnePlus Pad Go 11.35", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 14; OPD2304) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.629 YaApp_Android/24.101/apad YaSearchBrowser/24.101/apad BroPP/1.0 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2304", + "type": "tablet" + } + }, + { + "desc": "OnePlus Pad 2 12.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; OPD2403 Build/UKQ1.231108.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2403", + "type": "tablet" + } + }, + { + "desc": "OnePlus Pad 11.61 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; OPD2203 Build/UKQ1.230924.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2203", + "type": "tablet" + } + }, { "desc": "OPPO Pad", "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; OPD2101 Build/TP1A.220905.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", @@ -4175,6 +4202,15 @@ "type": "mobile" } }, + { + "desc": "Xiaomi MI PAD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; en-us; MI PAD Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.3.2", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD", + "type": "tablet" + } + }, { "desc": "Xiaomi MI PAD 2", "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", @@ -4184,6 +4220,33 @@ "type": "tablet" } }, + { + "desc": "Xiaomi MI PAD 2", + "ua": "Mozilla/5.0 (Linux; x86_64; Android 5.1; MI PAD 2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 YaBrowser/20.11.2.69.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 2", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 3", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.0; MI PAD 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.216 YaBrowser/21.5.6.56.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 3", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 4", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 8.1.0; MI PAD 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 YaBrowser/19.9.1.126.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 4", + "type": "tablet" + } + }, { "desc": "Xiaomi MI PAD 4 PLUS", "ua": "Mozilla/5.0 (Linux; Android 8.1; MI PAD 4 PLUS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", @@ -4193,6 +4256,69 @@ "type": "tablet" } }, + { + "desc": "Xiaomi MI PAD 4 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 8.1; Mi Pad4 Wi-Fi) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Mobile Safari/537.36 EdgA/86.0.622.61", + "expect": { + "vendor": "Xiaomi", + "model": "Mi Pad4 Wi-Fi", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5", + "ua": "Mozilla/5.0 (Linux; Android 13; 21051182G Build/TKQ1.221013.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Xiaomi", + "model": "21051182G", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; M2105K81AC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Safari/537.36 Line/13.15.1/IAB", + "expect": { + "vendor": "Xiaomi", + "model": "M2105K81AC", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; M2105K81C) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2105K81C", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 6 Max 14", + "ua": "Mozilla/5.0 (Linux; U; Android 14; zh-tw; 2307BRPDCC Build/UKQ1.230804.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.118 Mobile Safari/537.36 Device/yudi Model/2307BRPDCC XiaoMi/MiuiBrowser/14.10.6", + "expect": { + "vendor": "Xiaomi", + "model": "2307BRPDCC", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 6 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 13; en-US; 23046RP50C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.6.2.1316 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "23046RP50C", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Pad 6S Pro 12.4", + "ua": "Mozilla/5.0 (Linux; Android 14; 24018RPACC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "24018RPACC", + "type": "tablet" + } + }, { "desc": "Xiaomi POCO X2", "ua": "Mozilla/5.0 (Linux; Android 10; POCO X2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", @@ -4364,6 +4490,51 @@ "type": "mobile" } }, + { + "desc": "XiaoMi Redmi Pad", + "ua": "Mozilla/5.0 (Linux; U; Android 12; id-id; Redmi Pad Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36 XiaoMi/MiuiBrowser/14.1.1-gn", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Pad", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad", + "ua": "Mozilla/5.0 (Linux; Android 14; 22081283G Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Xiaomi", + "model": "22081283G", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad Pro", + "ua": "Mozilla/5.0 (Linux; Android 14; 2405CRPFDG Build/UKQ1.240116.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.97 Safari/537.36 [FB_IAB/FB4A;FBAV/476.0.0.49.74;] FBNV/1", + "expect": { + "vendor": "Xiaomi", + "model": "2405CRPFDG", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad SE", + "ua": "Dalvik/2.1.0 (Linux; U; Android 14; 23073RPBFG Build/UKQ1.231003.002)", + "expect": { + "vendor": "Xiaomi", + "model": "23073RPBFG", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad SE 8.7", + "ua": "Mozilla/5.0 (Linux; Android 14; 24076RP19G Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Mobile Safari/537.36 Line/14.18.1/IAB", + "expect": { + "vendor": "Xiaomi", + "model": "24076RP19G", + "type": "tablet" + } + }, { "desc": "ZTE Blade A6", "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE BLADE A0620 Build/NMF26F; ru-ru) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.2.0.50586AP", From 536031d78977a7af78996f82cf5be75a049650c3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 20 Nov 2024 16:59:37 +0700 Subject: [PATCH 07/73] Improve device detection: Google Pixel Tablet --- src/main/ua-parser.js | 2 +- test/specs/device-all.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index e915b24..b0bf179 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -598,7 +598,7 @@ ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ // Google - /(pixel c)\b/i // Google Pixel C + /(pixel (c|tablet))\b/i // Google Pixel C/Tablet ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ diff --git a/test/specs/device-all.json b/test/specs/device-all.json index e0f2aee..b45d4ac 100644 --- a/test/specs/device-all.json +++ b/test/specs/device-all.json @@ -4760,6 +4760,15 @@ "type": "mobile" } }, + { + "desc": "Google Pixel Tablet", + "ua": "Mozilla/5.0 (Linux; Android 14; Pixel Tablet Build/AP2A.240905.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel Tablet", + "type": "tablet" + } + }, { "desc": "Google Pixel XL", "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel XL Build/NDE63X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", From 4ddbeeaa069dd6b0dee81e542c0c0ce1e6dd1fe1 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 20 Nov 2024 17:01:04 +0700 Subject: [PATCH 08/73] Insert a link to contributing guidelines in PR template --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f1a3b8d..c658b18 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ # Prerequisites -- [ ] I have read and follow the contributing guidelines +- [ ] I have read and follow the [contributing](https://github.com/faisalman/ua-parser-js/blob/master/CONTRIBUTING.md) guidelines - [ ] I have read and accept the [Contributor License Agreement (CLA)](https://gist.github.com/faisalman/2ed16621ebb544157eba85a7f7381417) Document and I hereby sign the CLA # Type of Change diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7ac0d6..0bb377b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,4 +4,4 @@ * Make some changes as required * Write unit test to showcase its functionality under `/test` * Run the test suites to make sure it's not breaking anything `$ npm run build+test` -* Submit a pull request under `develop` branch & check the CLA in the submission form \ No newline at end of file +* Submit a pull request & check the CLA in the submission form \ No newline at end of file From c8ece08b1b90131746db6b02aba114aa2bf2c5f7 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 20 Nov 2024 17:19:46 +0700 Subject: [PATCH 09/73] Improve device detection: Google Pixel Watch --- src/main/ua-parser.js | 3 ++- test/specs/device-all.json | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index b0bf179..2fb34d3 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -782,7 +782,8 @@ /\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [ - /((pebble))app/i // Pebble + /((pebble))app/i, // Pebble + /(google) (pixel watch[\w ]*)( bui|\))/i // Pixel Watch ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [ diff --git a/test/specs/device-all.json b/test/specs/device-all.json index b45d4ac..9adbd09 100644 --- a/test/specs/device-all.json +++ b/test/specs/device-all.json @@ -4769,6 +4769,24 @@ "type": "tablet" } }, + { + "desc": "Google Pixel Watch", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Google Pixel Watch Build/TWD4.231005.002)", + "expect": { + "vendor": "Google", + "model": "Pixel Watch", + "type": "wearable" + } + }, + { + "desc": "Google Pixel Watch 2", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Google Pixel Watch 2 Build/TWD9.240605.001.A1)", + "expect": { + "vendor": "Google", + "model": "Pixel Watch 2", + "type": "wearable" + } + }, { "desc": "Google Pixel XL", "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel XL Build/NDE63X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", From c72198d47032d4535f01a1d98fd8858f9cc9bd4c Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 20 Nov 2024 17:54:41 +0700 Subject: [PATCH 10/73] Improve device detection: Nokia tablets --- src/main/ua-parser.js | 6 ++++-- test/specs/device-all.json | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 2fb34d3..39c8d7b 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -593,9 +593,11 @@ ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [ // Nokia + /(nokia) (t[12][01])/i + ], [VENDOR, MODEL, [TYPE, TABLET]], [ /(?:maemo|nokia).*(n900|lumia \d+)/i, - /nokia[-_ ]?([-\w\.]*)/i - ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ + /nokia[-_ ]?(([-\w\.]*))/i + ], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [ // Google /(pixel (c|tablet))\b/i // Google Pixel C/Tablet diff --git a/test/specs/device-all.json b/test/specs/device-all.json index 9adbd09..d73fd3e 100644 --- a/test/specs/device-all.json +++ b/test/specs/device-all.json @@ -2186,6 +2186,33 @@ "type": "mobile" } }, + { + "desc": "Nokia T20", + "ua": "Mozilla/5.0 (Linux; Android 12; Nokia T20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "T20", + "type": "tablet" + } + }, + { + "desc": "Nokia T20", + "ua": "Mozilla/5.0 (Linux; Android 11; Nokia T20 Build/RP1A.201005.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/93.0.4577.62 Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "T20", + "type": "tablet" + } + }, + { + "desc": "Nokia T21", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Nokia T21 Build/TP1A.220624.014)", + "expect": { + "vendor": "Nokia", + "model": "T21", + "type": "tablet" + } + }, { "desc": "Nokia 2720 Flip", "ua": "Mozilla/5.0 (Mobile; Nokia_2720_Flip; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.2", From 94d3d84cd55caf6b46514e4be175b8ca9d612d73 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 20 Nov 2024 18:00:18 +0700 Subject: [PATCH 11/73] Add new device vendor: HMD --- src/enums/ua-parser-enums.js | 1 + src/main/ua-parser.js | 2 +- test/specs/device-all.json | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index ab46296..37066fc 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -213,6 +213,7 @@ const Vendor = Object.freeze({ GEEKSPHONE: 'GeeksPhone', GENERIC: 'Generic', GOOGLE: 'Google', + HMD: 'HMD', HP: 'HP', HTC: 'HTC', HUAWEI: 'Huawei', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 39c8d7b..a3b867e 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -697,7 +697,7 @@ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan - /; (imo) ([\w ]+?)(?: bui|\))/i, // IMO + /; (hmd|imo) ([\w ]+?)(?: bui|\))/i, // HMD/IMO /(hp) ([\w ]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia diff --git a/test/specs/device-all.json b/test/specs/device-all.json index d73fd3e..bfefe5d 100644 --- a/test/specs/device-all.json +++ b/test/specs/device-all.json @@ -350,6 +350,33 @@ "type": "mobile" } }, + { + "desc": "HMD Pulse", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse", + "type": "mobile" + } + }, + { + "desc": "HMD Pulse Plus", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse Plus) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse Plus", + "type": "mobile" + } + }, + { + "desc": "HMD Pulse Pro", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse Pro", + "type": "mobile" + } + }, { "desc": "Honor MagicPad 13 WiFi", "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; GDI-W09 Build/HONORGDI-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", From a1d81c928c3776d8906280ab2fc95e7f41323481 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 21 Nov 2024 16:06:27 +0700 Subject: [PATCH 12/73] Move device test spec into separate files --- test/mocha-test.js | 10 +- test/specs/device-all.json | 5362 ---------------------------- test/specs/devices/_others.json | 250 ++ test/specs/devices/acer.json | 11 + test/specs/devices/advan.json | 29 + test/specs/devices/alcatel.json | 20 + test/specs/devices/amazon.json | 137 + test/specs/devices/apple.json | 128 + test/specs/devices/asus.json | 155 + test/specs/devices/blackberry.json | 47 + test/specs/devices/cat.json | 38 + test/specs/devices/energizer.json | 29 + test/specs/devices/facebook.json | 38 + test/specs/devices/fairphone.json | 29 + test/specs/devices/google.json | 236 ++ test/specs/devices/hmd.json | 29 + test/specs/devices/honor.json | 164 + test/specs/devices/htc.json | 29 + test/specs/devices/huawei.json | 947 +++++ test/specs/devices/imo.json | 38 + test/specs/devices/infinix.json | 56 + test/specs/devices/itel.json | 56 + test/specs/devices/jolla.json | 11 + test/specs/devices/kobo.json | 20 + test/specs/devices/lenovo.json | 74 + test/specs/devices/lg.json | 164 + test/specs/devices/meizu.json | 20 + test/specs/devices/micromax.json | 30 + test/specs/devices/microsoft.json | 47 + test/specs/devices/motorola.json | 83 + test/specs/devices/nintendo.json | 47 + test/specs/devices/nokia.json | 74 + test/specs/devices/nothing.json | 29 + test/specs/devices/nvidia.json | 11 + test/specs/devices/oneplus.json | 119 + test/specs/devices/oppo.json | 137 + test/specs/devices/ouya.json | 11 + test/specs/devices/panasonic.json | 47 + test/specs/devices/pico.json | 29 + test/specs/devices/polytron.json | 38 + test/specs/devices/realme.json | 74 + test/specs/devices/roku.json | 29 + test/specs/devices/samsung.json | 371 ++ test/specs/devices/sharp.json | 56 + test/specs/devices/smartfren.json | 29 + test/specs/devices/sony.json | 209 ++ test/specs/devices/tcl.json | 479 +++ test/specs/devices/technisat.json | 20 + test/specs/devices/tecno.json | 20 + test/specs/devices/tesla.json | 20 + test/specs/devices/ulefone.json | 92 + test/specs/devices/vivo.json | 74 + test/specs/devices/xiaomi.json | 524 +++ test/specs/devices/zte.json | 11 + 54 files changed, 5474 insertions(+), 5363 deletions(-) delete mode 100644 test/specs/device-all.json create mode 100644 test/specs/devices/_others.json create mode 100644 test/specs/devices/acer.json create mode 100644 test/specs/devices/advan.json create mode 100644 test/specs/devices/alcatel.json create mode 100644 test/specs/devices/amazon.json create mode 100644 test/specs/devices/apple.json create mode 100644 test/specs/devices/asus.json create mode 100644 test/specs/devices/blackberry.json create mode 100644 test/specs/devices/cat.json create mode 100644 test/specs/devices/energizer.json create mode 100644 test/specs/devices/facebook.json create mode 100644 test/specs/devices/fairphone.json create mode 100644 test/specs/devices/google.json create mode 100644 test/specs/devices/hmd.json create mode 100644 test/specs/devices/honor.json create mode 100644 test/specs/devices/htc.json create mode 100644 test/specs/devices/huawei.json create mode 100644 test/specs/devices/imo.json create mode 100644 test/specs/devices/infinix.json create mode 100644 test/specs/devices/itel.json create mode 100644 test/specs/devices/jolla.json create mode 100644 test/specs/devices/kobo.json create mode 100644 test/specs/devices/lenovo.json create mode 100644 test/specs/devices/lg.json create mode 100644 test/specs/devices/meizu.json create mode 100644 test/specs/devices/micromax.json create mode 100644 test/specs/devices/microsoft.json create mode 100644 test/specs/devices/motorola.json create mode 100644 test/specs/devices/nintendo.json create mode 100644 test/specs/devices/nokia.json create mode 100644 test/specs/devices/nothing.json create mode 100644 test/specs/devices/nvidia.json create mode 100644 test/specs/devices/oneplus.json create mode 100644 test/specs/devices/oppo.json create mode 100644 test/specs/devices/ouya.json create mode 100644 test/specs/devices/panasonic.json create mode 100644 test/specs/devices/pico.json create mode 100644 test/specs/devices/polytron.json create mode 100644 test/specs/devices/realme.json create mode 100644 test/specs/devices/roku.json create mode 100644 test/specs/devices/samsung.json create mode 100644 test/specs/devices/sharp.json create mode 100644 test/specs/devices/smartfren.json create mode 100644 test/specs/devices/sony.json create mode 100644 test/specs/devices/tcl.json create mode 100644 test/specs/devices/technisat.json create mode 100644 test/specs/devices/tecno.json create mode 100644 test/specs/devices/tesla.json create mode 100644 test/specs/devices/ulefone.json create mode 100644 test/specs/devices/vivo.json create mode 100644 test/specs/devices/xiaomi.json create mode 100644 test/specs/devices/zte.json diff --git a/test/mocha-test.js b/test/mocha-test.js index 68213ac..9b35330 100644 --- a/test/mocha-test.js +++ b/test/mocha-test.js @@ -7,10 +7,18 @@ var traverse = require('@babel/traverse').default; var {UAParser} = require('../src/main/ua-parser'); var browsers = require('./specs/browser-all.json'); var cpus = require('./specs/cpu-all.json'); -var devices = require('./specs/device-all.json'); +var devices = readJsonFiles('test/specs/devices'); var engines = require('./specs/engine-all.json'); var os = require('./specs/os-all.json'); +function readJsonFiles(dir) { + var list = []; + fs.readdirSync(dir).forEach(function (file) { + list.push(...JSON.parse(fs.readFileSync(`${dir}/${file}`, 'utf-8'))); + }); + return list; +}; + var parser = new UAParser(); var methods = [ { diff --git a/test/specs/device-all.json b/test/specs/device-all.json deleted file mode 100644 index bfefe5d..0000000 --- a/test/specs/device-all.json +++ /dev/null @@ -1,5362 +0,0 @@ -[ - { - "desc": "K", - "ua": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "K", - "type": "mobile" - } - }, - { - "desc": "Advan M4", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0; ADVAN M4 Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36 OPR/28.0.2254.119214", - "expect": { - "vendor": "ADVAN", - "model": "M4", - "type": "mobile" - } - }, - { - "desc": "Advan S40", - "ua": "Mozilla/5.0 (Linux; Android 7.0; ADVAN S40 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Mobile Safari/537.36 EdgA/79.0.309.58", - "expect": { - "vendor": "ADVAN", - "model": "S40", - "type": "mobile" - } - }, - { - "desc": "Advan Sketsa 2", - "ua": "Mozilla/5.0 (Linux; Android 11; ADVAN 1011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36", - "expect": { - "vendor": "ADVAN", - "model": "1011", - "type": "mobile" - } - }, - { - "desc": "ASUS Nexus 7", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "Nexus 7", - "type": "tablet" - } - }, - { - "desc": "ASUS Padfone", - "ua": "Mozilla/5.0 (Linux; Android 4.1.1; PadFone 2 Build/JRO03L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "PadFone", - "type": "tablet" - } - }, - { - "desc": "ASUS ZenPad 10", - "ua": "Mozilla/5.0 (Linux; Android 6.0; P00C Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "P00C", - "type": "tablet" - } - }, - { - "desc": "ASUS ZenPad Z8s", - "ua": "Mozilla/5.0 (Linux; Android 7.0; ASUS_P00J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Safari/537.36\n", - "expect": { - "vendor": "ASUS", - "model": "P00J", - "type": "tablet" - } - }, - { - "desc": "ASUS ROG", - "ua": "Mozilla/5.0 (Linux; Android 8.1; ZS600KL Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZS600KL", - "type": "mobile" - } - }, - { - "desc": "ASUS ROG II", - "ua": "Mozilla/5.0 (Linux; Android 9; ASUS_I001DA Build/PKQ1.190414.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "I001DA", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 2", - "ua": "Mozilla/5.0 (Linux; Android 5.0; ASUS ZenFone 2 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZenFone 2", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 3 Deluxe", - "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_Z016D Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.132 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "Z016D", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 5", - "ua": "Mozilla/5.0 (Linux; Android 8.0; ZE620KL Build/OPR1.170623.032) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZE620KL", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 7", - "ua": "Mozilla/5.0 (Linux; Android 10; ASUS_I002D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.81 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "I002D", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 7 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; ZS671KS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZS671KS", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Max Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; ZB602KL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZB602KL", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Max Pro (M1)", - "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X00TD Build/OPM1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "X00TD", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Max M2", - "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01AD) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "X01AD", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Max Pro M2", - "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01BDA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "X01BDA", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Go", - "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_X009DA Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "X009DA", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 2 Laser", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ASUS_Z00ED) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "Z00ED", - "type": "mobile" - } - }, - { - "desc": "Acer Iconia A1-810", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; A1-810 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", - "expect": { - "vendor": "Acer", - "model": "A1-810", - "type": "tablet" - } - }, - { - "desc": "BlackBerry Priv", - "ua": "User-Agent: Mozilla/5.0 (Linux; Android 5.1.1; STV100-1 Build/LMY47V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/46.0.2490.76 Mobile Safari/537.36", - "expect": { - "vendor": "BlackBerry", - "model": "STV100-1", - "type": "mobile" - } - }, - { - "desc": "BlackBerry Keyone", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBB100-1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Mobile Safari/537.36", - "expect": { - "vendor": "BlackBerry", - "model": "BBB100-1", - "type": "mobile" - } - }, - { - "desc": "BlackBerry Key2", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBF100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", - "expect": { - "vendor": "BlackBerry", - "model": "BBF100-1", - "type": "mobile" - } - }, - { - "desc": "BlackBerry Key2 LE", - "ua": "User-Agent: Mozilla/5.0 (Linux; Android 8.1.0; BBE100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497 Mobile Safari/537.36", - "expect": { - "vendor": "BlackBerry", - "model": "BBE100-1", - "type": "mobile" - } - }, - { - "desc": "Blackview 4900Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; BV4900Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "BV4900Pro", - "type": "mobile" - } - }, - { - "desc": "Cat B15Q", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; B15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "Cat", - "model": "B15Q", - "type": "mobile" - } - }, - { - "desc": "Cat B35", - "ua": "Mozilla/5.0 (Mobile; CAT B35; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.1", - "expect": { - "vendor": "Cat", - "model": "B35", - "type": "mobile" - } - }, - { - "desc": "Cat S22 Flip", - "ua": "Mozilla/5.0 (Linux; Android 11; S22 FLIP Build/RKQ1.210416.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36", - "expect": { - "vendor": "Cat", - "model": "S22 FLIP", - "type": "mobile" - } - }, - { - "desc": "Cat S62 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; S62 Pro Build/RKQ1.210406.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.85 Mobile Safari/537.36 GSA/12.34.17.23.arm64", - "expect": { - "vendor": "Cat", - "model": "S62 Pro", - "type": "mobile" - } - }, - { - "desc": "Desktop (IE11 with Tablet string)", - "ua": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; GWX:MANAGED; rv:11.0) like Gecko", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "undefined" - } - }, - { - "desc": "Mobile (DuckDuckGo mobile browser)", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile DuckDuckGo/5 Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Energizer Energy 400", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Energy400 Build/MRA58K test-keys; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.158 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/172.0.0.66.93;]", - "expect": { - "vendor": "Energizer", - "model": "Energy400", - "type": "mobile" - } - }, - { - "desc": "Energizer Energy 400S", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Energy 400S Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.85 Mobile Safari/537.36", - "expect": { - "vendor": "Energizer", - "model": "Energy 400S", - "type": "mobile" - } - }, - { - "desc": "Energizer Ultimate 65G", - "ua": "Mozilla/5.0 (Linux; Android 14; Energizer Ultimate 65G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Energizer", - "model": "Ultimate 65G", - "type": "mobile" - } - }, - { - "desc": "Fairphone 1U", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; FP1U Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Fairphone", - "model": "FP1U", - "type": "mobile" - } - }, - { - "desc": "Fairphone 2", - "ua": "Mozilla/5.0 (Linux; Android 7.1.2; FP2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Fairphone", - "model": "FP2", - "type": "mobile" - } - }, - { - "desc": "Fairphone 3", - "ua": "Mozilla/5.0 (Linux; Android 9; FP3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", - "expect": { - "vendor": "Fairphone", - "model": "FP3", - "type": "mobile" - } - }, - { - "desc": "HMD Pulse", - "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "HMD", - "model": "Pulse", - "type": "mobile" - } - }, - { - "desc": "HMD Pulse Plus", - "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse Plus) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "HMD", - "model": "Pulse Plus", - "type": "mobile" - } - }, - { - "desc": "HMD Pulse Pro", - "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "HMD", - "model": "Pulse Pro", - "type": "mobile" - } - }, - { - "desc": "Honor MagicPad 13 WiFi", - "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; GDI-W09 Build/HONORGDI-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "GDI-W09", - "type": "tablet" - } - }, - { - "desc": "Honor Pad 2", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; en-nz; JDN-W09 Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/6.0 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "JDN-W09", - "type": "tablet" - } - }, - { - "desc": "Honor Pad 2", - "ua": "Mozilla/5.0 (Linux; U; Android 9; zh-Hans-CN; JDN2-W09HN Build/HUAWEIJDN2-W09HN) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.6.6.164 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "JDN2-W09HN", - "type": "tablet" - } - }, - { - "desc": "Honor Pad 7 10.1", - "ua": "Mozilla/5.0 (Linux; Android 12; AGM3-AL09HN Build/HONORAGM3-AL09HN; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.46 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/490.0.0.63.82;IABMV/1;]", - "expect": { - "vendor": "Honor", - "model": "AGM3-AL09HN", - "type": "tablet" - } - }, - { - "desc": "Honor Pad 8 12.0", - "ua": "Mozilla/5.0 (Linux; Android 12; HEY-W09 Build/HONORHEY-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "HEY-W09", - "type": "tablet" - } - }, - { - "desc": "Honor Pad 9 12.1", - "ua": "Mozilla/5.0 (Linux; Android 13; HEY2-N09 Build/HONORHEY2-N09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 [FB_IAB/FB4A;FBAV/465.0.0.63.83;]", - "expect": { - "vendor": "Honor", - "model": "HEY2-N09", - "type": "tablet" - } - }, - { - "desc": "Honor Pad 9 12.1 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 14; HEY2-W09 Build/HONORHEY2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/129.0.6668.102 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", - "expect": { - "vendor": "Honor", - "model": "HEY2-W09", - "type": "tablet" - } - }, - { - "desc": "Honor Pad V7 Pro 11", - "ua": "Mozilla/5.0 (Linux; Android 12; BRT-AN09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 EdgA/109.0.1518.53", - "expect": { - "vendor": "Honor", - "model": "BRT-AN09", - "type": "tablet" - } - }, - { - "desc": "Honor Pad V7 Pro 11 WiFi", - "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; BRT-W09 Build/HONORBRT-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.5.0.336 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "BRT-W09", - "type": "tablet" - } - }, - { - "desc": "Honor Pad X6", - "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09HN Build/HUAWEIAGR-W09HN; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.9 SP-engine/2.28.0 baiduboxapp/12.9.0.11 (Baidu; P1 10) NABar/1.0", - "expect": { - "vendor": "Honor", - "model": "AGR-W09HN", - "type": "tablet" - } - }, - { - "desc": "Honor Pad X7 8 LTE", - "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-AL00HN; HMSCore 6.0.0.306) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.3.300 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "KOB2-AL00HN", - "type": "tablet" - } - }, - { - "desc": "Honor Pad X7 8 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-W09HN; HMSCore 6.1.0.314) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 HuaweiBrowser/12.0.0.301 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "KOB2-W09HN", - "type": "tablet" - } - }, - { - "desc": "Honor Pad X8 Lite", - "ua": "Mozilla/5.0 (Linux; Android 12; AGM-W09HN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "AGM-W09HN", - "type": "tablet" - } - }, - { - "desc": "Honor Pad X9 11.5 LTE", - "ua": "Mozilla/5.0 (Linux; Android 13; ELN-L09 Build/HONORELN-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Mobile Safari/537.36[FBAN/EMA;FBLC/zh_CN;FBAV/432.0.0.9.110;FBCX/modulariab;]", - "expect": { - "vendor": "Honor", - "model": "ELN-L09", - "type": "tablet" - } - }, - { - "desc": "Honor Pad X9 11.5 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 13; ELN-W09 Build/HONORELN-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "ELN-W09", - "type": "tablet" - } - }, - { - "desc": "HTC Desire 820", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; HTC Desire 820 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", - "expect": { - "vendor": "HTC", - "model": "Desire 820", - "type": "mobile" - } - }, - { - "desc": "HTC Evo Shift 4G", - "ua": "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0", - "expect": { - "vendor": "Sprint", - "model": "APA7373KT", - "type": "mobile" - } - }, - { - "desc": "HTC Nexus 9", - "ua": "Mozilla/5.0 (Linux; Android 5.0; Nexus 9 Build/LRX21R) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Mobile Crosswalk/7.36.154.13 Safari/537.36", - "expect": { - "vendor": "HTC", - "model": "Nexus 9", - "type": "tablet" - } - }, - { - "desc": "Huawei Honor", - "ua": "Mozilla/5.0 (Linux; U; Android 2.3; xx-xx; U8860 Build/HuaweiU8860) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", - "expect": { - "vendor": "Huawei", - "model": "U8860", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L41) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L41", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-AL10", - "type": "mobile" - } - }, - { - "desc": "Huawei Nexus 6P", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC19V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537", - "expect": { - "vendor": "Huawei", - "model": "Nexus 6P", - "type": "mobile" - } - }, - { - "desc": "Huawei P10", - "ua": "Mozilla/5.0 (Linux; Android 7.0; VTR-L09 Build/HUAWEIVTR-L09; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "VTR-L09", - "type": "mobile" - } - }, - { - "desc": "Huawei Y3II", - "ua": "Mozilla/5.0 (Linux; U; Android 5.1; xx-xx; HUAWEI LUA-L03 Build/HUAWEILUA-L03) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LUA-L03", - "type": "mobile" - } - }, - { - "desc": "HUAWEI MediaPad C5 8", - "ua": "Mozilla/5.0 (Linux; Android 7.0; MON-AL19B Build/HUAWEIMON-AL19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.83 Mobile Safari/537.36 T7/11.7 baiduboxapp/11.7.0.10 (Baidu; P1 7.0)", - "expect": { - "vendor": "Huawei", - "model": "MON-AL19B", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M2 10.1", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; HUAWEI M2-A01L Build/HUAWEIM2-A01L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/95.0.4638.74 Safari/537.36[FBAN/EMA;FBLC/fr_FR;FBAV/421.0.0.14.100;]", - "expect": { - "vendor": "Huawei", - "model": "M2-A01L", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M3", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0; en-US; BTV-DL09 Build/HUAWEIBEETHOVEN-DL09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11.5.0.1015 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BTV-DL09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M3 8", - "ua": "Mozilla/5.0 (Linux; Android 7.0; HUAWEI BTV-W09 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.96 Mobile Safari/537.36 AlohaBrowser/3.1.1", - "expect": { - "vendor": "Huawei", - "model": "BTV-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M3 Lite", - "ua": "Mozilla/5.0 (Linux; Android 7.0; CPN-L09 Build/HUAWEICPN-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36[FBAN/EMA;FBLC/ru_RU;FBAV/233.0.0.12.118;]", - "expect": { - "vendor": "Huawei", - "model": "CPN-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M3 Lite", - "ua": "Mozilla/5.0 (Linux; Android 7.0; CPN-W09 Build/HUAWEICPN-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.71 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/374.0.0.20.109;]", - "expect": { - "vendor": "Huawei", - "model": "CPN-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M3 Lite 10", - "ua": "Mozilla/5.0 (Linux; Android 7.0; BAH-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BAH-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5 10.8", - "ua": "Mozilla/5.0 (Linux; Android 9; CMR-W09 Build/HUAWEICMR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.102 Safari/537.36 Line/14.18.1/IAB", - "expect": { - "vendor": "Huawei", - "model": "CMR-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; BAH2-W19 Build/HUAWEIBAH2-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BAH2-W19", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5 Lite", - "ua": "Mozilla/5.0 (Linux; Android 9; JDN2-W09 Build/HUAWEIJDN2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/90.0.4430.210 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/318.0.0.39.154;]", - "expect": { - "vendor": "Huawei", - "model": "JDN2-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5 Lite", - "ua": "Mozilla/5.0 (Linux; Android 9; JDN2-AL50 Build/HUAWEIJDN2-AL50; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.13.0 SP-engine/2.29.0 matrixstyle/0 lite baiduboxapp/5.8.0.10 (Baidu; P1 9) NABar/1.", - "expect": { - "vendor": "Huawei", - "model": "JDN2-AL50", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5 8.4", - "ua": "Mozilla/5.0 (Linux; Android 9; SHT-W09 Build/HUAWEISHT-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.87 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "SHT-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5", - "ua": "Mozilla/5.0 (Linux; Android 9; SHT-AL09 Build/HUAWEISHT-AL09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "SHT-AL09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M6 10.8", - "ua": "Mozilla/5.0 (Linux; Android 14; SCM-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6612.143 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "SCM-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M6 8.4", - "ua": "Mozilla/5.0 (Linux; Android 9; VRD-W09; HMSCore 6.14.0.321; GMSCore 22.26.15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "VRD-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T5", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-L09 Build/HUAWEIAGS2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.125 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS2-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10", - "ua": "Mozilla/5.0 (Linux; U; Android 10; en-US; AGR-L09 Build/HUAWEIAGR-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.3.8.1305 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGR-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10", - "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09 Build/HUAWEIAGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGR-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10s", - "ua": "Mozilla/5.0 (Linux; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS3-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T 8.0", - "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-L09 Build/HUAWEIKOB2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/396.0.0.21.104;]", - "expect": { - "vendor": "Huawei", - "model": "KOB2-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T 8.0", - "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-W09 Build/HUAWEIKOB2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 Mobile Safari/537.36 HuaweiBrowser/15.0.4.312 HMSCore/6.14.0.301", - "expect": { - "vendor": "Huawei", - "model": "KOB2-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T1 10", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; T1-A21w Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Safari/537.36 SputnikBrowser/1.2.8.161", - "expect": { - "vendor": "Huawei", - "model": "T1-A21w", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T1 10", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; T1-A23L Build/HuaweiMediaPad; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 BingWeb/6.9.10", - "expect": { - "vendor": "Huawei", - "model": "T1-A23L", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T1 10", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; T1-A21L Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.93 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "T1-A21L", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T1 7", - "ua": "Mozilla/5.0 (Linux; 4.4.2; T1-701u) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "T1-701u", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T1 8", - "ua": "Mozilla/5.0 (Linux; U; Android 9.0; MediaPad T1 8.0 Build/HuaweiMediaPad) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30 OPR/28.0.2254.119224", - "expect": { - "vendor": "Huawei", - "model": "MediaPad T1 8.0", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10 9.7", - "ua": "Mozilla/5.0 (Linux; U; Android 10; en-US; AGRK-L09 Build/HUAWEIAGRK-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.6.0.1315 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGRK-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10 9.7 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; AGRK-W09; HMSCore 6.14.0.321) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGRK-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10s 10.1 LTE", - "ua": "Mozilla/5.0 (Linux; Android 10; AGS3K-L09 Build/HUAWEIAGS3K-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36 [FB_IAB/FB4A;FBAV/362.0.0.27.109;]", - "expect": { - "vendor": "Huawei", - "model": "AGS3K-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10s 10.1 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; AGS3K-W09; HMSCore 6.14.0.321) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS3K-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T2 10.0 Pro", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; 605HW Build/HuaweiMediaPad; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.78 Safari/537.36 [FB_IAB/FB4A;FBAV/436.0.0.35.101;]", - "expect": { - "vendor": "Huawei", - "model": "605HW", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T2 7.0 Pro", - "ua": "Mozilla/5.0 (Linux; Android 6.0; BGO-DL09 Build/HuaweiBAGGIO; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/407.0.0.30.97;]", - "expect": { - "vendor": "Huawei", - "model": "BGO-DL09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T3 10", - "ua": "Mozilla/5.0 (Linux; Android 7.0; AGS-W09 Build/HUAWEIAGS-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.90 Safari/537.36 GSA/10.83.10.21.arm64", - "expect": { - "vendor": "Huawei", - "model": "AGS-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T3 7", - "ua": "Mozilla/5.0 (Linux; Android 7.0; BG2-U03 Build/HUAWEIBG2-U03; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.111 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BG2-U03", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T3 8", - "ua": "Mozilla/5.0 (Linux; Android 7.0; KOB-W09 Build/HUAWEIKOB-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 Safari/537.36 [FB_IAB/Orca-Android;FBAV/354.0.0.10.113;]", - "expect": { - "vendor": "Huawei", - "model": "KOB-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T5 10", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-W09 Build/HUAWEIAGS2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", - "expect": { - "vendor": "Huawei", - "model": "AGS2-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad X2", - "ua": "Mozilla/5.0 (Linux; Android 8.0; GEM-703L Build/HUAWEIGEM-703L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/043906 Mobile Safari/537.36 MicroMessenger/6.6.3.1260(0x26060339) NetType/WIFI Language/zh_", - "expect": { - "vendor": "Huawei", - "model": "GEM-703L", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 10.4", - "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH3-W09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BAH3-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 10.4", - "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH3-L09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BAH3-L09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 10.4 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; BAH3-W59 Build/HUAWEIBAH3-W59; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36HiSearch/22.0.6.315", - "expect": { - "vendor": "Huawei", - "model": "BAH3-W59", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 10.4 (2022)", - "ua": "Mozilla/5.0 (Linux; Android 10; BAH4-L09 Build/HUAWEIBAH4-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BAH4-L09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 10.4 (2022) WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH4-W09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BAH4-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 10.4 SE", - "ua": "Mozilla/5.0 (Linux; Android 12; AGS5-L09 Build/HUAWEIAGS5-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS5-L09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 10.4 SE WiFi", - "ua": "Mozilla/5.0 (Linux; Android 12; AGS5-W09 Build/HUAWEIAGS5-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Safari/537.36 [FB_IAB/FB4A;FBAV/480.0.0.54.88;]", - "expect": { - "vendor": "Huawei", - "model": "AGS5-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 11 (2023) WiFi", - "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; DBR-W10 Build/HUAWEIDBR-W10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.9.6.501 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "DBR-W10", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 11 WiFi", - "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-cn; DBY-W09 Build/HUAWEIDBY-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.86 MQQBrowser/14.6 Mobile Safari/537.36 COVC/046801", - "expect": { - "vendor": "Huawei", - "model": "DBY-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 11.5 Air WiFi", - "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; DBY2-W00 Build/HUAWEIDBY2-W00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/7.3.8.663 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "DBY2-W00", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 11.5 LTE", - "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; BTK-AL09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BTK-AL09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 11.5 S WiFi", - "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; TGR-W09; HMSCore 6.14.0.322; GMSCore 0.3.3.1.240913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 HuaweiBrowser/14.0.2.317 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "TGR-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad 11.5 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; BTK-W09; HMSCore 6.14.0.322; GMSCore 214816056) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BTK-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad C5 8", - "ua": "Mozilla/5.0 (Linux; Android 7.0; MON-W19 Build/HUAWEIMON-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Mobile Safari/537.36 [Pinterest/Android]", - "expect": { - "vendor": "Huawei", - "model": "MON-W19", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad Pro 11", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 12; GOT-AL09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 YaBrowser/23.5.5.60.01 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "GOT-AL09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad Pro 11 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 12; GOT-W09 Build/HUAWEIGOT-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/97.0.4692.98 Safari/537.36 T7/13.19 BDOS/1.0 (HarmonyOS 3.0.0) SP-engine/2.57.0 baiduboxapp/13.19.0.12 (Baidu; P1 12) NABar/1.0", - "expect": { - "vendor": "Huawei", - "model": "GOT-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad Pro 12.6 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; WGR-W09 Build/HUAWEIWGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/412.0.0.8.106;]", - "expect": { - "vendor": "Huawei", - "model": "WGR-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad SE 11 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; AGS6-W09; HMSCore 6.12.2.309) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.5.315 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS6-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad Pro 13.2", - "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; PCE-W29; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "PCE-W29", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad T 10", - "ua": "Mozilla/5.0 (Linux; Android 10; AGR-L09; HMSCore 5.0.4.301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.3.304 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGR-L09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad T10s", - "ua": "Mozilla/5.0 (Linux; U; Android 10; zh-cn; AGS3-AL00 Build/HUAWEIAGS3-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/11.4 Mobile Safari/537.36 COVC/045530", - "expect": { - "vendor": "Huawei", - "model": "AGS3-AL00", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad T10s WiFi", - "ua": "Mozilla/5.0 (Linux; U; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/88.0.4324.93 Safari/537.36 OPR/60.0.2254.59405", - "expect": { - "vendor": "Huawei", - "model": "AGS3-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad T8 8 LTE", - "ua": "Mozilla/5.0 (Linux; U; Android 10; KOB2K-L09 Build/HUAWEIKOB2K-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36 OPR/83.0.2254.73002", - "expect": { - "vendor": "Huawei", - "model": "KOB2K-L09", - "type": "tablet" - } - }, - { - "desc": "Huawei M3", - "ua": "Mozilla/5.0 (Linux; Android 7.0; BTV-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BTV-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei Mate 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 8.0; BLA-L29 Build/HUAWEIBLA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.6 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BLA-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate X", - "ua": "Mozilla/5.0 (Linux; Android 9; TAH-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "TAH-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate X2", - "ua": "Mozilla/5.0 (Linux; Android 10; TET-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "TET-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 X", - "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "EVR-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L09", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-AL00", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-AL10", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L0C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L0C", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-TL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-TL00", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 50 Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; DCO-LX9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "DCO-LX9", - "type": "mobile" - } - }, - { - "desc": "Huawei P20 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "ANE-LX1", - "type": "mobile" - } - }, - { - "desc": "Huawei P20", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; EML-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "EML-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "CLT-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P30", - "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "ELE-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P30 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "VOG-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P40", - "ua": "Mozilla/5.0 (Linux; Android 10; ANA-AN00 Build/HUAWEIANA-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/11.26 SP-engine/2.22.0 baiduboxapp/11.26.0.10 (Baidu; P1 10) NABar/1.0", - "expect": { - "vendor": "Huawei", - "model": "ANA-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei P40 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; ELS-AN00 Build/HUAWEIELS-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/6.0.0", - "expect": { - "vendor": "Huawei", - "model": "ELS-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei 30 Pro+", - "ua": "Mozilla/5.0 (Linux; Android 10; EBG-AN10 Build/HUAWEIEBG-AN10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36 EdgA/42.0.0.2741", - "expect": { - "vendor": "Huawei", - "model": "EBG-AN10", - "type": "mobile" - } - }, - { - "desc": "Huawei 30S", - "ua": "Mozilla/5.0 (Linux; Android 10; CDY-AN90 Build/HUAWEICDY-AN90; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/5.8.0", - "expect": { - "vendor": "Huawei", - "model": "CDY-AN90", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L21", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L61", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L71) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L71", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L61D", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YALE-L61A", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YALE-L61D", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L71A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YALE-L71A", - "type": "mobile" - } - }, - { - "desc": "Huawei Enjoy10e", - "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", - "expect": { - "vendor": "Huawei", - "model": "MED-AL00", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 6A", - "ua": "Mozilla/5.0 (Linux; Android 7.0; DLI-L22 Build/HONORDLI-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/252.0.0.22.355;]", - "expect": { - "vendor": "Honor", - "model": "DLI-L22", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 7", - "ua": "Mozilla/5.0 (Linux; Android 6.0; PLK-L01 Build/HONORPLK-L01; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "PLK-L01", - "type": "mobile" - } - }, - { - "desc": "Huawei 10 Lite", - "ua": "Mozilla/5.0 (Linux; Android 9; HRY-LX1 Build/HONORHRY-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "HRY-LX1", - "type": "mobile" - } - }, - { - "desc": "Huawei Y7 2018", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; LDN-L01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LDN-L01", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 8X", - "ua": "Mozilla/5.0 (Linux; Android 9; JSN-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "JSN-L21", - "type": "mobile" - } - }, - { - "desc": "Huawei Y6 2019", - "ua": "Mozilla/5.0 (Linux; Android 9; MRD-LX1N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "MRD-LX1N", - "type": "mobile" - } - }, - { - "desc": "Huawei Y9 2019", - "ua": "Mozilla/5.0 (Linux; Android 9; JKM-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "JKM-LX2", - "type": "mobile" - } - }, - { - "desc": "Huawei Y5", - "ua": "Mozilla/5.0 (Linux; Android 9; AMN-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AMN-LX3", - "type": "mobile" - } - }, - { - "desc": "Huawei Y7p", - "ua": "Mozilla/5.0 (Linux; Android 9; ART-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "ART-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SNE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "SNE-LX1", - "type": "mobile" - } - }, - { - "desc": "Huawei P10 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; WAS-LX1A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "WAS-LX1A", - "type": "mobile" - } - }, - { - "desc": "Huawei Y5 Lite 2018", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; DRA-LX5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "DRA-LX5", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 8C", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BKK-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BKK-LX2", - "type": "mobile" - } - }, - { - "desc": "IMO FEEL A2", - "ua": "Mozilla/5.0 (Linux; Android 5.1; IMO FEEL A2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/49.0.2623.105 Mobile Safari/537.36", - "expect": { - "vendor": "IMO", - "model": "FEEL A2", - "type": "mobile" - } - }, - { - "desc": "IMO Q2", - "ua": "Mozilla/5.0 (Linux; Android 5.1; IMO Q2 Build/LMY47D; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/65.0.3325.109 Mobile Safari/537.36 GSA/7.22.24.21.arm", - "expect": { - "vendor": "IMO", - "model": "Q2", - "type": "mobile" - } - }, - { - "desc": "IMO S2", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; IMO S2 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.162 Mobile Safari/537.36", - "expect": { - "vendor": "IMO", - "model": "S2", - "type": "mobile" - } - }, - { - "desc": "IMO Tab X9", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; id-id; IMO TAB X9 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", - "expect": { - "vendor": "IMO", - "model": "TAB X9", - "type": "tablet" - } - }, - { - "desc": "Infinix Hot 7 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; Infinix X625C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X625C", - "type": "mobile" - } - }, - { - "desc": "Infinix Hot 10T", - "ua": "Mozilla/5.0 (Linux; Android 11; Infinix X689C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X689C", - "type": "mobile" - } - }, - { - "desc": "Infinix Hot 11s", - "ua": "Mozilla/5.0 (Linux; Android 11; Infinix X6812 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X6812", - "type": "mobile" - } - }, - { - "desc": "Infinix Smart 5", - "ua": "Mozilla/5.0 (Linux; Android 10; Infinix X657C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X657C", - "type": "mobile" - } - }, - { - "desc": "Infinix XPad", - "ua": "Mozilla/5.0 (Linux; Android 14; Infinix X1101B Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.99 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", - "expect": { - "vendor": "Infinix", - "model": "X1101B", - "type": "tablet" - } - }, - { - "desc": "Infinix Zero 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; Infinix X6815B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X6815B", - "type": "mobile" - } - }, - { - "desc": "Apple Desktop", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15", - "expect": { - "vendor": "Apple", - "model": "Macintosh", - "type": "undefined" - } - }, - { - "desc": "Apple Watch", - "ua": "atc/1.0 watchOS/7.3.3 model/Watch4,2 hwp/t8006 build/18S830 (6; dt:191)", - "expect": { - "vendor": "Apple", - "model": "watch", - "type": "wearable" - } - }, - { - "desc": "iPad using UCBrowser", - "ua": "Mozilla/5.0 (iPad; U; CPU OS 11_2 like Mac OS X; zh-CN; iPad5,3) AppleWebKit/534.46 (KHTML, like Gecko) UCBrowser/3.0.1.776 U3/ Mobile/10A403 Safari/7543.48.3", - "expect": { - "vendor": "Apple", - "model": "iPad", - "type": "tablet" - } - }, - { - "desc": "iPad Air", - "ua": "Mozilla/5.0 (iPad; CPU OS 12_4_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPad4,1;FBMD/iPad;FBSN/iOS;FBSV/12.4.5;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPad", - "type": "tablet" - } - }, - { - "desc": "iPad using Facebook Browser", - "ua": "Mozilla/5.0 (iPad; CPU OS 14_4_2 like Mac OS X) WebKit/8610 (KHTML, like Gecko) Mobile/18D70 [FBAN/FBIOS;FBDV/iPad7,11;FBMD/iPad;FBSN/iOS;FBSV/14.4.2;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5]", - "expect": { - "vendor": "Apple", - "model": "iPad", - "type": "tablet" - } - }, - { - "desc": "iPod", - "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53", - "expect": { - "vendor": "Apple", - "model": "iPod touch", - "type": "mobile" - } - }, - { - "desc": "JVC LT-43V55LFA Smart TV", - "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB211 VSTVB MB200 HbbTV/1.2.1 (; JVC; MB211; 3.19.4.2; _TV_NT72563_2017 SmartTvA/3.0.0", - "expect": { - "vendor": "JVC", - "model": "MB211", - "type": "smarttv" - } - }, - { - "desc": "JVC LT-43V65LUA Smart TV", - "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB130 VSTVB MB100 HbbTV/1.2.1 (; JVC; MB130; 5.7.20.0; _TV_G10_2017;) SmartTvA/3.0.0", - "expect": { - "vendor": "JVC", - "model": "MB130", - "type": "smarttv" - } - }, - { - "desc": "Kobo eReader", - "ua": "Mozilla/5.0 (Unknown; Linux) AppleWebKit/538.1 (KHTML, like Gecko) Kobo eReader Safari/538.1", - "expect": { - "vendor": "Kobo", - "model": "eReader", - "type": "tablet" - } - }, - { - "desc": "Kobo Touch", - "ua": "Mozilla/5.0 (Linux; U; Android 2.0; en-us;) AppleWebKit/538.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/538.1 (Kobo Touch 0377/4.20.14622)", - "expect": { - "vendor": "Kobo", - "model": "Touch", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab 2", - "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Lenovo TAB 2 A7-30HC Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TAB 2 A7", - "type": "tablet" - } - }, - { - "desc": "Lenovo Phone", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Lenovo PB2-650M Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/311.0.0.44.117;]", - "expect": { - "vendor": "Lenovo", - "model": "PB2-650M", - "type": "mobile" - } - }, - { - "desc": "Lenovo Tab 3 Pro", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X90F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "YT3-X90F", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab 4", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo TB-X304F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TB-X304F", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab 4", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo TAB 2 A7-30HC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TAB 2 A7", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab 7 Essential", - "ua": "Mozilla/5.0 (Linux; Android 7.0; Lenovo TB-7304X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TB-7304X", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab M10", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X606F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 YaBrowser/20.9.4.99.01 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TB-X606F", - "type": "tablet" - } - }, - { - "desc": "Lenovo IdeaTab S6000", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; IdeaTab S6000-H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 YaBrowser/18.11.1.1011.01 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "IdeaTab S6000-H", - "type": "tablet" - } - }, - { - "desc": "LG V40 ThinQ", - "ua": "Mozilla/5.0 (Linux; Android 9; LM-V405) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-V405", - "type": "mobile" - } - }, - { - "desc": "LG K30", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; LM-X410.F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-X410.F", - "type": "mobile" - } - }, - { - "desc": "LG K30", - "ua": "Mozilla/5.0 (Linux; Android 9; LM-X410.FGN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-X410.FGN", - "type": "mobile" - } - }, - { - "desc": "LG K40", - "ua": "Mozilla/5.0 (Linux; Android 10; LM-X420) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-X420", - "type": "mobile" - } - }, - { - "desc": "LG Stylo 4", - "ua": "Mozilla/5.0 (Linux; Android 10; LM-Q710(FGN)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "LM-Q710(FGN)", - "type": "mobile" - } - }, - { - "desc": "LG Stylo 5", - "ua": "Mozilla/5.0 (Linux; Android 9; LM-Q720) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-Q720", - "type": "mobile" - } - }, - { - "desc": "LG G7 ThinQ", - "ua": "Mozilla/5.0 (Linux; Android 9; LM-G710VM Build/PKQ1.181105.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-G710VM", - "type": "mobile" - } - }, - { - "desc": "LG K20", - "ua": "Mozilla/5.0 (Android 13; Mobile; LG-M255; rv:111.0) Gecko/111.0 Firefox/111.0", - "expect": { - "vendor": "LG", - "model": "M255", - "type": "mobile" - } - }, - { - "desc": "LG K500", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; LG-K500 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "K500", - "type": "mobile" - } - }, - { - "desc": "LG Nexus 4", - "ua": "Mozilla/5.0 (Linux; Android 4.2.1; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", - "expect": { - "vendor": "LG", - "model": "Nexus 4", - "type": "mobile" - } - }, - { - "desc": "LG Nexus 4", - "ua": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; Google Nexus 4 - 4.3 - API 18 - 768x1280 Build/JLS36G) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "LG", - "model": "Nexus 4", - "type": "mobile" - } - }, - { - "desc": "LG Nexus 5", - "ua": "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", - "expect": { - "vendor": "LG", - "model": "Nexus 5", - "type": "mobile" - } - }, - { - "desc": "LG Wing", - "ua": "Mozilla/5.0 (Linux; Android 10; LM-F100N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-F100N", - "type": "mobile" - } - }, - { - "desc": "LG Smart TV", - "ua": "Mozilla/5.0 (DirectFB; U; Linux mips; en) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) LG Browser (; LG NetCast.TV-2011)", - "expect": { - "vendor": "LG", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "LG Smart TV", - "ua": "Mozilla/5.0 (Linux; NetCast; U) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/53.0.2785 34 Safari/537.31 SmartTV/8.5", - "expect": { - "vendor": "LG", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "LG Android TV", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; LG Android TV Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", - "expect": { - "vendor": "LG", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "Loewe Smart TV", - "ua": "Mozilla/5.0 (Linux; U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2207.0 LOEWE-SL410/5.2.0.0 HbbTV/1.4.1 (; LOEWE; SL410; LOH/5.2.0.0;;) FVC/3.0 (LOEWE; SL410;) CE-HTML/1.0 Config (L:deu,CC:DEU) NETRANGEMMH", - "expect": { - "vendor": "LOEWE", - "model": "SL410", - "type": "smarttv" - } - }, - { - "desc": "Meizu M5 Note", - "ua": "Mozilla/5.0 (Linux; Android 6.0; M5 Note Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043024 Safari/537.36 MicroMessenger/6.5.7.1040 NetType/WIFI Language/zh_CN", - "expect": { - "vendor": "Meizu", - "model": "M5 Note", - "type": "mobile" - } - }, - { - "desc": "Micromax Bharat 2 Plus", - "ua": "Mozilla/5.0 (Linux; U; Android 7.0; en-US; Micromax Q402Plus Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.12.9.1226 Mobile Safari/537.36", - "expect": { - "vendor": "Micromax", - "model": "Q402Plus", - "type": "mobile" - } - }, - { - "desc": "Micromax Canvas Infinity", - "ua": "Mozilla/5.0 (Linux; U; Android 7.1.2; en-US; Micromax HS2 Build/N2G47H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/13.2.0.1296 (SpeedMode) U4/1.0 UCWEB/2.0 Mobile Safari/534.30", - "expect": { - "vendor": "Micromax", - "model": "HS2", - "type": "mobile" - } - }, - { - "desc": "Micromax In 1b", - "ua": "Mozilla/5.0 (Linux; U; Android 10; Micromax E7533 Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36 OPR/54.0.2254.56148", - "expect": { - "vendor": "Micromax", - "model": "E7533", - "type": "mobile" - } - }, - { - "desc": "Microsoft Lumia 950", - "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", - "expect": { - "vendor": "Microsoft", - "model": "Lumia 950", - "type": "mobile" - } - }, - { - "desc": "Microsoft Surface Duo", - "ua": "Dalvik/2.1.0 (Linux; U; Android 10; Surface Duo Build/2020.1014.61)", - "expect": { - "vendor": "Microsoft", - "model": "Surface Duo", - "type": "tablet" - } - }, - { - "desc": "Motorola Moto X", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; XT1097 Build/KXE21.187-38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.109 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "XT1097", - "type": "mobile" - } - }, - { - "desc": "Motorola Moto Z3 Play", - "ua": "Mozilla/5.0 (Linux; Android 9; Moto Z3 Play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "Moto Z3 Play", - "type": "mobile" - } - }, - { - "desc": "Meizu M3S", - "ua": "Mozilla/5.0 (X11; Linux; Android 5.1; MZ-M3s Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrom/45.0.2454.94 Mobile Safari/537.36", - "expect": { - "vendor": "Meizu", - "model": "M3s", - "type": "mobile" - } - }, - { - "desc": "Microsoft Lumia 950", - "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", - "expect": { - "vendor": "Microsoft", - "model": "Lumia 950", - "type": "mobile" - } - }, - { - "desc": "Motorola Nexus 6", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.20 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "Nexus 6", - "type": "mobile" - } - }, - { - "desc": "Motorola Droid RAZR 4G", - "ua": "Mozilla/5.0 (Linux; U; Android 2.3; xx-xx; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", - "expect": { - "vendor": "Motorola", - "model": "DROID RAZR 4G", - "type": "mobile" - } - }, - { - "desc": "Motorola RAZR 2019", - "ua": "Mozilla/5.0 (Linux; Android 9; motorola razr) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.1 Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "razr", - "type": "mobile" - } - }, - { - "desc": "iPhone", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPhone SE", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPhone SE using Facebook App", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPhone 11 Pro Max", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone12,5;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPhone XS", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone11,2;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPod touch", - "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53", - "expect": { - "vendor": "Apple", - "model": "iPod touch", - "type": "mobile" - } - }, - { - "desc": "itel A25", - "ua": "Mozilla/5.0 (Linux; Android 9; itel L5002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.130 Mobile Safari/537.36 OPR/63.3.3216.58675", - "expect": { - "vendor": "itel", - "model": "L5002", - "type": "mobile" - } - }, - { - "desc": "itel A50", - "ua": "Mozilla/5.0 (Linux; U; Android 14; itel A667L Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Mobile Safari/537.36 OPR/83.1.2254.73239", - "expect": { - "vendor": "itel", - "model": "A667L", - "type": "mobile" - } - }, - { - "desc": "itel KidPad 1", - "ua": "Mozilla/5.0 (Linux; Android 10; Itel W7001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", - "expect": { - "vendor": "itel", - "model": "W7001", - "type": "tablet" - } - }, - { - "desc": "itel Pad One", - "ua": "Mozilla/5.0 (Linux; Android 12; itel P10001L Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.172 Safari/537.36", - "expect": { - "vendor": "itel", - "model": "P10001L", - "type": "tablet" - } - }, - { - "desc": "itel RS4", - "ua": "Mozilla/5.0 (Linux; Android 13; itel S666LN Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.165 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/468.1.0.56.78;]", - "expect": { - "vendor": "itel", - "model": "S666LN", - "type": "mobile" - } - }, - { - "desc": "itel Vision 2S", - "ua": "Mozilla/5.0 (Linux; Android 11; itel P651L Build/RP1A.201005.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.76 Mobile Safari/537.36", - "expect": { - "vendor": "itel", - "model": "P651L", - "type": "mobile" - } - }, - { - "desc": "Moto X", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2; xx-xx; XT1058 Build/13.9.0Q2.X-70-GHOST-ATT_LE-2) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Motorola", - "model": "XT1058", - "type": "mobile" - } - }, - { - "desc": "Motorola Moto g(6) Play", - "ua": "Mozilla/5.0 (Linux; Android 9; moto g(6) play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "moto g(6) play", - "type": "mobile" - } - }, - { - "desc": "Motorola Moto g(7) Supra", - "ua": "Mozilla/5.0 (Linux; Android 9; moto g(7) supra Build/PCOS29.114-134-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/73.0.3683.90 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "moto g(7) supra", - "type": "mobile" - } - }, - { - "desc": "Motorola Moto E", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Moto E (4) Build/NDQS26.69-64-11-7; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "Moto E (4)", - "type": "mobile" - } - }, - { - "desc": "Nokia3xx", - "ua": "Nokia303/14.87 CLDC-1.1", - "expect": { - "vendor": "Nokia", - "model": "303", - "type": "mobile" - } - }, - { - "desc": "Nokia 3.2", - "ua": "Mozilla/5.0 (Linux; Android 10; Nokia 3.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36", - "expect": { - "vendor": "Nokia", - "model": "3.2", - "type": "mobile" - } - }, - { - "desc": "Nokia 7", - "ua": "Mozilla/5.0 (Linux; Android 11; Nokia 7.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Nokia", - "model": "7.2", - "type": "mobile" - } - }, - { - "desc": "Nokia N9", - "ua": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", - "expect": { - "vendor": "Nokia", - "model": "N9", - "type": "mobile" - } - }, - { - "desc": "Nokia T20", - "ua": "Mozilla/5.0 (Linux; Android 12; Nokia T20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", - "expect": { - "vendor": "Nokia", - "model": "T20", - "type": "tablet" - } - }, - { - "desc": "Nokia T20", - "ua": "Mozilla/5.0 (Linux; Android 11; Nokia T20 Build/RP1A.201005.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/93.0.4577.62 Safari/537.36", - "expect": { - "vendor": "Nokia", - "model": "T20", - "type": "tablet" - } - }, - { - "desc": "Nokia T21", - "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Nokia T21 Build/TP1A.220624.014)", - "expect": { - "vendor": "Nokia", - "model": "T21", - "type": "tablet" - } - }, - { - "desc": "Nokia 2720 Flip", - "ua": "Mozilla/5.0 (Mobile; Nokia_2720_Flip; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.2", - "expect": { - "vendor": "Nokia", - "model": "2720 Flip", - "type": "mobile" - } - }, - { - "desc": "Nothing 1", - "ua": "Mozilla/5.0 (Linux; Android 13; A063) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36", - "expect": { - "vendor": "Nothing", - "model": "A063", - "type": "mobile" - } - }, - { - "desc": "Nothing 2", - "ua": "Mozilla/5.0 (Linux; Android 14; A065 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.53 Mobile Safari/537.36", - "expect": { - "vendor": "Nothing", - "model": "A065", - "type": "mobile" - } - }, - { - "desc": "Nothing 2a", - "ua": "Mozilla/5.0 (Linux; Android 14; A142 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.71 Mobile Safari/537.36", - "expect": { - "vendor": "Nothing", - "model": "A142", - "type": "mobile" - } - }, - { - "desc": "Oculus Quest", - "ua": "Mozilla/5.0 (Linux; Android 10; Quest) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", - "expect": { - "vendor": "Facebook", - "model": "Quest", - "type": "xr" - } - }, - { - "desc": "Oculus Quest 2", - "ua": "Mozilla/5.0 (Linux; Android 10; Quest 2) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", - "expect": { - "vendor": "Facebook", - "model": "Quest 2", - "type": "xr" - } - }, - { - "desc": "Oculus Quest 3", - "ua": "Mozilla/5.0 (X11; Linux x86_64; Quest 3) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/31.4.0.6.51.566757996 Chrome/120.0.6099.283 VR Safari/537.36", - "expect": { - "vendor": "Facebook", - "model": "Quest 3", - "type": "xr" - } - }, - { - "desc": "Oculus Quest Pro", - "ua": "Mozilla/5.0 (X11; Linux x86_64; Quest Pro) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/24.4.0.22.60.426469926 SamsungBrowser/4.0 Chrome/106.0.5249.181 VR Safari/537.36", - "expect": { - "vendor": "Facebook", - "model": "Quest Pro", - "type": "xr" - } - }, - { - "desc": "Issue #747", - "ua": "python-requests/2.25.1", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "undefined" - } - }, - { - "desc": "OnePlus One", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A0001", - "type": "mobile" - } - }, - { - "desc": "OnePlus One", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; OnePlus One A0001 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A0001", - "type": "mobile" - } - }, - { - "desc": "OnePlus 2", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ONE A2003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A2003", - "type": "mobile" - } - }, - { - "desc": "OnePlus 3", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ONEPLUS A3000 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A3000", - "type": "mobile" - } - }, - { - "desc": "OnePlus 6", - "ua": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A6003", - "type": "mobile" - } - }, - { - "desc": "OnePlus 6T", - "ua": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6010) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A6010", - "type": "mobile" - } - }, - { - "desc": "OnePlus 7T Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; HD1913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36 EdgA/110.0.1587.66", - "expect": { - "vendor": "undefined", - "model": "HD1913", - "type": "mobile" - } - }, - { - "desc": "OnePlus 8T", - "ua": "Mozilla/5.0 (Linux; Android 11; KB2005) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "KB2005", - "type": "mobile" - } - }, - { - "desc": "OnePlus 8 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; IN2025) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.119 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "IN2025", - "type": "mobile" - } - }, - { - "desc": "OnePlus 10RT", - "ua": "Mozilla/5.0 (Linux; Android 13; CPH2413) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "CPH2413", - "type": "mobile" - } - }, - { - "desc": "OnePlus Nord N100", - "ua": "Mozilla/5.0 (Linux; Android 10; BE2015 Build/QKQ1.200719.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "BE2015", - "type": "mobile" - } - }, - { - "desc": "OnePlus Nord N10 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; BE2029) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "BE2029", - "type": "mobile" - } - }, - { - "desc": "OnePlus Pad Go 11.35", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 14; OPD2304) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.629 YaApp_Android/24.101/apad YaSearchBrowser/24.101/apad BroPP/1.0 SA/3 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "OPD2304", - "type": "tablet" - } - }, - { - "desc": "OnePlus Pad 2 12.1 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 14; OPD2403 Build/UKQ1.231108.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "OPD2403", - "type": "tablet" - } - }, - { - "desc": "OnePlus Pad 11.61 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 14; OPD2203 Build/UKQ1.230924.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "OPD2203", - "type": "tablet" - } - }, - { - "desc": "OPPO Pad", - "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; OPD2101 Build/TP1A.220905.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "OPD2101", - "type": "tablet" - } - }, - { - "desc": "OPPO Neo", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; R831T Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 OppoBrowser/3.3.2 Mobile Safari/534.30", - "expect": { - "vendor": "OPPO", - "model": "R831T", - "type": "mobile" - } - }, - { - "desc": "OPPO R7s", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; OPPO R7s Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/7.1 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "R7s", - "type": "mobile" - } - }, - { - "desc": "OPPO A3s", - "ua": "Mozilla/5.0 (Linux; Android 8.1; CPH1803 Build/OPM1.171019.026; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "CPH1803", - "type": "mobile" - } - }, - { - "desc": "OPPO A12", - "ua": "Mozilla/5.0 (Linux; Android 9; CPH2083) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "CPH2083", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno", - "ua": "Mozilla/5.0 (Linux; Android 9; PCAT00 Build/PKQ1.190101.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PCAT00", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno3 Pro 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; PCLM50) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.117 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PCLM50", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno4 SE", - "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PEAM00 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PEAM00", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno4 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; PDPM00 Build/QKQ1.200216.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PDPM00", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno4 Pro 5G", - "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PDNT00 Build/QKQ1.200216.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PDNT00", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno5 A", - "ua": "Mozilla/5.0 (Linux; Android 11; A101OP) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "A101OP", - "type": "mobile" - } - }, - { - "desc": "OPPO Find X", - "ua": "Mozilla/5.0 (Linux; Android 8.1; PAFM00 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PAFM00", - "type": "mobile" - } - }, - { - "desc": "OPPO Find 7a", - "ua": "Mozilla/5.0 (Linux; U; Android 4.3; xx-xx; X9007 Build/JLS36C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "OPPO", - "model": "X9007", - "type": "mobile" - } - }, - { - "desc": "OPPO F5", - "ua": "ozilla/5.0 (Linux; Android 7.1.1; CPH1723) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "CPH1723", - "type": "mobile" - } - }, - { - "desc": "Realme C1", - "ua": "Mozilla/5.0 (Linux; Android 8.1; RMX1811 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX1811", - "type": "mobile" - } - }, - { - "desc": "Realme C2", - "ua": "Mozilla/5.0 (Linux; Android 9; RMX1941) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX1941", - "type": "mobile" - } - }, - { - "desc": "Realme Narzo 20", - "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; RMX2193 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX2193", - "type": "mobile" - } - }, - { - "desc": "Realme 2 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; RMX1801) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX1801", - "type": "mobile" - } - }, - { - "desc": "Realme 3 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; RMX1851) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX1851", - "type": "mobile" - } - }, - { - "desc": "Realme 8", - "ua": "Mozilla/5.0 (Linux; Android 12; RMX3085) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX3085", - "type": "mobile" - } - }, - { - "desc": "Realme 9 Pro", - "ua": "Mozilla/5.0 (Linux; Android 13; RMX3471) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX3471", - "type": "mobile" - } - }, - { - "desc": "Realme GT Master", - "ua": "Mozilla/5.0 (Linux; Android 13; RMX3363) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX3363", - "type": "mobile" - } - }, - { - "desc": "Panasonic T31", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Panasonic T31 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.170 Mobile Safari/537.36 ", - "expect": { - "vendor": "Panasonic", - "model": "T31", - "type": "mobile" - } - }, - { - "desc": "Panasonic TX-32CSW514 SmartTV", - "ua": "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", - "expect": { - "vendor": "Panasonic", - "model": "VIERA 2015", - "type": "smarttv" - } - }, - { - "desc": "Panasonic TX-40FXW724 SmartTV", - "ua": "HbbTV/1.4.1 (+DRM;Panasonic;SmartTV2018mid;3.024;4301-0003 0002-0000;SmartTV2018;)", - "expect": { - "vendor": "Panasonic", - "model": "SmartTV2018mid", - "type": "smarttv" - } - }, - { - "desc": "Panasonic TX-43HXW904 SmartTV", - "ua": "HbbTV/1.5.1 (+DRM;Panasonic;SmartTV2020mid;3.326;4301-0003 0008-0000;com.panasonic.SmartTV2020mid;)", - "expect": { - "vendor": "Panasonic", - "model": "SmartTV2020mid", - "type": "smarttv" - } - }, - { - "desc": "Panasonic DMR-HST130 SAT receiver", - "ua": "HbbTV/1.1.1 (+PVR;Panasonic;DIGA WebKit M8658;3.420;;)", - "expect": { - "vendor": "Panasonic", - "model": "DIGA WebKit M8658", - "type": "smarttv" - } - }, - { - "desc": "Philips SmartTV", - "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", - "expect": { - "vendor": "Philips", - "model": "", - "type": "smarttv" - } - }, - { - "desc": "Philips 32PFL6606K/02 SmartTV (2011)", - "ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70", - "expect": { - "vendor": "Philips", - "model": "", - "type": "smarttv" - } - }, - { - "desc": "Philips 32PFL6606K/02 SmartTV (2013)", - "ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70", - "expect": { - "vendor": "Philips", - "model": "", - "type": "smarttv" - } - }, - { - "desc": "Philips 32PHS5301/12 SmartTV (2016)", - "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 OPR/29.0.1803.0 OMI/4.5.23.37.MOT2.13 HbbTV/1.2.1 (;Philips;32PHS5301/12;;_TV_MT5800;) Firmware/TPM161E_012.002.045.001 en", - "expect": { - "vendor": "Philips", - "model": "32PHS5301/12", - "type": "smarttv" - } - }, - { - "desc": "Pico 4", - "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.8.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.38 Chrome/105.0.5195.68 VR Safari/537.36", - "expect": { - "vendor": "PICO", - "model": "4", - "type": "xr" - } - }, - { - "desc": "Pico 4", - "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0", - "expect": { - "vendor": "PICO", - "model": "4", - "type": "xr" - } - }, - { - "desc": "Pico Neo3 Link", - "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", - "expect": { - "vendor": "Pico", - "model": "Neo3 Link", - "type": "xr" - } - }, - { - "desc": "Polytron Prime 7 Pro", - "ua": "Mozilla/5.0 (Linux; U; Android 7.0; POLYTRON_P552 Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/64.0.3282.137 Mobile Safari/537.36 OPR/50.0.2254.149182", - "expect": { - "vendor": "POLYTRON", - "model": "P552", - "type": "mobile" - } - }, - { - "desc": "Polytron Rocket T1", - "ua": "Mozilla/5.0 (Linux; U; Android 5.0; en-US; POLYTRON R2501 Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/13.1.2.1293 Mobile Safari/537.36", - "expect": { - "vendor": "POLYTRON", - "model": "R2501", - "type": "mobile" - } - }, - { - "desc": "Polytron Rocket T6", - "ua": "Mozilla/5.0 (Linux; Android 7.0; POLYTRON R2509) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.92 Mobile Safari/537.36", - "expect": { - "vendor": "POLYTRON", - "model": "R2509", - "type": "mobile" - } - }, - { - "desc": "Polytron Zap 6 Posh", - "ua": "Mozilla/5.0 (Linux; U; Android 5.1; in-ID; POLYTRON_4G501 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.10.0.1163 UCTurbo/1.9.9.900 Mobile Safari/537.36", - "expect": { - "vendor": "POLYTRON", - "model": "4G501", - "type": "mobile" - } - }, - { - "desc": "Roku", - "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", - "expect": { - "vendor": "Roku", - "model": "", - "type": "smarttv" - } - }, - { - "desc": "Roku", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Roku/DVP-8.10 (468.10E04145A)", - "expect": { - "vendor": "Roku", - "model": "DVP-8.10", - "type": "smarttv" - } - }, - { - "desc": "Roku", - "ua": "Roku4640X/DVP-7.70 (297.70E04154A)", - "expect": { - "vendor": "Roku", - "model": "DVP-7.70", - "type": "smarttv" - } - }, - { - "desc": "Xiaomi TV", - "ua": "Mozilla/5.0 (Linux; Android 10; MiTV-MOOQ0 Build/QTG3.200305.006; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.61 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MiTV-MOOQ0", - "type": "smarttv" - } - }, - { - "desc": "Kindle Fire HD", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", - "expect": { - "vendor": "Amazon", - "model": "KFTT", - "type": "tablet" - } - }, - { - "desc": "Kindle Fire HD", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", - "expect": { - "vendor": "Amazon", - "model": "KFTT", - "type": "tablet" - } - }, - { - "desc": "Echo Show 5", - "ua": "Mozilla/5.0 (Linux; Android 5.1; AEORK Build/LVY48F; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "AEORK", - "type": "tablet" - } - }, - { - "desc": "Echo Show 8", - "ua": "Mozilla/5.0 (Linux; Android 7.1; AEOCH) AppleWebKit/537.36 (KHTML, like Gecko) Silk/77.2.21 like Chrome/77.0.3865.92 Mobile Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "AEOCH", - "type": "tablet" - } - }, - { - "desc": "Echo Show 8", - "ua": "Mozilla/5.0 (Linux; Android 7.1.2; AEOCW) AppleWebKit/537.36 (KHTML, like Gecko) Silk/106.3.3 like Chrome/106.0.5249.170 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "AEOCW", - "type": "tablet" - } - }, - { - "desc": "Echo Show 15", - "ua": "Mozilla/5.0 (Linux; Android 9; AEOHY) AppleWebKit/537.36 (KHTML, like Gecko) Silk/112.6.3 like Chrome/112.0.5615.213 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "AEOHY", - "type": "tablet" - } - }, - { - "desc": "Echo Dot", - "ua": "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AEOBC Build/LVY48F)", - "expect": { - "vendor": "Amazon", - "model": "AEOBC", - "type": "embedded" - } - }, - { - "desc": "Samsung Galaxy A21s", - "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-A217F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.0 Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A217F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A31", - "ua": "Mozilla/5.0 (Linux; Android 10; SM-A315G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A315G", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A50", - "ua": "Mozilla/5.0 (Linux; Android 9; SM-A505F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.105 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A505F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A50s", - "ua": "Mozilla/5.0 (Linux; Android 11; SM-A507FN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A507FN", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A52s", - "ua": "Mozilla/5.0 (Linux; Android 13; SM-A528B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A528B", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A80", - "ua": "Mozilla/5.0 (Linux; Android 9; SM-A805F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.112 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A805F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Fold", - "ua": "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-F900U Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.2 Chrome/67.0.3396.87 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-F900U", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Z Flip", - "ua": "Mozilla/5.0 (Linux; Android 10; SM-F700N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-F700N", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Z Fold2", - "ua": "Mozilla/5.0 (Linux; Android 10; SM-F916B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-F916B", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S10E", - "ua": "Mozilla/5.0 (Linux; Android 9; SM-G970F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G970F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S20 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; SCG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SCG01", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Note 10+", - "ua": "Mozilla/5.0 (Linux; Android 9; SM-N976V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-N976V", - "type": "mobile" - } - }, - { - "desc": "Samsung SM-C5000", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; SM-C5000 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 wkbrowser 4.1.35 3065", - "expect": { - "vendor": "Samsung", - "model": "SM-C5000", - "type": "mobile" - } - }, - { - "desc": "Samsung C8", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; SM-C7108) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-C7108", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Note 8", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; GT-N5100 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "GT-N5100", - "type": "tablet" - } - }, - { - "desc": "Samsung SM-T231", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T231 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T231", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab 6 Lite", - "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-P610) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/12.0 Chrome/79.0.3945.136 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-P610", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab A 9.7", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; SM-P550 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-P550", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab A 10.1", - "ua": " Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-T515) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/13.0 Chrome/83.0.4103.106 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T515", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab S7", - "ua": "Mozilla/5.0 (Linux; Android 10; SM-T870) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T870", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab S8", - "ua": "Mozilla/5.0 (Linux; Android 12; SM-X706B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-X706B", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab S", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T700 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T700", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab Pro 10.1", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T520 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T520", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Watch", - "ua": "Mozilla/5.0 (Linux; Tizen 5.5; SAMSUNG SM-R805W) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.0 Chrome/69.0.3497.106 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-R805W", - "type": "wearable" - } - }, - { - "desc": "Samsung Galaxy Watch Active 2", - "ua": "Mozilla/5.0 (Linux; Tizen 5.5; SAMSUNG SM-R820) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.0 Chrome/69.0.3497.106 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-R820", - "type": "wearable" - } - }, - { - "desc": "Samsung Galaxy Watch4", - "ua": "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-R875U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.2. Chrome/102.0.5005.125 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-R875U", - "type": "wearable" - } - }, - { - "desc": "Samsung Galaxy Watch5 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-R925U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.2. Chrome/111.0.5563.116 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-R925U", - "type": "wearable" - } - }, - { - "desc": "Samsung Note 10.1", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-P605) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-P605", - "type": "tablet" - } - }, - { - "desc": "Samsung SmartTV2011", - "ua": "HbbTV/1.1.1 (;;;;;) Maple;2011", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2011", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV2012", - "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2012", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV2014", - "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2014;T-NT14UDEUC-1060.4;;) WebKit", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2014", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV", - "ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV", - "ua": "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", - "expect": { - "vendor": "Samsung", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV HBBTV", - "ua": "HbbTV/1.5.1 (+DRM;Samsung;SmartTV2021:UAU7000;T-KSU2EDEUC-1506.0;KantSU2e;urn:samsungtv:familyname:21_KANTSU2E_UHD_BASIC:2021;) Tizen/6.0 (+TVPLUS+SmartHubLink) Chrome/76 LaTivu_1.0.1_2021 RVID/17", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2021:UAU7000", - "type": "smarttv" - } - }, - { - "desc": "Sharp AQUOS-TVX19B", - "ua": "Mozilla/5.0 (Linux; Android 9; AQUOS-TVX19B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "AQUOS-TVX19B", - "type": "smarttv" - } - }, - { - "desc": "Sharp Aquos B10", - "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-A01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SH-A01", - "type": "mobile" - } - }, - { - "desc": "Sharp Aquos L2", - "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02 Build/S4045) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SH-L02", - "type": "mobile" - } - }, - { - "desc": "Sharp Aquos L2", - "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SH-L02", - "type": "mobile" - } - }, - { - "desc": "Sharp Aquos R2", - "ua": "Mozilla/5.0 (Linux; Android 8.0; SHV42) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SHV42", - "type": "mobile" - } - }, - { - "desc": "Smartfren Andromax L", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Andromax B26D2H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Smartfren", - "model": "Andromax B26D2H", - "type": "mobile" - } - }, - { - "desc": "Smartfren Andromax G2", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Smartfren Andromax AD9A1H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.83 Mobile Safari/537.36", - "expect": { - "vendor": "Smartfren", - "model": "Andromax AD9A1H", - "type": "mobile" - } - }, - { - "desc": "Smartfren New Andromax I", - "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; id-id; New Andromax-i Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Smartfren", - "model": "New Andromax-i", - "type": "mobile" - } - }, - { - "desc": "SONY Xperia 1 III", - "ua": "Mozilla/5.0 (Linux; Android 11; A101SO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "A101SO", - "type": "mobile" - } - }, - { - "desc": "Sony G8141 (Xperia XZ1)", - "ua": "Mozilla/5.0 (Linux; Android 9; SO-01K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "SO-01K", - "type": "mobile" - } - }, - { - "desc": "Sony G8141 (Xperia XZ Premium)", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; G8141) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "G8141", - "type": "mobile" - } - }, - { - "desc": "Sony C5303 (Xperia SP)", - "ua": "Mozilla/5.0 (Linux; Android 4.3; C5303 Build/12.1.A.1.205) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.93 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "C5303", - "type": "mobile" - } - }, - { - "desc": "Sony SO-02F (Xperia Z1 F)", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; SO-02F Build/14.1.H.2.119) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "SO-02F", - "type": "mobile" - } - }, - { - "desc": "Sony D6653 (Xperia Z3)", - "ua": "Mozilla/5.0 (Linux; Android 4.4; D6653 Build/23.0.A.0.376) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "D6653", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia SOL25 (ZL2)", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4; SOL25 Build/17.1.1.C.1.64) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Sony", - "model": "SOL25", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia SP", - "ua": "Mozilla/5.0 (Linux; Android 4.3; C5302 Build/12.1.A.1.201) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "C5302", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia L4", - "ua": "Mozilla/5.0 (Linux; Android 9; XQ-AD51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "XQ-AD51", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia 1ii", - "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AT51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "XQ-AT51", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia 1ii", - "ua": "Mozilla/5.0 (Linux; Android 10; SOG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "SOG01", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia 10ii", - "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AU52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "XQ-AU52", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AQ52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "XQ-AQ52", - "type": "mobile" - } - }, - { - "desc": "Sony SGP521 (Xperia Z2 Tablet)", - "ua": "Mozilla/5.0 (Linux; Android 4.4; SGP521 Build/17.1.A.0.432) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" - } - }, - { - "desc": "Sony Xperia Z2 Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SGP561) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" - } - }, - { - "desc": "Sony Tablet S", - "ua": "Mozilla/5.0 (Linux; U; Android 3.1; Sony Tablet S Build/THMAS10000) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13", - "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" - } - }, - { - "desc": "Sony Tablet Z LTE", - "ua": "Mozilla/5.0 (Linux; U; Android 4.1; SonySGP321 Build/10.2.C.0.143) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", - "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" - } - }, - { - "desc": "Sony BRAVIA 4K GB ATV3", - "ua": "Mozilla/5.0 (Linux; Andr0id 9; BRAVIA 4K GB ATV3 Build/PTT1.190515.001.S38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.0.180.DIA5.104 Model/Sony-BRAVIA-4K-GB-ATV3", - "expect": { - "vendor": "Sony", - "model": "BRAVIA 4K GB ATV3", - "type": "smarttv" - } - }, - { - "desc": "Sony BRAVIA 4K GB ATV3", - "ua": "Mozilla/5.0 (Linux; Android 9; BRAVIA 4K GB ATV3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "BRAVIA 4K GB ATV3", - "type": "smarttv" - } - }, - { - "desc": "Sony Bravia 4k UR2", - "ua": "Mozilla/5.0 (Linux: Andr0id 9: BRAVIA 4K UR2 Build/PTT1.190515.001.S104) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.5.431.DIA5HBBTV.250 Model/Sony-BRAVIA-4K-UR2", - "expect": { - "vendor": "Sony", - "model": "BRAVIA 4K UR2", - "type": "smarttv" - } - }, - { - "desc": "TCL 10 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; T790Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 EdgA/114.0.1823.43", - "expect": { - "vendor": "TCL", - "model": "T790Y", - "type": "mobile" - } - }, - { - "desc": "TCL 10 5G UW", - "ua": "Mozilla/5.0 (Linux; Android 10; T790S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T790S", - "type": "mobile" - } - }, - { - "desc": "TCL 10 Plus", - "ua": "Mozilla/5.0 (Linux; Android 11; T782H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Mobile Safari/537.36 OPR/64.3.3282.60839", - "expect": { - "vendor": "TCL", - "model": "T782H", - "type": "mobile" - } - }, - { - "desc": "TCL 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; T799B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T799B", - "type": "mobile" - } - }, - { - "desc": "TCL 10 SE", - "ua": "Mozilla/5.0 (Linux; Android 10; T766H_RU) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T766H", - "type": "mobile" - } - }, - { - "desc": "TCL 10 TabMax", - "ua": "Mozilla/5.0 (Linux; Android 11; 9296Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9296Q", - "type": "tablet" - } - }, - { - "desc": "TCL 10 TabMax 4G", - "ua": "Mozilla/5.0 (Linux; Android 10; 9295G_EEA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9295G", - "type": "tablet" - } - }, - { - "desc": "TCL 10 TabMax WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; 9296G_TR) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9296G", - "type": "tablet" - } - }, - { - "desc": "TCL 10L", - "ua": "Mozilla/5.0 (Linux; Android 10; T770B Build/QKQ1.200329.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 GSA/11.41.10.23.arm64", - "expect": { - "vendor": "TCL", - "model": "T770B", - "type": "mobile" - } - }, - { - "desc": "TCL 10L", - "ua": "Mozilla/5.0 (Linux; Android 11; T770H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T770H", - "type": "mobile" - } - }, - { - "desc": "TCL 20 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; T781) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T781", - "type": "mobile" - } - }, - { - "desc": "TCL 20 Pro 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T810S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Mobile Safari/537.36 EdgA/113.0.1774.63", - "expect": { - "vendor": "TCL", - "model": "T810S", - "type": "mobile" - } - }, - { - "desc": "TCL 20 SE", - "ua": "Mozilla/5.0 (Linux; Android 11; T671H Build/RKQ1.201112.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.73 Mobile Safari/537.36 GoogleApp/13.9.7.23.arm64", - "expect": { - "vendor": "TCL", - "model": "T671H", - "type": "mobile" - } - }, - { - "desc": "TCL 20 XE", - "ua": "Mozilla/5.0 (Linux; Android 11; 5087Z) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "5087Z", - "type": "mobile" - } - }, - { - "desc": "TCL 20B", - "ua": "Mozilla/5.0 (Linux; Android 11; 6159K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "6159K", - "type": "mobile" - } - }, - { - "desc": "TCL 205", - "ua": "Mozilla/5.0 (Linux; Android 11; 4187D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "4187D", - "type": "mobile" - } - }, - { - "desc": "TCL 20E", - "ua": "Mozilla/5.0 (Linux; Android 11; 6125A) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/18.0 Chrome/99.0.4844.88 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "6125A", - "type": "mobile" - } - }, - { - "desc": "TCL 20L", - "ua": "Mozilla/5.0 (Linux; Android 11; T774H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.59 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T774H", - "type": "mobile" - } - }, - { - "desc": "TCL 20L Plus", - "ua": "Mozilla/5.0 (Linux; Android 11; T775H Build/RKQ1.210107.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T775H", - "type": "mobile" - } - }, - { - "desc": "TCL 20R 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; T767H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36 OPR/71.3.3718.67322", - "expect": { - "vendor": "TCL", - "model": "T767H", - "type": "mobile" - } - }, - { - "desc": "TCL 20S", - "ua": "Mozilla/5.0 (Linux; Android 11; T773O) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T773O", - "type": "mobile" - } - }, - { - "desc": "TCL 20Y", - "ua": "Mozilla/5.0 (Linux; Android 11; 6156D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.134 Mobile Safari/537.36 OPR/70.3.3653.66287", - "expect": { - "vendor": "TCL", - "model": "6156D", - "type": "mobile" - } - }, - { - "desc": "TCL 30 V 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; T781S Build/RKQ1.210614.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/369.0.0.5.110;]", - "expect": { - "vendor": "TCL", - "model": "T781S", - "type": "mobile" - } - }, - { - "desc": "TCL 30 XE 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T767W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/416.0.0.35.85;]", - "expect": { - "vendor": "TCL", - "model": "T767W", - "type": "mobile" - } - }, - { - "desc": "TCL 305", - "ua": "Mozilla/5.0 (Linux; arm; Android 11; 6102D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.167 YaBrowser/22.7.6.96.00 SA/3 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "6102D", - "type": "mobile" - } - }, - { - "desc": "TCL 306", - "ua": "Mozilla/5.0 (Linux; Android 12; 6102H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.141 Mobile Safari/537.36[FBAN/EMA;FBLC/it_IT;FBAV/332.0.0.22.108;]", - "expect": { - "vendor": "TCL", - "model": "6102H", - "type": "mobile" - } - }, - { - "desc": "TCL 30", - "ua": "Mozilla/5.0 (Linux; Android 12; T676H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T676H", - "type": "mobile" - } - }, - { - "desc": "TCL 30+", - "ua": "Mozilla/5.0 (Linux; Android 12; T676J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T676J", - "type": "mobile" - } - }, - { - "desc": "TCL 30 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T776H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T776H", - "type": "mobile" - } - }, - { - "desc": "TCL 30 LE", - "ua": "Mozilla/5.0 (Linux; Android 12; 4188V Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/352.0.0.14.108;]", - "expect": { - "vendor": "TCL", - "model": "4188V", - "type": "mobile" - } - }, - { - "desc": "TCL 30 SE", - "ua": "Mozilla/5.0 (Linux; Android 12; 6165H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/396.1.0.28.104;]", - "expect": { - "vendor": "TCL", - "model": "6165H", - "type": "mobile" - } - }, - { - "desc": "TCL 30E", - "ua": "Mozilla/5.0 (Linux; Android 12; 6127I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "6127I", - "type": "mobile" - } - }, - { - "desc": "TCL 40 NxtPaper", - "ua": "Mozilla/5.0 (Linux; Android 13; T612B Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.53 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T612B", - "type": "mobile" - } - }, - { - "desc": "TCL A3", - "ua": "Mozilla/5.0 (Linux; Android 11; A509DL Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Mobile Safari/537.36 GSA/13.18.7.23.arm64", - "expect": { - "vendor": "TCL", - "model": "A509DL", - "type": "mobile" - } - }, - { - "desc": "TCL A30", - "ua": "Mozilla/5.0 (Linux; Android 11; 5102L Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/413.0.0.30.104;]", - "expect": { - "vendor": "TCL", - "model": "5102L", - "type": "mobile" - } - }, - { - "desc": "TCL 40 SE", - "ua": "Mozilla/5.0 (Linux; Android 13; T610K Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T610K", - "type": "mobile" - } - }, - { - "desc": "TCL 40 XE 5G", - "ua": "Mozilla/5.0 (Linux; Android 13; T609DL Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.136 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/466.1.0.57.85;]", - "expect": { - "vendor": "TCL", - "model": "T609DL", - "type": "mobile" - } - }, - { - "desc": "TCL 403", - "ua": "Mozilla/5.0 (Linux; Android 12; T431D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T431D", - "type": "mobile" - } - }, - { - "desc": "TCL 405", - "ua": "Mozilla/5.0 (Linux; Android 12; T506D Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]", - "expect": { - "vendor": "TCL", - "model": "T506D", - "type": "mobile" - } - }, - { - "desc": "TCL 408", - "ua": "Mozilla/5.0 (Linux; U; Android 12; T507U Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/105.0.5195.136 Mobile Safari/537.36 OPR/75.0.2254.68857", - "expect": { - "vendor": "TCL", - "model": "T507U", - "type": "mobile" - } - }, - { - "desc": "TCL 40R 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T771K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 EdgA/114.0.1823.37", - "expect": { - "vendor": "TCL", - "model": "T771K", - "type": "mobile" - } - }, - { - "desc": "TCL Ion X", - "ua": "Mozilla/5.0 (Linux; Android 12; T430W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.60 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T430W", - "type": "mobile" - } - }, - { - "desc": "TCL NxtPaper 11", - "ua": "Mozilla/5.0 (Linux; Android 13; 9466X Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.179 Safari/537.36 [FB_IAB/FB4A;FBAV/473.0.0.41.81;]", - "expect": { - "vendor": "TCL", - "model": "9466X", - "type": "tablet" - } - }, - { - "desc": "TCL Stylus 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T779W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.2 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T779W", - "type": "mobile" - } - }, - { - "desc": "TCL Tab 8 4G", - "ua": "Mozilla/5.0 (Linux; Android 10; 9048S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9048S", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 8 LE", - "ua": "Mozilla/5.0 (Linux; Android 12; 9137W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9137W", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10 FHD 4G", - "ua": "Mozilla/5.0 (Linux; Android 11; 9060G Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.196 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9060G", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10 HD 4G", - "ua": "Mozilla/5.0 (Linux; Android 11; 9060X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9060X", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10 LTE", - "ua": "Mozilla/5.0 (Linux; Android 13; 8196G Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.162 Safari/537.36 [FB_IAB/FB4A;FBAV/471.0.0.35.80;]", - "expect": { - "vendor": "TCL", - "model": "8196G", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 13; 8496G Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.61 Safari/537.36 [FB_IAB/FB4A;FBAV/474.0.0.52.74;]", - "expect": { - "vendor": "TCL", - "model": "8496G", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10L", - "ua": "Mozilla/5.0 (Linux; Android 11; 8491X_EEA Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.105 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "8491X", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10s 4G", - "ua": "Mozilla/5.0 (Linux; Android 11; 9080G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9080G", - "type": "tablet" - } - }, - { - "desc": "TCL Xess P17AA", - "ua": "Mozilla/5.0 (Linux; Android 5.1; TCL Xess P17AA Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "Xess P17AA", - "type": "tablet" - } - }, - { - "desc": "Tecno KC8", - "ua": "Mozilla/5.0 (Linux; Android 10; TECNO KC8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TECNO", - "model": "KC8", - "type": "mobile" - } - }, - { - "desc": "Tecno Spark 8C", - "ua": "Mozilla/5.0 (Linux; Android 11; TECNO KG5n) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TECNO", - "model": "KG5n", - "type": "mobile" - } - }, - { - "desc": "Tesla", - "ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", - "expect": { - "vendor": "Tesla", - "model": "undefined", - "type": "embedded" - } - }, - { - "desc": "Tesla", - "ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/79.0.3945.130 Chrome/79.0.3945.130 Safari/537.36 Tesla/2020.16.2.1-e99c70fff409", - "expect": { - "vendor": "Tesla", - "model": "undefined", - "type": "embedded" - } - }, - { - "desc": "TechniSAT Digit ISIO S SAT receiver", - "ua": "Opera/9.80 (Linux sh4; U; HbbTV/1.1.1 (;;;;;); CE-HTML; TechniSat Digit ISIO S; de) Presto/2.9.167 Version/11.50", - "expect": { - "vendor": "TechniSat", - "model": "Digit ISIO S", - "type": "smarttv" - } - }, - { - "desc": "TechniSAT MultyVision SmartTV", - "ua": "Opera/9.80 (Linux i686; U; HbbTV/1.1.1 (;;;;;); CE-HTML; TechniSat MultyVision ISIO; de) Presto/2.9.167 Version/11.50", - "expect": { - "vendor": "TechniSat", - "model": "MultyVision ISIO", - "type": "smarttv" - } - }, - { - "desc": "Ulefone Armor", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Armor Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.107 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Armor", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 6.0; Armor) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 YaBrowser/20.4.2.101.00 SA/1 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Armor", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor 8 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; Armor 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.1.3922.71199", - "expect": { - "vendor": "Ulefone", - "model": "Armor 8 Pro", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor 12 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; Armor 12 5G Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Armor 12 5G", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor 20WT", - "ua": "Mozilla/5.0 (Linux; Android 12; Armor 20WT) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Armor 20WT", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor Pad", - "ua": "Mozilla/5.0 (Linux; Android 12; Armor Pad Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/431.0.0.30.108;]", - "expect": { - "vendor": "Ulefone", - "model": "Armor Pad", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor X5 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; Armor X5 Pro Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/430.0.0.23.113;]", - "expect": { - "vendor": "Ulefone", - "model": "Armor X5 Pro", - "type": "mobile" - } - }, - { - "desc": "Ulefone Power Armor 14 Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor14 Pro Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.138 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Power Armor14 Pro", - "type": "mobile" - } - }, - { - "desc": "Ulefone Power Armor 18T", - "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor 18T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Power Armor 18T", - "type": "mobile" - } - }, - { - "desc": "Ulefone Power Armor 19T", - "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor 19T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.3.3922.71982", - "expect": { - "vendor": "Ulefone", - "model": "Power Armor 19T", - "type": "mobile" - } - }, - { - "desc": "Xiaomi 2201117TG", - "ua": "Mozilla/5.0 (Linux; Android 11; 2201117TG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.98 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "2201117TG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi M2004J19C", - "ua": "Mozilla/5.0 (Linux; Android 11; M2004J19C Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.77 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2004J19C", - "type": "mobile" - } - }, - { - "desc": "Xiaomi M2006C3MNG", - "ua": "Mozilla/5.0 (Linux; Android 11; M2006C3MNG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2006C3MNG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi 21061119DG", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; 21061119DG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 YaBrowser/23.3.7.24.00 SA/3 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "21061119DG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi 2013023", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; en-US; 2013023 Build/HM2013023) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/10.0.1.512 U3/0.8.0 Mobile Safari/533.1", - "expect": { - "vendor": "Xiaomi", - "model": "2013023", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Hongmi Note 1W", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-CN; HM NOTE 1W Build/JDQ39) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.7.9.439 U3/0.8.0 Mobile Safari/533.1", - "expect": { - "vendor": "Xiaomi", - "model": "HM NOTE 1W", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 3C", - "ua": "Mozilla/5.0 (Linux; U; Android 4.3; zh-CN; MI 3C Build/JLS36C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.7.9.439 U3/0.8.0 Mobile Safari/533.1", - "expect": { - "vendor": "Xiaomi", - "model": "MI 3C", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 5", - "ua": "Mozilla/5.0 (Linux; Android 7.0; MI 5 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.83 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI 5", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 6", - "ua": "Mozilla/5.0 (Linux; Android 7.1; MI 6 Build/NMF26X; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.125 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI 6", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 10 Pro", - "ua": "Linux; U; Android 13; Mi 10 Pro Build/TKQ1.221114.001", - "expect": { - "vendor": "Xiaomi", - "model": "Mi 10 Pro", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 5s Plus", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; MI 5s Plus Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/8.7.1", - "expect": { - "vendor": "Xiaomi", - "model": "MI 5s Plus", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi A1", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Mi A1 Build/OPR1.170623.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi A1", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi Note", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; MI NOTE LTE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI NOTE LTE", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi One Plus", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; MI-ONE Plus Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Xiaomi", - "model": "MI-ONE Plus", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi Max 3", - "ua": "Mozilla/5.0 (Linux; Android 9; MI MAX 3 Build/PKQ1.181007.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI MAX 3", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi A1", - "ua": "Mozilla/5.0 (Linux; Android 9; Mi A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.101 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi A1", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi A2 Lite", - "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2 Lite) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi A2 Lite", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 9 SE", - "ua": "Mozilla/5.0 (Linux; Android 9; Mi 9 SE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi 9 SE", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi A2", - "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi A2", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi CC9", - "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-cn; MI CC 9 Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.116 Mobile Safari/537.36 XiaoMi/MiuiBrowser/15.5.18", - "expect": { - "vendor": "Xiaomi", - "model": "MI CC 9", - "type": "mobile" - } - }, - { - "desc": "Xiaomi MI PAD", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; en-us; MI PAD Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.3.2", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD", - "type": "tablet" - } - }, - { - "desc": "Xiaomi MI PAD 2", - "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD 2", - "type": "tablet" - } - }, - { - "desc": "Xiaomi MI PAD 2", - "ua": "Mozilla/5.0 (Linux; x86_64; Android 5.1; MI PAD 2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 YaBrowser/20.11.2.69.01 Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD 2", - "type": "tablet" - } - }, - { - "desc": "Xiaomi MI PAD 3", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.0; MI PAD 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.216 YaBrowser/21.5.6.56.01 Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD 3", - "type": "tablet" - } - }, - { - "desc": "Xiaomi MI PAD 4", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 8.1.0; MI PAD 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 YaBrowser/19.9.1.126.01 Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD 4", - "type": "tablet" - } - }, - { - "desc": "Xiaomi MI PAD 4 PLUS", - "ua": "Mozilla/5.0 (Linux; Android 8.1; MI PAD 4 PLUS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD 4 PLUS", - "type": "tablet" - } - }, - { - "desc": "Xiaomi MI PAD 4 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 8.1; Mi Pad4 Wi-Fi) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Mobile Safari/537.36 EdgA/86.0.622.61", - "expect": { - "vendor": "Xiaomi", - "model": "Mi Pad4 Wi-Fi", - "type": "tablet" - } - }, - { - "desc": "Xiaomi Mi Pad 5", - "ua": "Mozilla/5.0 (Linux; Android 13; 21051182G Build/TKQ1.221013.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", - "expect": { - "vendor": "Xiaomi", - "model": "21051182G", - "type": "tablet" - } - }, - { - "desc": "Xiaomi Mi Pad 5 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; M2105K81AC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Safari/537.36 Line/13.15.1/IAB", - "expect": { - "vendor": "Xiaomi", - "model": "M2105K81AC", - "type": "tablet" - } - }, - { - "desc": "Xiaomi Mi Pad 5 Pro 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; M2105K81C) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2105K81C", - "type": "tablet" - } - }, - { - "desc": "Xiaomi Mi Pad 6 Max 14", - "ua": "Mozilla/5.0 (Linux; U; Android 14; zh-tw; 2307BRPDCC Build/UKQ1.230804.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.118 Mobile Safari/537.36 Device/yudi Model/2307BRPDCC XiaoMi/MiuiBrowser/14.10.6", - "expect": { - "vendor": "Xiaomi", - "model": "2307BRPDCC", - "type": "tablet" - } - }, - { - "desc": "Xiaomi Mi Pad 6 Pro", - "ua": "Mozilla/5.0 (Linux; U; Android 13; en-US; 23046RP50C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.6.2.1316 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "23046RP50C", - "type": "tablet" - } - }, - { - "desc": "Xiaomi Pad 6S Pro 12.4", - "ua": "Mozilla/5.0 (Linux; Android 14; 24018RPACC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "24018RPACC", - "type": "tablet" - } - }, - { - "desc": "Xiaomi POCO X2", - "ua": "Mozilla/5.0 (Linux; Android 10; POCO X2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "POCO X2", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO X3 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; M2102J20SI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2102J20SI", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO X3 Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; M2102J20SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2102J20SG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO X3 NFC", - "ua": "Mozilla/5.0 (Linux; Android 12; M2007J20CG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2007J20CG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO M2 Pro", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; POCO M2 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 YaBrowser/22.11.7.42.00 SA/3 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "POCO M2 Pro", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO M3", - "ua": "Mozilla/5.0 (Linux; Android 10; M2010J19CI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2010J19CI", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCOPHONE F1", - "ua": "Mozilla/5.0 (Linux; Android 10; POCOPHONE F1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "POCOPHONE F1", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi 4A", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Redmi 4A Build/MMB29M; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi 4A", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi 10C", - "ua": "Mozilla/5.0 (Linux; Android 12; 220333QAG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "220333QAG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi K30 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 5G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi K30 5G", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi K30 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi K30 Pro", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi Note 3", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Redmi Note 3 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.116 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 3", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi Note 9 Pro Max", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9 Pro Max) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.99 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 9 Pro Max", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 9S", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 9S", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 10 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; M2103K19C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2103K19C", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 13; M2101K6P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2101K6P", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; M2101K6G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2101K6G", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 8", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 8", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 12 Turbo", - "ua": "Mozilla/5.0 (Linux; Android 13; 23049RAD8C; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/16.7.1.1", - "expect": { - "vendor": "Xiaomi", - "model": "23049RAD8C", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Pad", - "ua": "Mozilla/5.0 (Linux; U; Android 12; id-id; Redmi Pad Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36 XiaoMi/MiuiBrowser/14.1.1-gn", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Pad", - "type": "tablet" - } - }, - { - "desc": "XiaoMi Redmi Pad", - "ua": "Mozilla/5.0 (Linux; Android 14; 22081283G Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", - "expect": { - "vendor": "Xiaomi", - "model": "22081283G", - "type": "tablet" - } - }, - { - "desc": "XiaoMi Redmi Pad Pro", - "ua": "Mozilla/5.0 (Linux; Android 14; 2405CRPFDG Build/UKQ1.240116.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.97 Safari/537.36 [FB_IAB/FB4A;FBAV/476.0.0.49.74;] FBNV/1", - "expect": { - "vendor": "Xiaomi", - "model": "2405CRPFDG", - "type": "tablet" - } - }, - { - "desc": "XiaoMi Redmi Pad SE", - "ua": "Dalvik/2.1.0 (Linux; U; Android 14; 23073RPBFG Build/UKQ1.231003.002)", - "expect": { - "vendor": "Xiaomi", - "model": "23073RPBFG", - "type": "tablet" - } - }, - { - "desc": "XiaoMi Redmi Pad SE 8.7", - "ua": "Mozilla/5.0 (Linux; Android 14; 24076RP19G Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Mobile Safari/537.36 Line/14.18.1/IAB", - "expect": { - "vendor": "Xiaomi", - "model": "24076RP19G", - "type": "tablet" - } - }, - { - "desc": "ZTE Blade A6", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE BLADE A0620 Build/NMF26F; ru-ru) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.2.0.50586AP", - "expect": { - "vendor": "ZTE", - "model": "BLADE A0620", - "type": "mobile" - } - }, - { - "desc": "PlayStation 4", - "ua": "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", - "expect": { - "vendor": "Sony", - "model": "PlayStation 4", - "type": "console" - } - }, - { - "desc": "PlayStation 5", - "ua": "Mozilla/5.0 (Playstation; Playstation 5/1.05) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15", - "expect": { - "vendor": "Sony", - "model": "Playstation 5", - "type": "console" - } - }, - { - "desc": "PlayStation Vita", - "ua": "Mozilla/5.0 (PlayStation Vita 3.52) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2", - "expect": { - "vendor": "Sony", - "model": "PlayStation Vita", - "type": "console" - } - }, - { - "desc": "Nintendo Switch", - "ua": "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", - "expect": { - "vendor": "Nintendo", - "model": "Switch", - "type": "console" - } - }, - { - "desc": "Nintendo WiiU", - "ua": "Mozilla/5.0 (Nintendo WiiU) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.4.2.9 NintendoBrowser/4.2.0.11146.EU", - "expect": { - "vendor": "Nintendo", - "model": "WiiU", - "type": "console" - } - }, - { - "desc": "Nintendo Wii", - "ua": "Opera/9.10 (Nintendo Wii; U; ; 1621; en)", - "expect": { - "vendor": "Nintendo", - "model": "Wii", - "type": "console" - } - }, - { - "desc": "Nintendo 3DS", - "ua": "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7610.EU", - "expect": { - "vendor": "Nintendo", - "model": "3DS", - "type": "console" - } - }, - { - "desc": "Nintendo 3DS", - "ua": "Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.EU", - "expect": { - "vendor": "Nintendo", - "model": "3DS", - "type": "console" - } - }, - { - "desc": "Galaxy Nexus", - "ua": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", - "expect": { - "vendor": "Samsung", - "model": "Galaxy Nexus", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy C9 Pro", - "ua": "Mozilla/5.0 (Linux; Android 6.0; SAMSUNG SM-C900F Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.2 Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-C900F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S5", - "ua": "Mozilla/5.0 (Linux; Android 5.0; SM-G900F Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.78 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G900F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy J7 Prime", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SM-G610F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G610F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S6", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-G920I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G920I", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S6 Edge", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-G925I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G925I", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Note 5 Chrome", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-N920C Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.91 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-N920C", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Note 5 Samsung Browser", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SAMSUNG SM-N920C Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-N920C", - "type": "mobile" - } - }, - { - "desc": "Google Chromecast with Google TV", - "ua": "Mozilla/5.0 (Linux; Android 12.0; Build/STTL.240206.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.0 Safari/537.36 CrKey/1.56.500000 DeviceType/AndroidTV", - "expect": { - "vendor": "Google", - "model": "Chromecast AndroidTV", - "type": "smarttv" - } - }, - { - "desc": "Google Chromecast Mini Smart Speaker", - "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/SmartSpeaker", - "expect": { - "vendor": "Google", - "model": "Chromecast SmartSpeaker", - "type": "smarttv" - } - }, - { - "desc": "Google Chromecast Third Generation", - "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast", - "expect": { - "vendor": "Google", - "model": "Chromecast Third Generation", - "type": "smarttv" - } - }, - { - "desc": "Google Chromecast Nest Hub", - "ua": "Mozilla/5.0 (Fuchsia) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 CrKey/1.56.500000", - "expect": { - "vendor": "Google", - "model": "Chromecast Nest Hub", - "type": "smarttv" - } - }, - { - "desc": "Google Chromecast", - "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.84 Safari/537.36 CrKey/1.22.79313", - "expect": { - "vendor": "Google", - "model": "Chromecast", - "type": "smarttv" - } - }, - { - "desc": "Google Pixel C", - "ua": "Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel C", - "type": "tablet" - } - }, - { - "desc": "Google Pixel C", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel C", - "type": "tablet" - } - }, - { - "desc": "Google Pixel", - "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel Build/NDE63V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel", - "type": "mobile" - } - }, - { - "desc": "Google Pixel Tablet", - "ua": "Mozilla/5.0 (Linux; Android 14; Pixel Tablet Build/AP2A.240905.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel Tablet", - "type": "tablet" - } - }, - { - "desc": "Google Pixel Watch", - "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Google Pixel Watch Build/TWD4.231005.002)", - "expect": { - "vendor": "Google", - "model": "Pixel Watch", - "type": "wearable" - } - }, - { - "desc": "Google Pixel Watch 2", - "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Google Pixel Watch 2 Build/TWD9.240605.001.A1)", - "expect": { - "vendor": "Google", - "model": "Pixel Watch 2", - "type": "wearable" - } - }, - { - "desc": "Google Pixel XL", - "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel XL Build/NDE63X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel XL", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 2", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 2", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 2 XL", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 XL Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 2 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 2 XL", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 2 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 2 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3 XL", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3 XL", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3a", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3a", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3a XL", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3a XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 4", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 4", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 4a", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 4a", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 4 XL", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 4 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 5", - "ua": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.120 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 5", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 7", - "ua": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 7", - "type": "mobile" - } - }, - { - "desc": "Generic Android Device", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)", - "expect": { - "vendor": "Generic", - "model": "Android 6.0.1" - } - }, - { - "desc": "Android Phone Unidentified Vendor (docomo F-04K)", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-04K Build/V15R060P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", - "expect": { - "model": "F-04K", - "type": "mobile" - } - }, - { - "desc": "docomo SH-02M", - "ua": "Mozilla/5.0 (Linux; Android 9; SH-02M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SH-02M", - "type": "mobile" - } - }, - { - "desc": "Android Tablet Unidentified Vendor (docomo F-02K)", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-02K Build/V44R059G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", - "expect": { - "model": "F-02K", - "type": "tablet" - } - }, - { - "desc": "Android Tablet Unidentified Vendor (docomo d-02K)", - "ua": "Mozilla/5.0 (Linux; Android 9; d-02K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Safari/537.36", - "expect": { - "model": "d-02K", - "type": "tablet" - } - }, - { - "desc": "LG VK Series Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.0.2; VK700 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.84 Safari/537.36", - "expect": { - "vendor": "LG", - "model": "VK700", - "type": "tablet" - } - }, - { - "desc": "LG LK Series Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.0.1; LGLK430 Build/LRX21Y) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LK430", - "type": "tablet" - } - }, - { - "desc": "Amazon Alexa Echo Show", - "ua": "AlexaWebMediaPlayer/1.0.200641.0 (Linux;Android 5.1.1)", - "expect": { - "vendor": "Amazon", - "model": "Alexa", - "type": "tablet" - } - }, - { - "desc": "Amazon Kindle Fire Tablet", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFSAWI", - "type": "tablet" - } - }, - { - "desc": "Amazon Kindle Fire Tablet", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFSAWI", - "type": "tablet" - } - }, - { - "desc": "Amazon Kindle Fire Tablet", - "ua": "Mozilla/5.0 (Linux; Android 9; KFMAWI Build/PS7312; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFMAWI", - "type": "tablet" - } - }, - { - "desc": "Amazon Fire TV", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; AFTB Build/JDQ39) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.173 Mobile Safari/537.22", - "expect": { - "vendor": "Amazon", - "model": "B", - "type": "smarttv" - } - }, - { - "desc": "Amazon Fire TV", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; AFTT) AppleWebKit/537.36 (KHTML, like Gecko) Silk/86.3.20 like Chrome/86.0.4240.198 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "T", - "type": "smarttv" - } - }, - { - "desc": "Amazon Fire TV", - "ua": "Mozilla/5.0 (Linux; Android 9; AFTKA Build/PS7633.3445N; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.160 Mobile Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KA", - "type": "smarttv" - } - }, - { - "desc": "Android TV", - "ua": "Mozilla/5.0 (Linux; Android 10; 2020/2021 UHD Android TV Build/QTG3.201102.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "Amazon Fire 7", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/80.5.3 like Chrome/80.0.3987.162 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFAUWI", - "type": "tablet" - } - }, - { - "desc": "FaceBook Mobile App", - "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", - "expect": { - "vendor": "Apple", - "model": "iPhone12,1", - "type": "mobile" - } - }, - { - "desc": "Issue #519", - "ua": "ios/iPhone/14.2/SOME_CUSTOM_APP_VERSION", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "Issue #454", - "ua": "Mosamzilla/5.0 (Windows; U; Win98; en-US; rv:1.7.5) Gecko/20050603 Netscape/8.0.2", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "undefined" - } - }, - { - "desc": "Alcatel", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ALCATEL A564C Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "ALCATEL", - "model": "A564C", - "type": "mobile" - } - }, - { - "desc": "Alcatel Go Flip", - "ua": "Mozilla/5.0 (Mobile; ALCATEL4044T; rv:37.0) Gecko/37.0 Firefox/37.0 KaiOS/1.0", - "expect": { - "vendor": "ALCATEL", - "model": "4044T", - "type": "mobile" - } - }, - { - "desc": "Jolla", - "ua": "Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0", - "expect": { - "vendor": "Jolla", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Xbox One", - "ua": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; Xbox; Xbox One)", - "expect": { - "vendor": "Microsoft", - "model": "Xbox One", - "type": "console" - } - }, - { - "desc": "Xbox", - "ua": "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)", - "expect": { - "vendor": "Microsoft", - "model": "Xbox", - "type": "console" - } - }, - { - "desc": "Nvidia Shield Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SHIELD Tablet Build/LVY48E; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.19 Safari/537.36", - "expect": { - "vendor": "Nvidia", - "model": "SHIELD Tablet", - "type": "tablet" - } - }, - { - "desc": "Ouya", - "ua": "Mozilla/5.0 (Linux; Android 4.1.2; OUYA Console Build/JZO54L-OUYA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.84 Safari/537.36", - "expect": { - "vendor": "OUYA", - "model": "undefined", - "type": "console" - } - }, - { - "desc": "Vivo S1 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; vivo 1920) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Vivo", - "model": "1920", - "type": "mobile" - } - }, - { - "desc": "Vivo Y52s", - "ua": "Mozilla/5.0 (Linux; Android 10; V2057A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.10 SP-engine/2.28.0 baiduboxapp/12.10.0.10 (Baidu; P1 10) NABar/1.0", - "expect": { - "vendor": "Vivo", - "model": "V2057A", - "type": "mobile" - } - }, - { - "desc": "Vivo X60", - "ua": "Mozilla/5.0 (Linux; Android 11; V2046A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.8.71.0", - "expect": { - "vendor": "Vivo", - "model": "V2046A", - "type": "mobile" - } - }, - { - "desc": "Vivo Y79A", - "ua": "Mozilla/5.0 (Linux; Android 7.1.2; vivo Y79A Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", - "expect": { - "vendor": "Vivo", - "model": "Y79A", - "type": "mobile" - } - }, - { - "desc": "Vivo Y93", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; vivo 1814) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Vivo", - "model": "1814", - "type": "mobile" - } - }, - { - "desc": "Vivo Y97", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; V1813T Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", - "expect": { - "vendor": "Vivo", - "model": "V1813T", - "type": "mobile" - } - }, - { - "desc": "Vivo iQOO Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; V1916A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.1.10.6", - "expect": { - "vendor": "Vivo", - "model": "V1916A", - "type": "mobile" - } - }, - { - "desc": "Vivo 1906 (Y11)", - "ua": "Mozilla/5.0 (Linux; Android 11; vivo 1906) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Vivo", - "model": "1906", - "type": "mobile" - } - }, - { - "desc": "Unknown Mobile using Firefox", - "ua": "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Firefox", - "ua": "Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown Mobile using Focus for Android", - "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Focus for Android", - "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown Device using Focus for Android with GeckoView", - "ua": "Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Mobile using Firefox OS", - "ua": "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Firefox OS", - "ua": "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown TV using Firefox OS", - "ua": "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "PDA with Windows CE", - "ua": "Mozilla/4.0 (PDA; Windows CE/1.0.1) NetFront/3.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - } -] \ No newline at end of file diff --git a/test/specs/devices/_others.json b/test/specs/devices/_others.json new file mode 100644 index 0000000..7ee9ec6 --- /dev/null +++ b/test/specs/devices/_others.json @@ -0,0 +1,250 @@ +[ + { + "desc": "Generic Android Device", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)", + "expect": { + "vendor": "Generic", + "model": "Android 6.0.1" + } + }, + { + "desc": "K", + "ua": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "K", + "type": "mobile" + } + }, + { + "desc": "Desktop (IE11 with Tablet string)", + "ua": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; GWX:MANAGED; rv:11.0) like Gecko", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "undefined" + } + }, + { + "desc": "Mobile (DuckDuckGo mobile browser)", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile DuckDuckGo/5 Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "JVC LT-43V55LFA Smart TV", + "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB211 VSTVB MB200 HbbTV/1.2.1 (; JVC; MB211; 3.19.4.2; _TV_NT72563_2017 SmartTvA/3.0.0", + "expect": { + "vendor": "JVC", + "model": "MB211", + "type": "smarttv" + } + }, + { + "desc": "JVC LT-43V65LUA Smart TV", + "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB130 VSTVB MB100 HbbTV/1.2.1 (; JVC; MB130; 5.7.20.0; _TV_G10_2017;) SmartTvA/3.0.0", + "expect": { + "vendor": "JVC", + "model": "MB130", + "type": "smarttv" + } + }, + { + "desc": "Loewe Smart TV", + "ua": "Mozilla/5.0 (Linux; U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2207.0 LOEWE-SL410/5.2.0.0 HbbTV/1.4.1 (; LOEWE; SL410; LOH/5.2.0.0;;) FVC/3.0 (LOEWE; SL410;) CE-HTML/1.0 Config (L:deu,CC:DEU) NETRANGEMMH", + "expect": { + "vendor": "LOEWE", + "model": "SL410", + "type": "smarttv" + } + }, + { + "desc": "Issue #747", + "ua": "python-requests/2.25.1", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "undefined" + } + }, + { + "desc": "Issue #454", + "ua": "Mosamzilla/5.0 (Windows; U; Win98; en-US; rv:1.7.5) Gecko/20050603 Netscape/8.0.2", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "undefined" + } + }, + { + "desc": "OnePlus 7T Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; HD1913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36 EdgA/110.0.1587.66", + "expect": { + "vendor": "undefined", + "model": "HD1913", + "type": "mobile" + } + }, + { + "desc": "Philips SmartTV", + "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", + "expect": { + "vendor": "Philips", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Philips 32PFL6606K/02 SmartTV (2011)", + "ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70", + "expect": { + "vendor": "Philips", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Philips 32PFL6606K/02 SmartTV (2013)", + "ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70", + "expect": { + "vendor": "Philips", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Philips 32PHS5301/12 SmartTV (2016)", + "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 OPR/29.0.1803.0 OMI/4.5.23.37.MOT2.13 HbbTV/1.2.1 (;Philips;32PHS5301/12;;_TV_MT5800;) Firmware/TPM161E_012.002.045.001 en", + "expect": { + "vendor": "Philips", + "model": "32PHS5301/12", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV", + "ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "Android Phone Unidentified Vendor (docomo F-04K)", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-04K Build/V15R060P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "model": "F-04K", + "type": "mobile" + } + }, + { + "desc": "Android Tablet Unidentified Vendor (docomo F-02K)", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-02K Build/V44R059G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", + "expect": { + "model": "F-02K", + "type": "tablet" + } + }, + { + "desc": "Android Tablet Unidentified Vendor (docomo d-02K)", + "ua": "Mozilla/5.0 (Linux; Android 9; d-02K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Safari/537.36", + "expect": { + "model": "d-02K", + "type": "tablet" + } + }, + { + "desc": "Android TV", + "ua": "Mozilla/5.0 (Linux; Android 10; 2020/2021 UHD Android TV Build/QTG3.201102.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "Unknown Mobile using Firefox", + "ua": "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Firefox", + "ua": "Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown Mobile using Focus for Android", + "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Focus for Android", + "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown Device using Focus for Android with GeckoView", + "ua": "Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Mobile using Firefox OS", + "ua": "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Firefox OS", + "ua": "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown TV using Firefox OS", + "ua": "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "PDA with Windows CE", + "ua": "Mozilla/4.0 (PDA; Windows CE/1.0.1) NetFront/3.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/acer.json b/test/specs/devices/acer.json new file mode 100644 index 0000000..7eff9d8 --- /dev/null +++ b/test/specs/devices/acer.json @@ -0,0 +1,11 @@ +[ + { + "desc": "Acer Iconia A1-810", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; A1-810 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", + "expect": { + "vendor": "Acer", + "model": "A1-810", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/advan.json b/test/specs/devices/advan.json new file mode 100644 index 0000000..16a2331 --- /dev/null +++ b/test/specs/devices/advan.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Advan M4", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; ADVAN M4 Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36 OPR/28.0.2254.119214", + "expect": { + "vendor": "ADVAN", + "model": "M4", + "type": "mobile" + } + }, + { + "desc": "Advan S40", + "ua": "Mozilla/5.0 (Linux; Android 7.0; ADVAN S40 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Mobile Safari/537.36 EdgA/79.0.309.58", + "expect": { + "vendor": "ADVAN", + "model": "S40", + "type": "mobile" + } + }, + { + "desc": "Advan Sketsa 2", + "ua": "Mozilla/5.0 (Linux; Android 11; ADVAN 1011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36", + "expect": { + "vendor": "ADVAN", + "model": "1011", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/alcatel.json b/test/specs/devices/alcatel.json new file mode 100644 index 0000000..edfdfcd --- /dev/null +++ b/test/specs/devices/alcatel.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Alcatel", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ALCATEL A564C Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "ALCATEL", + "model": "A564C", + "type": "mobile" + } + }, + { + "desc": "Alcatel Go Flip", + "ua": "Mozilla/5.0 (Mobile; ALCATEL4044T; rv:37.0) Gecko/37.0 Firefox/37.0 KaiOS/1.0", + "expect": { + "vendor": "ALCATEL", + "model": "4044T", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/amazon.json b/test/specs/devices/amazon.json new file mode 100644 index 0000000..6e60318 --- /dev/null +++ b/test/specs/devices/amazon.json @@ -0,0 +1,137 @@ +[ + { + "desc": "Kindle Fire HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", + "expect": { + "vendor": "Amazon", + "model": "KFTT", + "type": "tablet" + } + }, + { + "desc": "Kindle Fire HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", + "expect": { + "vendor": "Amazon", + "model": "KFTT", + "type": "tablet" + } + }, + { + "desc": "Echo Show 5", + "ua": "Mozilla/5.0 (Linux; Android 5.1; AEORK Build/LVY48F; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "AEORK", + "type": "tablet" + } + }, + { + "desc": "Echo Show 8", + "ua": "Mozilla/5.0 (Linux; Android 7.1; AEOCH) AppleWebKit/537.36 (KHTML, like Gecko) Silk/77.2.21 like Chrome/77.0.3865.92 Mobile Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "AEOCH", + "type": "tablet" + } + }, + { + "desc": "Echo Show 8", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; AEOCW) AppleWebKit/537.36 (KHTML, like Gecko) Silk/106.3.3 like Chrome/106.0.5249.170 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "AEOCW", + "type": "tablet" + } + }, + { + "desc": "Echo Show 15", + "ua": "Mozilla/5.0 (Linux; Android 9; AEOHY) AppleWebKit/537.36 (KHTML, like Gecko) Silk/112.6.3 like Chrome/112.0.5615.213 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "AEOHY", + "type": "tablet" + } + }, + { + "desc": "Echo Dot", + "ua": "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AEOBC Build/LVY48F)", + "expect": { + "vendor": "Amazon", + "model": "AEOBC", + "type": "embedded" + } + }, + { + "desc": "Amazon Kindle Fire Tablet", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFSAWI", + "type": "tablet" + } + }, + { + "desc": "Amazon Kindle Fire Tablet", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFSAWI", + "type": "tablet" + } + }, + { + "desc": "Amazon Kindle Fire Tablet", + "ua": "Mozilla/5.0 (Linux; Android 9; KFMAWI Build/PS7312; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFMAWI", + "type": "tablet" + } + }, + { + "desc": "Amazon Fire TV", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; AFTB Build/JDQ39) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.173 Mobile Safari/537.22", + "expect": { + "vendor": "Amazon", + "model": "B", + "type": "smarttv" + } + }, + { + "desc": "Amazon Fire TV", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; AFTT) AppleWebKit/537.36 (KHTML, like Gecko) Silk/86.3.20 like Chrome/86.0.4240.198 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "T", + "type": "smarttv" + } + }, + { + "desc": "Amazon Fire TV", + "ua": "Mozilla/5.0 (Linux; Android 9; AFTKA Build/PS7633.3445N; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.160 Mobile Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KA", + "type": "smarttv" + } + }, + { + "desc": "Amazon Fire 7", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/80.5.3 like Chrome/80.0.3987.162 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFAUWI", + "type": "tablet" + } + }, + { + "desc": "Amazon Alexa Echo Show", + "ua": "AlexaWebMediaPlayer/1.0.200641.0 (Linux;Android 5.1.1)", + "expect": { + "vendor": "Amazon", + "model": "Alexa", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/apple.json b/test/specs/devices/apple.json new file mode 100644 index 0000000..4de5728 --- /dev/null +++ b/test/specs/devices/apple.json @@ -0,0 +1,128 @@ +[ + { + "desc": "Apple Desktop", + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15", + "expect": { + "vendor": "Apple", + "model": "Macintosh", + "type": "undefined" + } + }, + { + "desc": "Apple Watch", + "ua": "atc/1.0 watchOS/7.3.3 model/Watch4,2 hwp/t8006 build/18S830 (6; dt:191)", + "expect": { + "vendor": "Apple", + "model": "watch", + "type": "wearable" + } + }, + { + "desc": "iPad using UCBrowser", + "ua": "Mozilla/5.0 (iPad; U; CPU OS 11_2 like Mac OS X; zh-CN; iPad5,3) AppleWebKit/534.46 (KHTML, like Gecko) UCBrowser/3.0.1.776 U3/ Mobile/10A403 Safari/7543.48.3", + "expect": { + "vendor": "Apple", + "model": "iPad", + "type": "tablet" + } + }, + { + "desc": "iPad Air", + "ua": "Mozilla/5.0 (iPad; CPU OS 12_4_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPad4,1;FBMD/iPad;FBSN/iOS;FBSV/12.4.5;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPad", + "type": "tablet" + } + }, + { + "desc": "iPad using Facebook Browser", + "ua": "Mozilla/5.0 (iPad; CPU OS 14_4_2 like Mac OS X) WebKit/8610 (KHTML, like Gecko) Mobile/18D70 [FBAN/FBIOS;FBDV/iPad7,11;FBMD/iPad;FBSN/iOS;FBSV/14.4.2;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5]", + "expect": { + "vendor": "Apple", + "model": "iPad", + "type": "tablet" + } + }, + { + "desc": "iPod", + "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53", + "expect": { + "vendor": "Apple", + "model": "iPod touch", + "type": "mobile" + } + }, + { + "desc": "iPhone", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone SE", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone SE using Facebook App", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone 11 Pro Max", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone12,5;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone XS", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone11,2;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPod touch", + "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53", + "expect": { + "vendor": "Apple", + "model": "iPod touch", + "type": "mobile" + } + }, + { + "desc": "FaceBook Mobile App", + "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", + "expect": { + "vendor": "Apple", + "model": "iPhone12,1", + "type": "mobile" + } + }, + { + "desc": "Issue #519", + "ua": "ios/iPhone/14.2/SOME_CUSTOM_APP_VERSION", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/asus.json b/test/specs/devices/asus.json new file mode 100644 index 0000000..4e3a0ef --- /dev/null +++ b/test/specs/devices/asus.json @@ -0,0 +1,155 @@ +[ + { + "desc": "ASUS Nexus 7", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "Nexus 7", + "type": "tablet" + } + }, + { + "desc": "ASUS Padfone", + "ua": "Mozilla/5.0 (Linux; Android 4.1.1; PadFone 2 Build/JRO03L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "PadFone", + "type": "tablet" + } + }, + { + "desc": "ASUS ZenPad 10", + "ua": "Mozilla/5.0 (Linux; Android 6.0; P00C Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "P00C", + "type": "tablet" + } + }, + { + "desc": "ASUS ZenPad Z8s", + "ua": "Mozilla/5.0 (Linux; Android 7.0; ASUS_P00J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Safari/537.36\n", + "expect": { + "vendor": "ASUS", + "model": "P00J", + "type": "tablet" + } + }, + { + "desc": "ASUS ROG", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ZS600KL Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZS600KL", + "type": "mobile" + } + }, + { + "desc": "ASUS ROG II", + "ua": "Mozilla/5.0 (Linux; Android 9; ASUS_I001DA Build/PKQ1.190414.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "I001DA", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 2", + "ua": "Mozilla/5.0 (Linux; Android 5.0; ASUS ZenFone 2 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZenFone 2", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 3 Deluxe", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_Z016D Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.132 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "Z016D", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 5", + "ua": "Mozilla/5.0 (Linux; Android 8.0; ZE620KL Build/OPR1.170623.032) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZE620KL", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 7", + "ua": "Mozilla/5.0 (Linux; Android 10; ASUS_I002D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.81 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "I002D", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 7 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; ZS671KS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZS671KS", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; ZB602KL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZB602KL", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max Pro (M1)", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X00TD Build/OPM1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X00TD", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max M2", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01AD) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X01AD", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max Pro M2", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01BDA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X01BDA", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Go", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_X009DA Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X009DA", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 2 Laser", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ASUS_Z00ED) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "Z00ED", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/blackberry.json b/test/specs/devices/blackberry.json new file mode 100644 index 0000000..f809d55 --- /dev/null +++ b/test/specs/devices/blackberry.json @@ -0,0 +1,47 @@ +[ + { + "desc": "BlackBerry Priv", + "ua": "User-Agent: Mozilla/5.0 (Linux; Android 5.1.1; STV100-1 Build/LMY47V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/46.0.2490.76 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "STV100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Keyone", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBB100-1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBB100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Key2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBF100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBF100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Key2 LE", + "ua": "User-Agent: Mozilla/5.0 (Linux; Android 8.1.0; BBE100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBE100-1", + "type": "mobile" + } + }, + { + "desc": "Blackview 4900Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; BV4900Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "BV4900Pro", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/cat.json b/test/specs/devices/cat.json new file mode 100644 index 0000000..7c5710d --- /dev/null +++ b/test/specs/devices/cat.json @@ -0,0 +1,38 @@ +[ + { + "desc": "Cat B15Q", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; B15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "Cat", + "model": "B15Q", + "type": "mobile" + } + }, + { + "desc": "Cat B35", + "ua": "Mozilla/5.0 (Mobile; CAT B35; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.1", + "expect": { + "vendor": "Cat", + "model": "B35", + "type": "mobile" + } + }, + { + "desc": "Cat S22 Flip", + "ua": "Mozilla/5.0 (Linux; Android 11; S22 FLIP Build/RKQ1.210416.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36", + "expect": { + "vendor": "Cat", + "model": "S22 FLIP", + "type": "mobile" + } + }, + { + "desc": "Cat S62 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; S62 Pro Build/RKQ1.210406.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.85 Mobile Safari/537.36 GSA/12.34.17.23.arm64", + "expect": { + "vendor": "Cat", + "model": "S62 Pro", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/energizer.json b/test/specs/devices/energizer.json new file mode 100644 index 0000000..ec1ec47 --- /dev/null +++ b/test/specs/devices/energizer.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Energizer Energy 400", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Energy400 Build/MRA58K test-keys; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.158 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/172.0.0.66.93;]", + "expect": { + "vendor": "Energizer", + "model": "Energy400", + "type": "mobile" + } + }, + { + "desc": "Energizer Energy 400S", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Energy 400S Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.85 Mobile Safari/537.36", + "expect": { + "vendor": "Energizer", + "model": "Energy 400S", + "type": "mobile" + } + }, + { + "desc": "Energizer Ultimate 65G", + "ua": "Mozilla/5.0 (Linux; Android 14; Energizer Ultimate 65G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Energizer", + "model": "Ultimate 65G", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/facebook.json b/test/specs/devices/facebook.json new file mode 100644 index 0000000..01e1c97 --- /dev/null +++ b/test/specs/devices/facebook.json @@ -0,0 +1,38 @@ +[ + { + "desc": "Oculus Quest", + "ua": "Mozilla/5.0 (Linux; Android 10; Quest) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest", + "type": "xr" + } + }, + { + "desc": "Oculus Quest 2", + "ua": "Mozilla/5.0 (Linux; Android 10; Quest 2) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest 2", + "type": "xr" + } + }, + { + "desc": "Oculus Quest 3", + "ua": "Mozilla/5.0 (X11; Linux x86_64; Quest 3) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/31.4.0.6.51.566757996 Chrome/120.0.6099.283 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest 3", + "type": "xr" + } + }, + { + "desc": "Oculus Quest Pro", + "ua": "Mozilla/5.0 (X11; Linux x86_64; Quest Pro) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/24.4.0.22.60.426469926 SamsungBrowser/4.0 Chrome/106.0.5249.181 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest Pro", + "type": "xr" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/fairphone.json b/test/specs/devices/fairphone.json new file mode 100644 index 0000000..e341cf7 --- /dev/null +++ b/test/specs/devices/fairphone.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Fairphone 1U", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; FP1U Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Fairphone", + "model": "FP1U", + "type": "mobile" + } + }, + { + "desc": "Fairphone 2", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; FP2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Fairphone", + "model": "FP2", + "type": "mobile" + } + }, + { + "desc": "Fairphone 3", + "ua": "Mozilla/5.0 (Linux; Android 9; FP3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "Fairphone", + "model": "FP3", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/google.json b/test/specs/devices/google.json new file mode 100644 index 0000000..a06b991 --- /dev/null +++ b/test/specs/devices/google.json @@ -0,0 +1,236 @@ +[ + { + "desc": "Google Chromecast with Google TV", + "ua": "Mozilla/5.0 (Linux; Android 12.0; Build/STTL.240206.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.0 Safari/537.36 CrKey/1.56.500000 DeviceType/AndroidTV", + "expect": { + "vendor": "Google", + "model": "Chromecast AndroidTV", + "type": "smarttv" + } + }, + { + "desc": "Google Chromecast Mini Smart Speaker", + "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/SmartSpeaker", + "expect": { + "vendor": "Google", + "model": "Chromecast SmartSpeaker", + "type": "smarttv" + } + }, + { + "desc": "Google Chromecast Third Generation", + "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast", + "expect": { + "vendor": "Google", + "model": "Chromecast Third Generation", + "type": "smarttv" + } + }, + { + "desc": "Google Chromecast Nest Hub", + "ua": "Mozilla/5.0 (Fuchsia) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 CrKey/1.56.500000", + "expect": { + "vendor": "Google", + "model": "Chromecast Nest Hub", + "type": "smarttv" + } + }, + { + "desc": "Google Chromecast", + "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.84 Safari/537.36 CrKey/1.22.79313", + "expect": { + "vendor": "Google", + "model": "Chromecast", + "type": "smarttv" + } + }, + { + "desc": "Google Pixel C", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel C", + "type": "tablet" + } + }, + { + "desc": "Google Pixel C", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel C", + "type": "tablet" + } + }, + { + "desc": "Google Pixel", + "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel Build/NDE63V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel", + "type": "mobile" + } + }, + { + "desc": "Google Pixel Tablet", + "ua": "Mozilla/5.0 (Linux; Android 14; Pixel Tablet Build/AP2A.240905.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel Tablet", + "type": "tablet" + } + }, + { + "desc": "Google Pixel Watch", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Google Pixel Watch Build/TWD4.231005.002)", + "expect": { + "vendor": "Google", + "model": "Pixel Watch", + "type": "wearable" + } + }, + { + "desc": "Google Pixel Watch 2", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Google Pixel Watch 2 Build/TWD9.240605.001.A1)", + "expect": { + "vendor": "Google", + "model": "Pixel Watch 2", + "type": "wearable" + } + }, + { + "desc": "Google Pixel XL", + "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel XL Build/NDE63X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 2", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 2 XL", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 XL Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 2 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 2 XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 2 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 2 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3 XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3 XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3a", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3a", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3a XL", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3a XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 4", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 4a", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4a", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 4 XL", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 5", + "ua": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.120 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 5", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 7", + "ua": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 7", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/hmd.json b/test/specs/devices/hmd.json new file mode 100644 index 0000000..2ca10a1 --- /dev/null +++ b/test/specs/devices/hmd.json @@ -0,0 +1,29 @@ +[ + { + "desc": "HMD Pulse", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse", + "type": "mobile" + } + }, + { + "desc": "HMD Pulse Plus", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse Plus) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse Plus", + "type": "mobile" + } + }, + { + "desc": "HMD Pulse Pro", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse Pro", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/honor.json b/test/specs/devices/honor.json new file mode 100644 index 0000000..321e51b --- /dev/null +++ b/test/specs/devices/honor.json @@ -0,0 +1,164 @@ +[ + { + "desc": "Honor MagicPad 13 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; GDI-W09 Build/HONORGDI-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "GDI-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 2", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; en-nz; JDN-W09 Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/6.0 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "JDN-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 2", + "ua": "Mozilla/5.0 (Linux; U; Android 9; zh-Hans-CN; JDN2-W09HN Build/HUAWEIJDN2-W09HN) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.6.6.164 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "JDN2-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 7 10.1", + "ua": "Mozilla/5.0 (Linux; Android 12; AGM3-AL09HN Build/HONORAGM3-AL09HN; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.46 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/490.0.0.63.82;IABMV/1;]", + "expect": { + "vendor": "Honor", + "model": "AGM3-AL09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 8 12.0", + "ua": "Mozilla/5.0 (Linux; Android 12; HEY-W09 Build/HONORHEY-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "HEY-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 9 12.1", + "ua": "Mozilla/5.0 (Linux; Android 13; HEY2-N09 Build/HONORHEY2-N09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 [FB_IAB/FB4A;FBAV/465.0.0.63.83;]", + "expect": { + "vendor": "Honor", + "model": "HEY2-N09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 9 12.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; HEY2-W09 Build/HONORHEY2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/129.0.6668.102 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", + "expect": { + "vendor": "Honor", + "model": "HEY2-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad V7 Pro 11", + "ua": "Mozilla/5.0 (Linux; Android 12; BRT-AN09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 EdgA/109.0.1518.53", + "expect": { + "vendor": "Honor", + "model": "BRT-AN09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad V7 Pro 11 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; BRT-W09 Build/HONORBRT-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.5.0.336 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "BRT-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X6", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09HN Build/HUAWEIAGR-W09HN; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.9 SP-engine/2.28.0 baiduboxapp/12.9.0.11 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Honor", + "model": "AGR-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X7 8 LTE", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-AL00HN; HMSCore 6.0.0.306) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.3.300 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "KOB2-AL00HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X7 8 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-W09HN; HMSCore 6.1.0.314) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 HuaweiBrowser/12.0.0.301 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "KOB2-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X8 Lite", + "ua": "Mozilla/5.0 (Linux; Android 12; AGM-W09HN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "AGM-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X9 11.5 LTE", + "ua": "Mozilla/5.0 (Linux; Android 13; ELN-L09 Build/HONORELN-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Mobile Safari/537.36[FBAN/EMA;FBLC/zh_CN;FBAV/432.0.0.9.110;FBCX/modulariab;]", + "expect": { + "vendor": "Honor", + "model": "ELN-L09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X9 11.5 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 13; ELN-W09 Build/HONORELN-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "ELN-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei Honor 6A", + "ua": "Mozilla/5.0 (Linux; Android 7.0; DLI-L22 Build/HONORDLI-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/252.0.0.22.355;]", + "expect": { + "vendor": "Honor", + "model": "DLI-L22", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 7", + "ua": "Mozilla/5.0 (Linux; Android 6.0; PLK-L01 Build/HONORPLK-L01; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "PLK-L01", + "type": "mobile" + } + }, + { + "desc": "Huawei 10 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; HRY-LX1 Build/HONORHRY-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "HRY-LX1", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/htc.json b/test/specs/devices/htc.json new file mode 100644 index 0000000..51ff339 --- /dev/null +++ b/test/specs/devices/htc.json @@ -0,0 +1,29 @@ +[ + { + "desc": "HTC Desire 820", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; HTC Desire 820 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", + "expect": { + "vendor": "HTC", + "model": "Desire 820", + "type": "mobile" + } + }, + { + "desc": "HTC Evo Shift 4G", + "ua": "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0", + "expect": { + "vendor": "Sprint", + "model": "APA7373KT", + "type": "mobile" + } + }, + { + "desc": "HTC Nexus 9", + "ua": "Mozilla/5.0 (Linux; Android 5.0; Nexus 9 Build/LRX21R) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Mobile Crosswalk/7.36.154.13 Safari/537.36", + "expect": { + "vendor": "HTC", + "model": "Nexus 9", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/huawei.json b/test/specs/devices/huawei.json new file mode 100644 index 0000000..670879e --- /dev/null +++ b/test/specs/devices/huawei.json @@ -0,0 +1,947 @@ +[ + { + "desc": "Huawei Honor", + "ua": "Mozilla/5.0 (Linux; U; Android 2.3; xx-xx; U8860 Build/HuaweiU8860) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", + "expect": { + "vendor": "Huawei", + "model": "U8860", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L41) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L41", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-AL10", + "type": "mobile" + } + }, + { + "desc": "Huawei Nexus 6P", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC19V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537", + "expect": { + "vendor": "Huawei", + "model": "Nexus 6P", + "type": "mobile" + } + }, + { + "desc": "Huawei P10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; VTR-L09 Build/HUAWEIVTR-L09; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VTR-L09", + "type": "mobile" + } + }, + { + "desc": "Huawei Y3II", + "ua": "Mozilla/5.0 (Linux; U; Android 5.1; xx-xx; HUAWEI LUA-L03 Build/HUAWEILUA-L03) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LUA-L03", + "type": "mobile" + } + }, + { + "desc": "HUAWEI MediaPad C5 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; MON-AL19B Build/HUAWEIMON-AL19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.83 Mobile Safari/537.36 T7/11.7 baiduboxapp/11.7.0.10 (Baidu; P1 7.0)", + "expect": { + "vendor": "Huawei", + "model": "MON-AL19B", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M2 10.1", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; HUAWEI M2-A01L Build/HUAWEIM2-A01L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/95.0.4638.74 Safari/537.36[FBAN/EMA;FBLC/fr_FR;FBAV/421.0.0.14.100;]", + "expect": { + "vendor": "Huawei", + "model": "M2-A01L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; en-US; BTV-DL09 Build/HUAWEIBEETHOVEN-DL09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11.5.0.1015 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTV-DL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; HUAWEI BTV-W09 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.96 Mobile Safari/537.36 AlohaBrowser/3.1.1", + "expect": { + "vendor": "Huawei", + "model": "BTV-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 Lite", + "ua": "Mozilla/5.0 (Linux; Android 7.0; CPN-L09 Build/HUAWEICPN-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36[FBAN/EMA;FBLC/ru_RU;FBAV/233.0.0.12.118;]", + "expect": { + "vendor": "Huawei", + "model": "CPN-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 Lite", + "ua": "Mozilla/5.0 (Linux; Android 7.0; CPN-W09 Build/HUAWEICPN-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.71 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/374.0.0.20.109;]", + "expect": { + "vendor": "Huawei", + "model": "CPN-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 Lite 10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BAH-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 10.8", + "ua": "Mozilla/5.0 (Linux; Android 9; CMR-W09 Build/HUAWEICMR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.102 Safari/537.36 Line/14.18.1/IAB", + "expect": { + "vendor": "Huawei", + "model": "CMR-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; BAH2-W19 Build/HUAWEIBAH2-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH2-W19", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; JDN2-W09 Build/HUAWEIJDN2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/90.0.4430.210 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/318.0.0.39.154;]", + "expect": { + "vendor": "Huawei", + "model": "JDN2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; JDN2-AL50 Build/HUAWEIJDN2-AL50; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.13.0 SP-engine/2.29.0 matrixstyle/0 lite baiduboxapp/5.8.0.10 (Baidu; P1 9) NABar/1.", + "expect": { + "vendor": "Huawei", + "model": "JDN2-AL50", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 8.4", + "ua": "Mozilla/5.0 (Linux; Android 9; SHT-W09 Build/HUAWEISHT-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.87 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SHT-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5", + "ua": "Mozilla/5.0 (Linux; Android 9; SHT-AL09 Build/HUAWEISHT-AL09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SHT-AL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M6 10.8", + "ua": "Mozilla/5.0 (Linux; Android 14; SCM-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6612.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SCM-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M6 8.4", + "ua": "Mozilla/5.0 (Linux; Android 9; VRD-W09; HMSCore 6.14.0.321; GMSCore 22.26.15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VRD-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T5", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-L09 Build/HUAWEIAGS2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.125 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS2-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10", + "ua": "Mozilla/5.0 (Linux; U; Android 10; en-US; AGR-L09 Build/HUAWEIAGR-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.3.8.1305 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09 Build/HUAWEIAGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS3-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T 8.0", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-L09 Build/HUAWEIKOB2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/396.0.0.21.104;]", + "expect": { + "vendor": "Huawei", + "model": "KOB2-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T 8.0", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-W09 Build/HUAWEIKOB2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 Mobile Safari/537.36 HuaweiBrowser/15.0.4.312 HMSCore/6.14.0.301", + "expect": { + "vendor": "Huawei", + "model": "KOB2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; T1-A21w Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Safari/537.36 SputnikBrowser/1.2.8.161", + "expect": { + "vendor": "Huawei", + "model": "T1-A21w", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; T1-A23L Build/HuaweiMediaPad; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 BingWeb/6.9.10", + "expect": { + "vendor": "Huawei", + "model": "T1-A23L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; T1-A21L Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.93 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "T1-A21L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 7", + "ua": "Mozilla/5.0 (Linux; 4.4.2; T1-701u) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "T1-701u", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 8", + "ua": "Mozilla/5.0 (Linux; U; Android 9.0; MediaPad T1 8.0 Build/HuaweiMediaPad) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30 OPR/28.0.2254.119224", + "expect": { + "vendor": "Huawei", + "model": "MediaPad T1 8.0", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10 9.7", + "ua": "Mozilla/5.0 (Linux; U; Android 10; en-US; AGRK-L09 Build/HUAWEIAGRK-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.6.0.1315 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGRK-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10 9.7 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; AGRK-W09; HMSCore 6.14.0.321) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGRK-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s 10.1 LTE", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3K-L09 Build/HUAWEIAGS3K-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36 [FB_IAB/FB4A;FBAV/362.0.0.27.109;]", + "expect": { + "vendor": "Huawei", + "model": "AGS3K-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s 10.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3K-W09; HMSCore 6.14.0.321) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS3K-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T2 10.0 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; 605HW Build/HuaweiMediaPad; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.78 Safari/537.36 [FB_IAB/FB4A;FBAV/436.0.0.35.101;]", + "expect": { + "vendor": "Huawei", + "model": "605HW", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T2 7.0 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0; BGO-DL09 Build/HuaweiBAGGIO; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/407.0.0.30.97;]", + "expect": { + "vendor": "Huawei", + "model": "BGO-DL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; AGS-W09 Build/HUAWEIAGS-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.90 Safari/537.36 GSA/10.83.10.21.arm64", + "expect": { + "vendor": "Huawei", + "model": "AGS-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 7", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BG2-U03 Build/HUAWEIBG2-U03; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.111 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BG2-U03", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; KOB-W09 Build/HUAWEIKOB-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 Safari/537.36 [FB_IAB/Orca-Android;FBAV/354.0.0.10.113;]", + "expect": { + "vendor": "Huawei", + "model": "KOB-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T5 10", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-W09 Build/HUAWEIAGS2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Huawei", + "model": "AGS2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad X2", + "ua": "Mozilla/5.0 (Linux; Android 8.0; GEM-703L Build/HUAWEIGEM-703L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/043906 Mobile Safari/537.36 MicroMessenger/6.6.3.1260(0x26060339) NetType/WIFI Language/zh_", + "expect": { + "vendor": "Huawei", + "model": "GEM-703L", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH3-W09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH3-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH3-L09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH3-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; BAH3-W59 Build/HUAWEIBAH3-W59; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36HiSearch/22.0.6.315", + "expect": { + "vendor": "Huawei", + "model": "BAH3-W59", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 (2022)", + "ua": "Mozilla/5.0 (Linux; Android 10; BAH4-L09 Build/HUAWEIBAH4-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH4-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 (2022) WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH4-W09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH4-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 SE", + "ua": "Mozilla/5.0 (Linux; Android 12; AGS5-L09 Build/HUAWEIAGS5-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS5-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 SE WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; AGS5-W09 Build/HUAWEIAGS5-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Safari/537.36 [FB_IAB/FB4A;FBAV/480.0.0.54.88;]", + "expect": { + "vendor": "Huawei", + "model": "AGS5-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11 (2023) WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; DBR-W10 Build/HUAWEIDBR-W10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.9.6.501 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DBR-W10", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-cn; DBY-W09 Build/HUAWEIDBY-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.86 MQQBrowser/14.6 Mobile Safari/537.36 COVC/046801", + "expect": { + "vendor": "Huawei", + "model": "DBY-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 Air WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; DBY2-W00 Build/HUAWEIDBY2-W00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/7.3.8.663 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DBY2-W00", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 LTE", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; BTK-AL09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTK-AL09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 S WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; TGR-W09; HMSCore 6.14.0.322; GMSCore 0.3.3.1.240913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 HuaweiBrowser/14.0.2.317 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TGR-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; BTK-W09; HMSCore 6.14.0.322; GMSCore 214816056) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTK-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad C5 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; MON-W19 Build/HUAWEIMON-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Mobile Safari/537.36 [Pinterest/Android]", + "expect": { + "vendor": "Huawei", + "model": "MON-W19", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 12; GOT-AL09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 YaBrowser/23.5.5.60.01 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "GOT-AL09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 11 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; GOT-W09 Build/HUAWEIGOT-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/97.0.4692.98 Safari/537.36 T7/13.19 BDOS/1.0 (HarmonyOS 3.0.0) SP-engine/2.57.0 baiduboxapp/13.19.0.12 (Baidu; P1 12) NABar/1.0", + "expect": { + "vendor": "Huawei", + "model": "GOT-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 12.6 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; WGR-W09 Build/HUAWEIWGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/412.0.0.8.106;]", + "expect": { + "vendor": "Huawei", + "model": "WGR-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad SE 11 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; AGS6-W09; HMSCore 6.12.2.309) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.5.315 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS6-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 13.2", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; PCE-W29; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "PCE-W29", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T 10", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-L09; HMSCore 5.0.4.301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.3.304 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T10s", + "ua": "Mozilla/5.0 (Linux; U; Android 10; zh-cn; AGS3-AL00 Build/HUAWEIAGS3-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/11.4 Mobile Safari/537.36 COVC/045530", + "expect": { + "vendor": "Huawei", + "model": "AGS3-AL00", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T10s WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/88.0.4324.93 Safari/537.36 OPR/60.0.2254.59405", + "expect": { + "vendor": "Huawei", + "model": "AGS3-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T8 8 LTE", + "ua": "Mozilla/5.0 (Linux; U; Android 10; KOB2K-L09 Build/HUAWEIKOB2K-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36 OPR/83.0.2254.73002", + "expect": { + "vendor": "Huawei", + "model": "KOB2K-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei M3", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BTV-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTV-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei Mate 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 8.0; BLA-L29 Build/HUAWEIBLA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.6 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BLA-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate X", + "ua": "Mozilla/5.0 (Linux; Android 9; TAH-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TAH-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate X2", + "ua": "Mozilla/5.0 (Linux; Android 10; TET-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TET-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 X", + "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "EVR-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L09", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL10", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L0C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L0C", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-TL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-TL00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 50 Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; DCO-LX9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DCO-LX9", + "type": "mobile" + } + }, + { + "desc": "Huawei P20 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ANE-LX1", + "type": "mobile" + } + }, + { + "desc": "Huawei P20", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; EML-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "EML-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "CLT-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P30", + "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ELE-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P30 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VOG-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P40", + "ua": "Mozilla/5.0 (Linux; Android 10; ANA-AN00 Build/HUAWEIANA-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/11.26 SP-engine/2.22.0 baiduboxapp/11.26.0.10 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Huawei", + "model": "ANA-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei P40 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; ELS-AN00 Build/HUAWEIELS-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/6.0.0", + "expect": { + "vendor": "Huawei", + "model": "ELS-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei 30 Pro+", + "ua": "Mozilla/5.0 (Linux; Android 10; EBG-AN10 Build/HUAWEIEBG-AN10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36 EdgA/42.0.0.2741", + "expect": { + "vendor": "Huawei", + "model": "EBG-AN10", + "type": "mobile" + } + }, + { + "desc": "Huawei 30S", + "ua": "Mozilla/5.0 (Linux; Android 10; CDY-AN90 Build/HUAWEICDY-AN90; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/5.8.0", + "expect": { + "vendor": "Huawei", + "model": "CDY-AN90", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L21", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L61", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L71) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L71", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L61D", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L61A", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L61D", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L71A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L71A", + "type": "mobile" + } + }, + { + "desc": "Huawei Enjoy10e", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", + "expect": { + "vendor": "Huawei", + "model": "MED-AL00", + "type": "mobile" + } + }, + { + "desc": "Huawei Y7 2018", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; LDN-L01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LDN-L01", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 8X", + "ua": "Mozilla/5.0 (Linux; Android 9; JSN-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "JSN-L21", + "type": "mobile" + } + }, + { + "desc": "Huawei Y6 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; MRD-LX1N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "MRD-LX1N", + "type": "mobile" + } + }, + { + "desc": "Huawei Y9 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; JKM-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "JKM-LX2", + "type": "mobile" + } + }, + { + "desc": "Huawei Y5", + "ua": "Mozilla/5.0 (Linux; Android 9; AMN-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AMN-LX3", + "type": "mobile" + } + }, + { + "desc": "Huawei Y7p", + "ua": "Mozilla/5.0 (Linux; Android 9; ART-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ART-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SNE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SNE-LX1", + "type": "mobile" + } + }, + { + "desc": "Huawei P10 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; WAS-LX1A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "WAS-LX1A", + "type": "mobile" + } + }, + { + "desc": "Huawei Y5 Lite 2018", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; DRA-LX5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DRA-LX5", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 8C", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BKK-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BKK-LX2", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/imo.json b/test/specs/devices/imo.json new file mode 100644 index 0000000..e794a80 --- /dev/null +++ b/test/specs/devices/imo.json @@ -0,0 +1,38 @@ +[ + { + "desc": "IMO FEEL A2", + "ua": "Mozilla/5.0 (Linux; Android 5.1; IMO FEEL A2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/49.0.2623.105 Mobile Safari/537.36", + "expect": { + "vendor": "IMO", + "model": "FEEL A2", + "type": "mobile" + } + }, + { + "desc": "IMO Q2", + "ua": "Mozilla/5.0 (Linux; Android 5.1; IMO Q2 Build/LMY47D; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/65.0.3325.109 Mobile Safari/537.36 GSA/7.22.24.21.arm", + "expect": { + "vendor": "IMO", + "model": "Q2", + "type": "mobile" + } + }, + { + "desc": "IMO S2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; IMO S2 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.162 Mobile Safari/537.36", + "expect": { + "vendor": "IMO", + "model": "S2", + "type": "mobile" + } + }, + { + "desc": "IMO Tab X9", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; id-id; IMO TAB X9 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "IMO", + "model": "TAB X9", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/infinix.json b/test/specs/devices/infinix.json new file mode 100644 index 0000000..6c356d3 --- /dev/null +++ b/test/specs/devices/infinix.json @@ -0,0 +1,56 @@ +[ + { + "desc": "Infinix Hot 7 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; Infinix X625C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X625C", + "type": "mobile" + } + }, + { + "desc": "Infinix Hot 10T", + "ua": "Mozilla/5.0 (Linux; Android 11; Infinix X689C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X689C", + "type": "mobile" + } + }, + { + "desc": "Infinix Hot 11s", + "ua": "Mozilla/5.0 (Linux; Android 11; Infinix X6812 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X6812", + "type": "mobile" + } + }, + { + "desc": "Infinix Smart 5", + "ua": "Mozilla/5.0 (Linux; Android 10; Infinix X657C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X657C", + "type": "mobile" + } + }, + { + "desc": "Infinix XPad", + "ua": "Mozilla/5.0 (Linux; Android 14; Infinix X1101B Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.99 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", + "expect": { + "vendor": "Infinix", + "model": "X1101B", + "type": "tablet" + } + }, + { + "desc": "Infinix Zero 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; Infinix X6815B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X6815B", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/itel.json b/test/specs/devices/itel.json new file mode 100644 index 0000000..109e6e0 --- /dev/null +++ b/test/specs/devices/itel.json @@ -0,0 +1,56 @@ +[ + { + "desc": "itel A25", + "ua": "Mozilla/5.0 (Linux; Android 9; itel L5002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.130 Mobile Safari/537.36 OPR/63.3.3216.58675", + "expect": { + "vendor": "itel", + "model": "L5002", + "type": "mobile" + } + }, + { + "desc": "itel A50", + "ua": "Mozilla/5.0 (Linux; U; Android 14; itel A667L Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Mobile Safari/537.36 OPR/83.1.2254.73239", + "expect": { + "vendor": "itel", + "model": "A667L", + "type": "mobile" + } + }, + { + "desc": "itel KidPad 1", + "ua": "Mozilla/5.0 (Linux; Android 10; Itel W7001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", + "expect": { + "vendor": "itel", + "model": "W7001", + "type": "tablet" + } + }, + { + "desc": "itel Pad One", + "ua": "Mozilla/5.0 (Linux; Android 12; itel P10001L Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.172 Safari/537.36", + "expect": { + "vendor": "itel", + "model": "P10001L", + "type": "tablet" + } + }, + { + "desc": "itel RS4", + "ua": "Mozilla/5.0 (Linux; Android 13; itel S666LN Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.165 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/468.1.0.56.78;]", + "expect": { + "vendor": "itel", + "model": "S666LN", + "type": "mobile" + } + }, + { + "desc": "itel Vision 2S", + "ua": "Mozilla/5.0 (Linux; Android 11; itel P651L Build/RP1A.201005.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.76 Mobile Safari/537.36", + "expect": { + "vendor": "itel", + "model": "P651L", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/jolla.json b/test/specs/devices/jolla.json new file mode 100644 index 0000000..622fea0 --- /dev/null +++ b/test/specs/devices/jolla.json @@ -0,0 +1,11 @@ +[ + { + "desc": "Jolla", + "ua": "Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0", + "expect": { + "vendor": "Jolla", + "model": "undefined", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/kobo.json b/test/specs/devices/kobo.json new file mode 100644 index 0000000..6648a9a --- /dev/null +++ b/test/specs/devices/kobo.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Kobo eReader", + "ua": "Mozilla/5.0 (Unknown; Linux) AppleWebKit/538.1 (KHTML, like Gecko) Kobo eReader Safari/538.1", + "expect": { + "vendor": "Kobo", + "model": "eReader", + "type": "tablet" + } + }, + { + "desc": "Kobo Touch", + "ua": "Mozilla/5.0 (Linux; U; Android 2.0; en-us;) AppleWebKit/538.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/538.1 (Kobo Touch 0377/4.20.14622)", + "expect": { + "vendor": "Kobo", + "model": "Touch", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/lenovo.json b/test/specs/devices/lenovo.json new file mode 100644 index 0000000..2ffc886 --- /dev/null +++ b/test/specs/devices/lenovo.json @@ -0,0 +1,74 @@ +[ + { + "desc": "Lenovo Tab 2", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Lenovo TAB 2 A7-30HC Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7", + "type": "tablet" + } + }, + { + "desc": "Lenovo Phone", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Lenovo PB2-650M Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/311.0.0.44.117;]", + "expect": { + "vendor": "Lenovo", + "model": "PB2-650M", + "type": "mobile" + } + }, + { + "desc": "Lenovo Tab 3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X90F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X90F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo TB-X304F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X304F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo TAB 2 A7-30HC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 7 Essential", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Lenovo TB-7304X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7304X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X606F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 YaBrowser/20.9.4.99.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606F", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab S6000", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; IdeaTab S6000-H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 YaBrowser/18.11.1.1011.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "IdeaTab S6000-H", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/lg.json b/test/specs/devices/lg.json new file mode 100644 index 0000000..f0312eb --- /dev/null +++ b/test/specs/devices/lg.json @@ -0,0 +1,164 @@ +[ + { + "desc": "LG V40 ThinQ", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-V405) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-V405", + "type": "mobile" + } + }, + { + "desc": "LG K30", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; LM-X410.F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-X410.F", + "type": "mobile" + } + }, + { + "desc": "LG K30", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-X410.FGN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-X410.FGN", + "type": "mobile" + } + }, + { + "desc": "LG K40", + "ua": "Mozilla/5.0 (Linux; Android 10; LM-X420) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-X420", + "type": "mobile" + } + }, + { + "desc": "LG Stylo 4", + "ua": "Mozilla/5.0 (Linux; Android 10; LM-Q710(FGN)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "LM-Q710(FGN)", + "type": "mobile" + } + }, + { + "desc": "LG Stylo 5", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-Q720) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-Q720", + "type": "mobile" + } + }, + { + "desc": "LG G7 ThinQ", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-G710VM Build/PKQ1.181105.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-G710VM", + "type": "mobile" + } + }, + { + "desc": "LG K20", + "ua": "Mozilla/5.0 (Android 13; Mobile; LG-M255; rv:111.0) Gecko/111.0 Firefox/111.0", + "expect": { + "vendor": "LG", + "model": "M255", + "type": "mobile" + } + }, + { + "desc": "LG K500", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; LG-K500 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "K500", + "type": "mobile" + } + }, + { + "desc": "LG Nexus 4", + "ua": "Mozilla/5.0 (Linux; Android 4.2.1; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", + "expect": { + "vendor": "LG", + "model": "Nexus 4", + "type": "mobile" + } + }, + { + "desc": "LG Nexus 4", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; Google Nexus 4 - 4.3 - API 18 - 768x1280 Build/JLS36G) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "LG", + "model": "Nexus 4", + "type": "mobile" + } + }, + { + "desc": "LG Nexus 5", + "ua": "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", + "expect": { + "vendor": "LG", + "model": "Nexus 5", + "type": "mobile" + } + }, + { + "desc": "LG Wing", + "ua": "Mozilla/5.0 (Linux; Android 10; LM-F100N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-F100N", + "type": "mobile" + } + }, + { + "desc": "LG Smart TV", + "ua": "Mozilla/5.0 (DirectFB; U; Linux mips; en) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) LG Browser (; LG NetCast.TV-2011)", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "LG Smart TV", + "ua": "Mozilla/5.0 (Linux; NetCast; U) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/53.0.2785 34 Safari/537.31 SmartTV/8.5", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "LG Android TV", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; LG Android TV Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "LG VK Series Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; VK700 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.84 Safari/537.36", + "expect": { + "vendor": "LG", + "model": "VK700", + "type": "tablet" + } + }, + { + "desc": "LG LK Series Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; LGLK430 Build/LRX21Y) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LK430", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/meizu.json b/test/specs/devices/meizu.json new file mode 100644 index 0000000..e18fdf0 --- /dev/null +++ b/test/specs/devices/meizu.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Meizu M5 Note", + "ua": "Mozilla/5.0 (Linux; Android 6.0; M5 Note Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043024 Safari/537.36 MicroMessenger/6.5.7.1040 NetType/WIFI Language/zh_CN", + "expect": { + "vendor": "Meizu", + "model": "M5 Note", + "type": "mobile" + } + }, + { + "desc": "Meizu M3S", + "ua": "Mozilla/5.0 (X11; Linux; Android 5.1; MZ-M3s Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrom/45.0.2454.94 Mobile Safari/537.36", + "expect": { + "vendor": "Meizu", + "model": "M3s", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/micromax.json b/test/specs/devices/micromax.json new file mode 100644 index 0000000..0416420 --- /dev/null +++ b/test/specs/devices/micromax.json @@ -0,0 +1,30 @@ +[ + + { + "desc": "Micromax Bharat 2 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 7.0; en-US; Micromax Q402Plus Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.12.9.1226 Mobile Safari/537.36", + "expect": { + "vendor": "Micromax", + "model": "Q402Plus", + "type": "mobile" + } + }, + { + "desc": "Micromax Canvas Infinity", + "ua": "Mozilla/5.0 (Linux; U; Android 7.1.2; en-US; Micromax HS2 Build/N2G47H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/13.2.0.1296 (SpeedMode) U4/1.0 UCWEB/2.0 Mobile Safari/534.30", + "expect": { + "vendor": "Micromax", + "model": "HS2", + "type": "mobile" + } + }, + { + "desc": "Micromax In 1b", + "ua": "Mozilla/5.0 (Linux; U; Android 10; Micromax E7533 Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36 OPR/54.0.2254.56148", + "expect": { + "vendor": "Micromax", + "model": "E7533", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/microsoft.json b/test/specs/devices/microsoft.json new file mode 100644 index 0000000..79c3511 --- /dev/null +++ b/test/specs/devices/microsoft.json @@ -0,0 +1,47 @@ +[ + { + "desc": "Microsoft Lumia 950", + "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", + "expect": { + "vendor": "Microsoft", + "model": "Lumia 950", + "type": "mobile" + } + }, + { + "desc": "Microsoft Surface Duo", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; Surface Duo Build/2020.1014.61)", + "expect": { + "vendor": "Microsoft", + "model": "Surface Duo", + "type": "tablet" + } + }, + { + "desc": "Microsoft Lumia 950", + "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", + "expect": { + "vendor": "Microsoft", + "model": "Lumia 950", + "type": "mobile" + } + }, + { + "desc": "Xbox", + "ua": "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)", + "expect": { + "vendor": "Microsoft", + "model": "Xbox", + "type": "console" + } + }, + { + "desc": "Xbox One", + "ua": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; Xbox; Xbox One)", + "expect": { + "vendor": "Microsoft", + "model": "Xbox One", + "type": "console" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/motorola.json b/test/specs/devices/motorola.json new file mode 100644 index 0000000..af6a4c8 --- /dev/null +++ b/test/specs/devices/motorola.json @@ -0,0 +1,83 @@ +[ + { + "desc": "Motorola Moto X", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; XT1097 Build/KXE21.187-38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.109 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "XT1097", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto Z3 Play", + "ua": "Mozilla/5.0 (Linux; Android 9; Moto Z3 Play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Moto Z3 Play", + "type": "mobile" + } + }, + { + "desc": "Motorola Nexus 6", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.20 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Nexus 6", + "type": "mobile" + } + }, + { + "desc": "Motorola Droid RAZR 4G", + "ua": "Mozilla/5.0 (Linux; U; Android 2.3; xx-xx; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", + "expect": { + "vendor": "Motorola", + "model": "DROID RAZR 4G", + "type": "mobile" + } + }, + { + "desc": "Motorola RAZR 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; motorola razr) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.1 Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "razr", + "type": "mobile" + } + }, + { + "desc": "Moto X", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2; xx-xx; XT1058 Build/13.9.0Q2.X-70-GHOST-ATT_LE-2) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Motorola", + "model": "XT1058", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto g(6) Play", + "ua": "Mozilla/5.0 (Linux; Android 9; moto g(6) play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "moto g(6) play", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto g(7) Supra", + "ua": "Mozilla/5.0 (Linux; Android 9; moto g(7) supra Build/PCOS29.114-134-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "moto g(7) supra", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto E", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Moto E (4) Build/NDQS26.69-64-11-7; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Moto E (4)", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/nintendo.json b/test/specs/devices/nintendo.json new file mode 100644 index 0000000..eb879b3 --- /dev/null +++ b/test/specs/devices/nintendo.json @@ -0,0 +1,47 @@ +[ + { + "desc": "Nintendo Switch", + "ua": "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", + "expect": { + "vendor": "Nintendo", + "model": "Switch", + "type": "console" + } + }, + { + "desc": "Nintendo WiiU", + "ua": "Mozilla/5.0 (Nintendo WiiU) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.4.2.9 NintendoBrowser/4.2.0.11146.EU", + "expect": { + "vendor": "Nintendo", + "model": "WiiU", + "type": "console" + } + }, + { + "desc": "Nintendo Wii", + "ua": "Opera/9.10 (Nintendo Wii; U; ; 1621; en)", + "expect": { + "vendor": "Nintendo", + "model": "Wii", + "type": "console" + } + }, + { + "desc": "Nintendo 3DS", + "ua": "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7610.EU", + "expect": { + "vendor": "Nintendo", + "model": "3DS", + "type": "console" + } + }, + { + "desc": "Nintendo 3DS", + "ua": "Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.EU", + "expect": { + "vendor": "Nintendo", + "model": "3DS", + "type": "console" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/nokia.json b/test/specs/devices/nokia.json new file mode 100644 index 0000000..c8cf6a9 --- /dev/null +++ b/test/specs/devices/nokia.json @@ -0,0 +1,74 @@ +[ + { + "desc": "Nokia3xx", + "ua": "Nokia303/14.87 CLDC-1.1", + "expect": { + "vendor": "Nokia", + "model": "303", + "type": "mobile" + } + }, + { + "desc": "Nokia 3.2", + "ua": "Mozilla/5.0 (Linux; Android 10; Nokia 3.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "3.2", + "type": "mobile" + } + }, + { + "desc": "Nokia 7", + "ua": "Mozilla/5.0 (Linux; Android 11; Nokia 7.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "7.2", + "type": "mobile" + } + }, + { + "desc": "Nokia N9", + "ua": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", + "expect": { + "vendor": "Nokia", + "model": "N9", + "type": "mobile" + } + }, + { + "desc": "Nokia T20", + "ua": "Mozilla/5.0 (Linux; Android 12; Nokia T20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "T20", + "type": "tablet" + } + }, + { + "desc": "Nokia T20", + "ua": "Mozilla/5.0 (Linux; Android 11; Nokia T20 Build/RP1A.201005.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/93.0.4577.62 Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "T20", + "type": "tablet" + } + }, + { + "desc": "Nokia T21", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Nokia T21 Build/TP1A.220624.014)", + "expect": { + "vendor": "Nokia", + "model": "T21", + "type": "tablet" + } + }, + { + "desc": "Nokia 2720 Flip", + "ua": "Mozilla/5.0 (Mobile; Nokia_2720_Flip; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.2", + "expect": { + "vendor": "Nokia", + "model": "2720 Flip", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/nothing.json b/test/specs/devices/nothing.json new file mode 100644 index 0000000..56dc460 --- /dev/null +++ b/test/specs/devices/nothing.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Nothing 1", + "ua": "Mozilla/5.0 (Linux; Android 13; A063) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36", + "expect": { + "vendor": "Nothing", + "model": "A063", + "type": "mobile" + } + }, + { + "desc": "Nothing 2", + "ua": "Mozilla/5.0 (Linux; Android 14; A065 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.53 Mobile Safari/537.36", + "expect": { + "vendor": "Nothing", + "model": "A065", + "type": "mobile" + } + }, + { + "desc": "Nothing 2a", + "ua": "Mozilla/5.0 (Linux; Android 14; A142 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.71 Mobile Safari/537.36", + "expect": { + "vendor": "Nothing", + "model": "A142", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/nvidia.json b/test/specs/devices/nvidia.json new file mode 100644 index 0000000..a78316e --- /dev/null +++ b/test/specs/devices/nvidia.json @@ -0,0 +1,11 @@ +[ + { + "desc": "Nvidia Shield Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SHIELD Tablet Build/LVY48E; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.19 Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD Tablet", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/oneplus.json b/test/specs/devices/oneplus.json new file mode 100644 index 0000000..44407d4 --- /dev/null +++ b/test/specs/devices/oneplus.json @@ -0,0 +1,119 @@ +[ + { + "desc": "OnePlus One", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A0001", + "type": "mobile" + } + }, + { + "desc": "OnePlus One", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; OnePlus One A0001 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A0001", + "type": "mobile" + } + }, + { + "desc": "OnePlus 2", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ONE A2003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A2003", + "type": "mobile" + } + }, + { + "desc": "OnePlus 3", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ONEPLUS A3000 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A3000", + "type": "mobile" + } + }, + { + "desc": "OnePlus 6", + "ua": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A6003", + "type": "mobile" + } + }, + { + "desc": "OnePlus 6T", + "ua": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6010) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A6010", + "type": "mobile" + } + }, + { + "desc": "OnePlus 8T", + "ua": "Mozilla/5.0 (Linux; Android 11; KB2005) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "KB2005", + "type": "mobile" + } + }, + { + "desc": "OnePlus 8 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; IN2025) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.119 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "IN2025", + "type": "mobile" + } + }, + { + "desc": "OnePlus Nord N100", + "ua": "Mozilla/5.0 (Linux; Android 10; BE2015 Build/QKQ1.200719.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "BE2015", + "type": "mobile" + } + }, + { + "desc": "OnePlus Nord N10 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; BE2029) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "BE2029", + "type": "mobile" + } + }, + { + "desc": "OnePlus Pad Go 11.35", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 14; OPD2304) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.629 YaApp_Android/24.101/apad YaSearchBrowser/24.101/apad BroPP/1.0 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2304", + "type": "tablet" + } + }, + { + "desc": "OnePlus Pad 2 12.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; OPD2403 Build/UKQ1.231108.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2403", + "type": "tablet" + } + }, + { + "desc": "OnePlus Pad 11.61 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; OPD2203 Build/UKQ1.230924.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2203", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/oppo.json b/test/specs/devices/oppo.json new file mode 100644 index 0000000..250909b --- /dev/null +++ b/test/specs/devices/oppo.json @@ -0,0 +1,137 @@ +[ + { + "desc": "OnePlus 10RT", + "ua": "Mozilla/5.0 (Linux; Android 13; CPH2413) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH2413", + "type": "mobile" + } + }, + { + "desc": "OPPO Pad", + "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; OPD2101 Build/TP1A.220905.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "OPD2101", + "type": "tablet" + } + }, + { + "desc": "OPPO Neo", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; R831T Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 OppoBrowser/3.3.2 Mobile Safari/534.30", + "expect": { + "vendor": "OPPO", + "model": "R831T", + "type": "mobile" + } + }, + { + "desc": "OPPO R7s", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; OPPO R7s Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/7.1 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "R7s", + "type": "mobile" + } + }, + { + "desc": "OPPO A3s", + "ua": "Mozilla/5.0 (Linux; Android 8.1; CPH1803 Build/OPM1.171019.026; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH1803", + "type": "mobile" + } + }, + { + "desc": "OPPO A12", + "ua": "Mozilla/5.0 (Linux; Android 9; CPH2083) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH2083", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno", + "ua": "Mozilla/5.0 (Linux; Android 9; PCAT00 Build/PKQ1.190101.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PCAT00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno3 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; PCLM50) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.117 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PCLM50", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 SE", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PEAM00 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PEAM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; PDPM00 Build/QKQ1.200216.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PDPM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 Pro 5G", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PDNT00 Build/QKQ1.200216.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PDNT00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno5 A", + "ua": "Mozilla/5.0 (Linux; Android 11; A101OP) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "A101OP", + "type": "mobile" + } + }, + { + "desc": "OPPO Find X", + "ua": "Mozilla/5.0 (Linux; Android 8.1; PAFM00 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PAFM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Find 7a", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; xx-xx; X9007 Build/JLS36C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "OPPO", + "model": "X9007", + "type": "mobile" + } + }, + { + "desc": "OPPO F5", + "ua": "ozilla/5.0 (Linux; Android 7.1.1; CPH1723) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH1723", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/ouya.json b/test/specs/devices/ouya.json new file mode 100644 index 0000000..1fa74c0 --- /dev/null +++ b/test/specs/devices/ouya.json @@ -0,0 +1,11 @@ +[ + { + "desc": "Ouya", + "ua": "Mozilla/5.0 (Linux; Android 4.1.2; OUYA Console Build/JZO54L-OUYA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.84 Safari/537.36", + "expect": { + "vendor": "OUYA", + "model": "undefined", + "type": "console" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/panasonic.json b/test/specs/devices/panasonic.json new file mode 100644 index 0000000..568c21d --- /dev/null +++ b/test/specs/devices/panasonic.json @@ -0,0 +1,47 @@ +[ + { + "desc": "Panasonic T31", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Panasonic T31 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.170 Mobile Safari/537.36 ", + "expect": { + "vendor": "Panasonic", + "model": "T31", + "type": "mobile" + } + }, + { + "desc": "Panasonic TX-32CSW514 SmartTV", + "ua": "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", + "expect": { + "vendor": "Panasonic", + "model": "VIERA 2015", + "type": "smarttv" + } + }, + { + "desc": "Panasonic TX-40FXW724 SmartTV", + "ua": "HbbTV/1.4.1 (+DRM;Panasonic;SmartTV2018mid;3.024;4301-0003 0002-0000;SmartTV2018;)", + "expect": { + "vendor": "Panasonic", + "model": "SmartTV2018mid", + "type": "smarttv" + } + }, + { + "desc": "Panasonic TX-43HXW904 SmartTV", + "ua": "HbbTV/1.5.1 (+DRM;Panasonic;SmartTV2020mid;3.326;4301-0003 0008-0000;com.panasonic.SmartTV2020mid;)", + "expect": { + "vendor": "Panasonic", + "model": "SmartTV2020mid", + "type": "smarttv" + } + }, + { + "desc": "Panasonic DMR-HST130 SAT receiver", + "ua": "HbbTV/1.1.1 (+PVR;Panasonic;DIGA WebKit M8658;3.420;;)", + "expect": { + "vendor": "Panasonic", + "model": "DIGA WebKit M8658", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/pico.json b/test/specs/devices/pico.json new file mode 100644 index 0000000..2f28212 --- /dev/null +++ b/test/specs/devices/pico.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Pico 4", + "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.8.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.38 Chrome/105.0.5195.68 VR Safari/537.36", + "expect": { + "vendor": "PICO", + "model": "4", + "type": "xr" + } + }, + { + "desc": "Pico 4", + "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0", + "expect": { + "vendor": "PICO", + "model": "4", + "type": "xr" + } + }, + { + "desc": "Pico Neo3 Link", + "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", + "expect": { + "vendor": "Pico", + "model": "Neo3 Link", + "type": "xr" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/polytron.json b/test/specs/devices/polytron.json new file mode 100644 index 0000000..595c27f --- /dev/null +++ b/test/specs/devices/polytron.json @@ -0,0 +1,38 @@ +[ + { + "desc": "Polytron Prime 7 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 7.0; POLYTRON_P552 Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/64.0.3282.137 Mobile Safari/537.36 OPR/50.0.2254.149182", + "expect": { + "vendor": "POLYTRON", + "model": "P552", + "type": "mobile" + } + }, + { + "desc": "Polytron Rocket T1", + "ua": "Mozilla/5.0 (Linux; U; Android 5.0; en-US; POLYTRON R2501 Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/13.1.2.1293 Mobile Safari/537.36", + "expect": { + "vendor": "POLYTRON", + "model": "R2501", + "type": "mobile" + } + }, + { + "desc": "Polytron Rocket T6", + "ua": "Mozilla/5.0 (Linux; Android 7.0; POLYTRON R2509) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.92 Mobile Safari/537.36", + "expect": { + "vendor": "POLYTRON", + "model": "R2509", + "type": "mobile" + } + }, + { + "desc": "Polytron Zap 6 Posh", + "ua": "Mozilla/5.0 (Linux; U; Android 5.1; in-ID; POLYTRON_4G501 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.10.0.1163 UCTurbo/1.9.9.900 Mobile Safari/537.36", + "expect": { + "vendor": "POLYTRON", + "model": "4G501", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/realme.json b/test/specs/devices/realme.json new file mode 100644 index 0000000..c16d4d0 --- /dev/null +++ b/test/specs/devices/realme.json @@ -0,0 +1,74 @@ +[ + { + "desc": "Realme C1", + "ua": "Mozilla/5.0 (Linux; Android 8.1; RMX1811 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1811", + "type": "mobile" + } + }, + { + "desc": "Realme C2", + "ua": "Mozilla/5.0 (Linux; Android 9; RMX1941) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1941", + "type": "mobile" + } + }, + { + "desc": "Realme Narzo 20", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; RMX2193 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX2193", + "type": "mobile" + } + }, + { + "desc": "Realme 2 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; RMX1801) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1801", + "type": "mobile" + } + }, + { + "desc": "Realme 3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; RMX1851) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1851", + "type": "mobile" + } + }, + { + "desc": "Realme 8", + "ua": "Mozilla/5.0 (Linux; Android 12; RMX3085) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX3085", + "type": "mobile" + } + }, + { + "desc": "Realme 9 Pro", + "ua": "Mozilla/5.0 (Linux; Android 13; RMX3471) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX3471", + "type": "mobile" + } + }, + { + "desc": "Realme GT Master", + "ua": "Mozilla/5.0 (Linux; Android 13; RMX3363) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX3363", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/roku.json b/test/specs/devices/roku.json new file mode 100644 index 0000000..a042f29 --- /dev/null +++ b/test/specs/devices/roku.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Roku", + "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", + "expect": { + "vendor": "Roku", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Roku", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Roku/DVP-8.10 (468.10E04145A)", + "expect": { + "vendor": "Roku", + "model": "DVP-8.10", + "type": "smarttv" + } + }, + { + "desc": "Roku", + "ua": "Roku4640X/DVP-7.70 (297.70E04154A)", + "expect": { + "vendor": "Roku", + "model": "DVP-7.70", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/samsung.json b/test/specs/devices/samsung.json new file mode 100644 index 0000000..0edb0f0 --- /dev/null +++ b/test/specs/devices/samsung.json @@ -0,0 +1,371 @@ +[ + { + "desc": "Samsung Galaxy A21s", + "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-A217F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.0 Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A217F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A31", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-A315G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A315G", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A50", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-A505F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.105 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A505F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A50s", + "ua": "Mozilla/5.0 (Linux; Android 11; SM-A507FN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A507FN", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A52s", + "ua": "Mozilla/5.0 (Linux; Android 13; SM-A528B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A528B", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A80", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-A805F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.112 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A805F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Fold", + "ua": "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-F900U Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.2 Chrome/67.0.3396.87 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F900U", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Z Flip", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-F700N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F700N", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Z Fold2", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-F916B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F916B", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S10E", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-G970F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G970F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S20 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; SCG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SCG01", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 10+", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-N976V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-N976V", + "type": "mobile" + } + }, + { + "desc": "Samsung SM-C5000", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; SM-C5000 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 wkbrowser 4.1.35 3065", + "expect": { + "vendor": "Samsung", + "model": "SM-C5000", + "type": "mobile" + } + }, + { + "desc": "Samsung C8", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; SM-C7108) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-C7108", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 8", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; GT-N5100 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "GT-N5100", + "type": "tablet" + } + }, + { + "desc": "Samsung SM-T231", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T231 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T231", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab 6 Lite", + "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-P610) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/12.0 Chrome/79.0.3945.136 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-P610", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab A 9.7", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; SM-P550 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-P550", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab A 10.1", + "ua": " Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-T515) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/13.0 Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T515", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab S7", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-T870) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T870", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab S8", + "ua": "Mozilla/5.0 (Linux; Android 12; SM-X706B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-X706B", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab S", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T700 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T700", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab Pro 10.1", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T520 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T520", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Watch", + "ua": "Mozilla/5.0 (Linux; Tizen 5.5; SAMSUNG SM-R805W) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.0 Chrome/69.0.3497.106 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-R805W", + "type": "wearable" + } + }, + { + "desc": "Samsung Galaxy Watch Active 2", + "ua": "Mozilla/5.0 (Linux; Tizen 5.5; SAMSUNG SM-R820) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.0 Chrome/69.0.3497.106 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-R820", + "type": "wearable" + } + }, + { + "desc": "Samsung Galaxy Watch4", + "ua": "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-R875U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.2. Chrome/102.0.5005.125 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-R875U", + "type": "wearable" + } + }, + { + "desc": "Samsung Galaxy Watch5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-R925U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.2. Chrome/111.0.5563.116 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-R925U", + "type": "wearable" + } + }, + { + "desc": "Samsung Note 10.1", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-P605) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-P605", + "type": "tablet" + } + }, + { + "desc": "Samsung SmartTV2011", + "ua": "HbbTV/1.1.1 (;;;;;) Maple;2011", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2011", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV2012", + "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2012", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV2014", + "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2014;T-NT14UDEUC-1060.4;;) WebKit", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2014", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV", + "ua": "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", + "expect": { + "vendor": "Samsung", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV HBBTV", + "ua": "HbbTV/1.5.1 (+DRM;Samsung;SmartTV2021:UAU7000;T-KSU2EDEUC-1506.0;KantSU2e;urn:samsungtv:familyname:21_KANTSU2E_UHD_BASIC:2021;) Tizen/6.0 (+TVPLUS+SmartHubLink) Chrome/76 LaTivu_1.0.1_2021 RVID/17", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2021:UAU7000", + "type": "smarttv" + } + }, + { + "desc": "Galaxy Nexus", + "ua": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", + "expect": { + "vendor": "Samsung", + "model": "Galaxy Nexus", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy C9 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0; SAMSUNG SM-C900F Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.2 Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-C900F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S5", + "ua": "Mozilla/5.0 (Linux; Android 5.0; SM-G900F Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.78 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G900F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy J7 Prime", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SM-G610F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G610F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S6", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-G920I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G920I", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S6 Edge", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-G925I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G925I", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 5 Chrome", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-N920C Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.91 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-N920C", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 5 Samsung Browser", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SAMSUNG SM-N920C Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-N920C", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/sharp.json b/test/specs/devices/sharp.json new file mode 100644 index 0000000..32d5340 --- /dev/null +++ b/test/specs/devices/sharp.json @@ -0,0 +1,56 @@ +[ + { + "desc": "Sharp AQUOS-TVX19B", + "ua": "Mozilla/5.0 (Linux; Android 9; AQUOS-TVX19B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "AQUOS-TVX19B", + "type": "smarttv" + } + }, + { + "desc": "Sharp Aquos B10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-A01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-A01", + "type": "mobile" + } + }, + { + "desc": "Sharp Aquos L2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02 Build/S4045) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-L02", + "type": "mobile" + } + }, + { + "desc": "Sharp Aquos L2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-L02", + "type": "mobile" + } + }, + { + "desc": "Sharp Aquos R2", + "ua": "Mozilla/5.0 (Linux; Android 8.0; SHV42) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SHV42", + "type": "mobile" + } + }, + { + "desc": "Docomo SH-02M", + "ua": "Mozilla/5.0 (Linux; Android 9; SH-02M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-02M", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/smartfren.json b/test/specs/devices/smartfren.json new file mode 100644 index 0000000..5413bb7 --- /dev/null +++ b/test/specs/devices/smartfren.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Smartfren Andromax L", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Andromax B26D2H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Smartfren", + "model": "Andromax B26D2H", + "type": "mobile" + } + }, + { + "desc": "Smartfren Andromax G2", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Smartfren Andromax AD9A1H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.83 Mobile Safari/537.36", + "expect": { + "vendor": "Smartfren", + "model": "Andromax AD9A1H", + "type": "mobile" + } + }, + { + "desc": "Smartfren New Andromax I", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; id-id; New Andromax-i Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Smartfren", + "model": "New Andromax-i", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/sony.json b/test/specs/devices/sony.json new file mode 100644 index 0000000..a4debe7 --- /dev/null +++ b/test/specs/devices/sony.json @@ -0,0 +1,209 @@ +[ + { + "desc": "SONY Xperia 1 III", + "ua": "Mozilla/5.0 (Linux; Android 11; A101SO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "A101SO", + "type": "mobile" + } + }, + { + "desc": "Sony G8141 (Xperia XZ1)", + "ua": "Mozilla/5.0 (Linux; Android 9; SO-01K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SO-01K", + "type": "mobile" + } + }, + { + "desc": "Sony G8141 (Xperia XZ Premium)", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; G8141) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "G8141", + "type": "mobile" + } + }, + { + "desc": "Sony C5303 (Xperia SP)", + "ua": "Mozilla/5.0 (Linux; Android 4.3; C5303 Build/12.1.A.1.205) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.93 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "C5303", + "type": "mobile" + } + }, + { + "desc": "Sony SO-02F (Xperia Z1 F)", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; SO-02F Build/14.1.H.2.119) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SO-02F", + "type": "mobile" + } + }, + { + "desc": "Sony D6653 (Xperia Z3)", + "ua": "Mozilla/5.0 (Linux; Android 4.4; D6653 Build/23.0.A.0.376) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "D6653", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia SOL25 (ZL2)", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4; SOL25 Build/17.1.1.C.1.64) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Sony", + "model": "SOL25", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia SP", + "ua": "Mozilla/5.0 (Linux; Android 4.3; C5302 Build/12.1.A.1.201) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "C5302", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia L4", + "ua": "Mozilla/5.0 (Linux; Android 9; XQ-AD51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AD51", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia 1ii", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AT51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AT51", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia 1ii", + "ua": "Mozilla/5.0 (Linux; Android 10; SOG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SOG01", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia 10ii", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AU52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AU52", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AQ52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AQ52", + "type": "mobile" + } + }, + { + "desc": "Sony SGP521 (Xperia Z2 Tablet)", + "ua": "Mozilla/5.0 (Linux; Android 4.4; SGP521 Build/17.1.A.0.432) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, + { + "desc": "Sony Xperia Z2 Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SGP561) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, + { + "desc": "Sony Tablet S", + "ua": "Mozilla/5.0 (Linux; U; Android 3.1; Sony Tablet S Build/THMAS10000) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, + { + "desc": "Sony Tablet Z LTE", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1; SonySGP321 Build/10.2.C.0.143) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, + { + "desc": "Sony BRAVIA 4K GB ATV3", + "ua": "Mozilla/5.0 (Linux; Andr0id 9; BRAVIA 4K GB ATV3 Build/PTT1.190515.001.S38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.0.180.DIA5.104 Model/Sony-BRAVIA-4K-GB-ATV3", + "expect": { + "vendor": "Sony", + "model": "BRAVIA 4K GB ATV3", + "type": "smarttv" + } + }, + { + "desc": "Sony BRAVIA 4K GB ATV3", + "ua": "Mozilla/5.0 (Linux; Android 9; BRAVIA 4K GB ATV3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "BRAVIA 4K GB ATV3", + "type": "smarttv" + } + }, + { + "desc": "Sony Bravia 4k UR2", + "ua": "Mozilla/5.0 (Linux: Andr0id 9: BRAVIA 4K UR2 Build/PTT1.190515.001.S104) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.5.431.DIA5HBBTV.250 Model/Sony-BRAVIA-4K-UR2", + "expect": { + "vendor": "Sony", + "model": "BRAVIA 4K UR2", + "type": "smarttv" + } + }, + { + "desc": "PlayStation 4", + "ua": "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", + "expect": { + "vendor": "Sony", + "model": "PlayStation 4", + "type": "console" + } + }, + { + "desc": "PlayStation 5", + "ua": "Mozilla/5.0 (Playstation; Playstation 5/1.05) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15", + "expect": { + "vendor": "Sony", + "model": "Playstation 5", + "type": "console" + } + }, + { + "desc": "PlayStation Vita", + "ua": "Mozilla/5.0 (PlayStation Vita 3.52) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2", + "expect": { + "vendor": "Sony", + "model": "PlayStation Vita", + "type": "console" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/tcl.json b/test/specs/devices/tcl.json new file mode 100644 index 0000000..1ea07a3 --- /dev/null +++ b/test/specs/devices/tcl.json @@ -0,0 +1,479 @@ +[ + { + "desc": "TCL 10 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; T790Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 EdgA/114.0.1823.43", + "expect": { + "vendor": "TCL", + "model": "T790Y", + "type": "mobile" + } + }, + { + "desc": "TCL 10 5G UW", + "ua": "Mozilla/5.0 (Linux; Android 10; T790S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T790S", + "type": "mobile" + } + }, + { + "desc": "TCL 10 Plus", + "ua": "Mozilla/5.0 (Linux; Android 11; T782H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Mobile Safari/537.36 OPR/64.3.3282.60839", + "expect": { + "vendor": "TCL", + "model": "T782H", + "type": "mobile" + } + }, + { + "desc": "TCL 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; T799B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T799B", + "type": "mobile" + } + }, + { + "desc": "TCL 10 SE", + "ua": "Mozilla/5.0 (Linux; Android 10; T766H_RU) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T766H", + "type": "mobile" + } + }, + { + "desc": "TCL 10 TabMax", + "ua": "Mozilla/5.0 (Linux; Android 11; 9296Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9296Q", + "type": "tablet" + } + }, + { + "desc": "TCL 10 TabMax 4G", + "ua": "Mozilla/5.0 (Linux; Android 10; 9295G_EEA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9295G", + "type": "tablet" + } + }, + { + "desc": "TCL 10 TabMax WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; 9296G_TR) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9296G", + "type": "tablet" + } + }, + { + "desc": "TCL 10L", + "ua": "Mozilla/5.0 (Linux; Android 10; T770B Build/QKQ1.200329.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 GSA/11.41.10.23.arm64", + "expect": { + "vendor": "TCL", + "model": "T770B", + "type": "mobile" + } + }, + { + "desc": "TCL 10L", + "ua": "Mozilla/5.0 (Linux; Android 11; T770H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T770H", + "type": "mobile" + } + }, + { + "desc": "TCL 20 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; T781) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T781", + "type": "mobile" + } + }, + { + "desc": "TCL 20 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T810S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Mobile Safari/537.36 EdgA/113.0.1774.63", + "expect": { + "vendor": "TCL", + "model": "T810S", + "type": "mobile" + } + }, + { + "desc": "TCL 20 SE", + "ua": "Mozilla/5.0 (Linux; Android 11; T671H Build/RKQ1.201112.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.73 Mobile Safari/537.36 GoogleApp/13.9.7.23.arm64", + "expect": { + "vendor": "TCL", + "model": "T671H", + "type": "mobile" + } + }, + { + "desc": "TCL 20 XE", + "ua": "Mozilla/5.0 (Linux; Android 11; 5087Z) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "5087Z", + "type": "mobile" + } + }, + { + "desc": "TCL 20B", + "ua": "Mozilla/5.0 (Linux; Android 11; 6159K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "6159K", + "type": "mobile" + } + }, + { + "desc": "TCL 205", + "ua": "Mozilla/5.0 (Linux; Android 11; 4187D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "4187D", + "type": "mobile" + } + }, + { + "desc": "TCL 20E", + "ua": "Mozilla/5.0 (Linux; Android 11; 6125A) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/18.0 Chrome/99.0.4844.88 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "6125A", + "type": "mobile" + } + }, + { + "desc": "TCL 20L", + "ua": "Mozilla/5.0 (Linux; Android 11; T774H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.59 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T774H", + "type": "mobile" + } + }, + { + "desc": "TCL 20L Plus", + "ua": "Mozilla/5.0 (Linux; Android 11; T775H Build/RKQ1.210107.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T775H", + "type": "mobile" + } + }, + { + "desc": "TCL 20R 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; T767H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36 OPR/71.3.3718.67322", + "expect": { + "vendor": "TCL", + "model": "T767H", + "type": "mobile" + } + }, + { + "desc": "TCL 20S", + "ua": "Mozilla/5.0 (Linux; Android 11; T773O) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T773O", + "type": "mobile" + } + }, + { + "desc": "TCL 20Y", + "ua": "Mozilla/5.0 (Linux; Android 11; 6156D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.134 Mobile Safari/537.36 OPR/70.3.3653.66287", + "expect": { + "vendor": "TCL", + "model": "6156D", + "type": "mobile" + } + }, + { + "desc": "TCL 30 V 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; T781S Build/RKQ1.210614.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/369.0.0.5.110;]", + "expect": { + "vendor": "TCL", + "model": "T781S", + "type": "mobile" + } + }, + { + "desc": "TCL 30 XE 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T767W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/416.0.0.35.85;]", + "expect": { + "vendor": "TCL", + "model": "T767W", + "type": "mobile" + } + }, + { + "desc": "TCL 305", + "ua": "Mozilla/5.0 (Linux; arm; Android 11; 6102D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.167 YaBrowser/22.7.6.96.00 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "6102D", + "type": "mobile" + } + }, + { + "desc": "TCL 306", + "ua": "Mozilla/5.0 (Linux; Android 12; 6102H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.141 Mobile Safari/537.36[FBAN/EMA;FBLC/it_IT;FBAV/332.0.0.22.108;]", + "expect": { + "vendor": "TCL", + "model": "6102H", + "type": "mobile" + } + }, + { + "desc": "TCL 30", + "ua": "Mozilla/5.0 (Linux; Android 12; T676H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T676H", + "type": "mobile" + } + }, + { + "desc": "TCL 30+", + "ua": "Mozilla/5.0 (Linux; Android 12; T676J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T676J", + "type": "mobile" + } + }, + { + "desc": "TCL 30 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T776H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T776H", + "type": "mobile" + } + }, + { + "desc": "TCL 30 LE", + "ua": "Mozilla/5.0 (Linux; Android 12; 4188V Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/352.0.0.14.108;]", + "expect": { + "vendor": "TCL", + "model": "4188V", + "type": "mobile" + } + }, + { + "desc": "TCL 30 SE", + "ua": "Mozilla/5.0 (Linux; Android 12; 6165H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/396.1.0.28.104;]", + "expect": { + "vendor": "TCL", + "model": "6165H", + "type": "mobile" + } + }, + { + "desc": "TCL 30E", + "ua": "Mozilla/5.0 (Linux; Android 12; 6127I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "6127I", + "type": "mobile" + } + }, + { + "desc": "TCL 40 NxtPaper", + "ua": "Mozilla/5.0 (Linux; Android 13; T612B Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.53 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T612B", + "type": "mobile" + } + }, + { + "desc": "TCL A3", + "ua": "Mozilla/5.0 (Linux; Android 11; A509DL Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Mobile Safari/537.36 GSA/13.18.7.23.arm64", + "expect": { + "vendor": "TCL", + "model": "A509DL", + "type": "mobile" + } + }, + { + "desc": "TCL A30", + "ua": "Mozilla/5.0 (Linux; Android 11; 5102L Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/413.0.0.30.104;]", + "expect": { + "vendor": "TCL", + "model": "5102L", + "type": "mobile" + } + }, + { + "desc": "TCL 40 SE", + "ua": "Mozilla/5.0 (Linux; Android 13; T610K Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T610K", + "type": "mobile" + } + }, + { + "desc": "TCL 40 XE 5G", + "ua": "Mozilla/5.0 (Linux; Android 13; T609DL Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.136 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/466.1.0.57.85;]", + "expect": { + "vendor": "TCL", + "model": "T609DL", + "type": "mobile" + } + }, + { + "desc": "TCL 403", + "ua": "Mozilla/5.0 (Linux; Android 12; T431D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T431D", + "type": "mobile" + } + }, + { + "desc": "TCL 405", + "ua": "Mozilla/5.0 (Linux; Android 12; T506D Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]", + "expect": { + "vendor": "TCL", + "model": "T506D", + "type": "mobile" + } + }, + { + "desc": "TCL 408", + "ua": "Mozilla/5.0 (Linux; U; Android 12; T507U Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/105.0.5195.136 Mobile Safari/537.36 OPR/75.0.2254.68857", + "expect": { + "vendor": "TCL", + "model": "T507U", + "type": "mobile" + } + }, + { + "desc": "TCL 40R 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T771K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 EdgA/114.0.1823.37", + "expect": { + "vendor": "TCL", + "model": "T771K", + "type": "mobile" + } + }, + { + "desc": "TCL Ion X", + "ua": "Mozilla/5.0 (Linux; Android 12; T430W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.60 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T430W", + "type": "mobile" + } + }, + { + "desc": "TCL NxtPaper 11", + "ua": "Mozilla/5.0 (Linux; Android 13; 9466X Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.179 Safari/537.36 [FB_IAB/FB4A;FBAV/473.0.0.41.81;]", + "expect": { + "vendor": "TCL", + "model": "9466X", + "type": "tablet" + } + }, + { + "desc": "TCL Stylus 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T779W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.2 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T779W", + "type": "mobile" + } + }, + { + "desc": "TCL Tab 8 4G", + "ua": "Mozilla/5.0 (Linux; Android 10; 9048S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9048S", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 8 LE", + "ua": "Mozilla/5.0 (Linux; Android 12; 9137W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9137W", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10 FHD 4G", + "ua": "Mozilla/5.0 (Linux; Android 11; 9060G Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.196 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9060G", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10 HD 4G", + "ua": "Mozilla/5.0 (Linux; Android 11; 9060X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9060X", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10 LTE", + "ua": "Mozilla/5.0 (Linux; Android 13; 8196G Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.162 Safari/537.36 [FB_IAB/FB4A;FBAV/471.0.0.35.80;]", + "expect": { + "vendor": "TCL", + "model": "8196G", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 13; 8496G Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.61 Safari/537.36 [FB_IAB/FB4A;FBAV/474.0.0.52.74;]", + "expect": { + "vendor": "TCL", + "model": "8496G", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10L", + "ua": "Mozilla/5.0 (Linux; Android 11; 8491X_EEA Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.105 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "8491X", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10s 4G", + "ua": "Mozilla/5.0 (Linux; Android 11; 9080G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9080G", + "type": "tablet" + } + }, + { + "desc": "TCL Xess P17AA", + "ua": "Mozilla/5.0 (Linux; Android 5.1; TCL Xess P17AA Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "Xess P17AA", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/technisat.json b/test/specs/devices/technisat.json new file mode 100644 index 0000000..e9dca81 --- /dev/null +++ b/test/specs/devices/technisat.json @@ -0,0 +1,20 @@ +[ + { + "desc": "TechniSAT Digit ISIO S SAT receiver", + "ua": "Opera/9.80 (Linux sh4; U; HbbTV/1.1.1 (;;;;;); CE-HTML; TechniSat Digit ISIO S; de) Presto/2.9.167 Version/11.50", + "expect": { + "vendor": "TechniSat", + "model": "Digit ISIO S", + "type": "smarttv" + } + }, + { + "desc": "TechniSAT MultyVision SmartTV", + "ua": "Opera/9.80 (Linux i686; U; HbbTV/1.1.1 (;;;;;); CE-HTML; TechniSat MultyVision ISIO; de) Presto/2.9.167 Version/11.50", + "expect": { + "vendor": "TechniSat", + "model": "MultyVision ISIO", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/tecno.json b/test/specs/devices/tecno.json new file mode 100644 index 0000000..a002fcf --- /dev/null +++ b/test/specs/devices/tecno.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Tecno KC8", + "ua": "Mozilla/5.0 (Linux; Android 10; TECNO KC8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TECNO", + "model": "KC8", + "type": "mobile" + } + }, + { + "desc": "Tecno Spark 8C", + "ua": "Mozilla/5.0 (Linux; Android 11; TECNO KG5n) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TECNO", + "model": "KG5n", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/tesla.json b/test/specs/devices/tesla.json new file mode 100644 index 0000000..34faa35 --- /dev/null +++ b/test/specs/devices/tesla.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Tesla", + "ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", + "expect": { + "vendor": "Tesla", + "model": "undefined", + "type": "embedded" + } + }, + { + "desc": "Tesla", + "ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/79.0.3945.130 Chrome/79.0.3945.130 Safari/537.36 Tesla/2020.16.2.1-e99c70fff409", + "expect": { + "vendor": "Tesla", + "model": "undefined", + "type": "embedded" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/ulefone.json b/test/specs/devices/ulefone.json new file mode 100644 index 0000000..c7aff32 --- /dev/null +++ b/test/specs/devices/ulefone.json @@ -0,0 +1,92 @@ +[ + { + "desc": "Ulefone Armor", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Armor Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.107 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Armor", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 6.0; Armor) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 YaBrowser/20.4.2.101.00 SA/1 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Armor", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor 8 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; Armor 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.1.3922.71199", + "expect": { + "vendor": "Ulefone", + "model": "Armor 8 Pro", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor 12 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; Armor 12 5G Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Armor 12 5G", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor 20WT", + "ua": "Mozilla/5.0 (Linux; Android 12; Armor 20WT) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Armor 20WT", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor Pad", + "ua": "Mozilla/5.0 (Linux; Android 12; Armor Pad Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/431.0.0.30.108;]", + "expect": { + "vendor": "Ulefone", + "model": "Armor Pad", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor X5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; Armor X5 Pro Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/430.0.0.23.113;]", + "expect": { + "vendor": "Ulefone", + "model": "Armor X5 Pro", + "type": "mobile" + } + }, + { + "desc": "Ulefone Power Armor 14 Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor14 Pro Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.138 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Power Armor14 Pro", + "type": "mobile" + } + }, + { + "desc": "Ulefone Power Armor 18T", + "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor 18T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Power Armor 18T", + "type": "mobile" + } + }, + { + "desc": "Ulefone Power Armor 19T", + "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor 19T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.3.3922.71982", + "expect": { + "vendor": "Ulefone", + "model": "Power Armor 19T", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/vivo.json b/test/specs/devices/vivo.json new file mode 100644 index 0000000..cad62f9 --- /dev/null +++ b/test/specs/devices/vivo.json @@ -0,0 +1,74 @@ +[ + { + "desc": "Vivo S1 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; vivo 1920) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Vivo", + "model": "1920", + "type": "mobile" + } + }, + { + "desc": "Vivo Y52s", + "ua": "Mozilla/5.0 (Linux; Android 10; V2057A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.10 SP-engine/2.28.0 baiduboxapp/12.10.0.10 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Vivo", + "model": "V2057A", + "type": "mobile" + } + }, + { + "desc": "Vivo X60", + "ua": "Mozilla/5.0 (Linux; Android 11; V2046A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.8.71.0", + "expect": { + "vendor": "Vivo", + "model": "V2046A", + "type": "mobile" + } + }, + { + "desc": "Vivo Y79A", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; vivo Y79A Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", + "expect": { + "vendor": "Vivo", + "model": "Y79A", + "type": "mobile" + } + }, + { + "desc": "Vivo Y93", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; vivo 1814) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Vivo", + "model": "1814", + "type": "mobile" + } + }, + { + "desc": "Vivo Y97", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; V1813T Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", + "expect": { + "vendor": "Vivo", + "model": "V1813T", + "type": "mobile" + } + }, + { + "desc": "Vivo iQOO Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; V1916A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.1.10.6", + "expect": { + "vendor": "Vivo", + "model": "V1916A", + "type": "mobile" + } + }, + { + "desc": "Vivo 1906 (Y11)", + "ua": "Mozilla/5.0 (Linux; Android 11; vivo 1906) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Vivo", + "model": "1906", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/xiaomi.json b/test/specs/devices/xiaomi.json new file mode 100644 index 0000000..688bd61 --- /dev/null +++ b/test/specs/devices/xiaomi.json @@ -0,0 +1,524 @@ +[ + { + "desc": "Xiaomi 2201117TG", + "ua": "Mozilla/5.0 (Linux; Android 11; 2201117TG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.98 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "2201117TG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi M2004J19C", + "ua": "Mozilla/5.0 (Linux; Android 11; M2004J19C Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.77 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2004J19C", + "type": "mobile" + } + }, + { + "desc": "Xiaomi M2006C3MNG", + "ua": "Mozilla/5.0 (Linux; Android 11; M2006C3MNG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2006C3MNG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi 21061119DG", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; 21061119DG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 YaBrowser/23.3.7.24.00 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "21061119DG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi 2013023", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; en-US; 2013023 Build/HM2013023) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/10.0.1.512 U3/0.8.0 Mobile Safari/533.1", + "expect": { + "vendor": "Xiaomi", + "model": "2013023", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Hongmi Note 1W", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-CN; HM NOTE 1W Build/JDQ39) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.7.9.439 U3/0.8.0 Mobile Safari/533.1", + "expect": { + "vendor": "Xiaomi", + "model": "HM NOTE 1W", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 3C", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; zh-CN; MI 3C Build/JLS36C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.7.9.439 U3/0.8.0 Mobile Safari/533.1", + "expect": { + "vendor": "Xiaomi", + "model": "MI 3C", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 5", + "ua": "Mozilla/5.0 (Linux; Android 7.0; MI 5 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.83 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI 5", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 6", + "ua": "Mozilla/5.0 (Linux; Android 7.1; MI 6 Build/NMF26X; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.125 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI 6", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 10 Pro", + "ua": "Linux; U; Android 13; Mi 10 Pro Build/TKQ1.221114.001", + "expect": { + "vendor": "Xiaomi", + "model": "Mi 10 Pro", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 5s Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; MI 5s Plus Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/8.7.1", + "expect": { + "vendor": "Xiaomi", + "model": "MI 5s Plus", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Mi A1 Build/OPR1.170623.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A1", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi Note", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; MI NOTE LTE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI NOTE LTE", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi One Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; MI-ONE Plus Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Xiaomi", + "model": "MI-ONE Plus", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi Max 3", + "ua": "Mozilla/5.0 (Linux; Android 9; MI MAX 3 Build/PKQ1.181007.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI MAX 3", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A1", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.101 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A1", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A2 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2 Lite) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A2 Lite", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 9 SE", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi 9 SE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi 9 SE", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A2", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A2", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi CC9", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-cn; MI CC 9 Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.116 Mobile Safari/537.36 XiaoMi/MiuiBrowser/15.5.18", + "expect": { + "vendor": "Xiaomi", + "model": "MI CC 9", + "type": "mobile" + } + }, + { + "desc": "Xiaomi MI PAD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; en-us; MI PAD Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.3.2", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 2", + "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 2", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 2", + "ua": "Mozilla/5.0 (Linux; x86_64; Android 5.1; MI PAD 2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 YaBrowser/20.11.2.69.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 2", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 3", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.0; MI PAD 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.216 YaBrowser/21.5.6.56.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 3", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 4", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 8.1.0; MI PAD 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 YaBrowser/19.9.1.126.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 4", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 4 PLUS", + "ua": "Mozilla/5.0 (Linux; Android 8.1; MI PAD 4 PLUS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 4 PLUS", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 4 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 8.1; Mi Pad4 Wi-Fi) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Mobile Safari/537.36 EdgA/86.0.622.61", + "expect": { + "vendor": "Xiaomi", + "model": "Mi Pad4 Wi-Fi", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5", + "ua": "Mozilla/5.0 (Linux; Android 13; 21051182G Build/TKQ1.221013.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Xiaomi", + "model": "21051182G", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; M2105K81AC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Safari/537.36 Line/13.15.1/IAB", + "expect": { + "vendor": "Xiaomi", + "model": "M2105K81AC", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; M2105K81C) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2105K81C", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 6 Max 14", + "ua": "Mozilla/5.0 (Linux; U; Android 14; zh-tw; 2307BRPDCC Build/UKQ1.230804.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.118 Mobile Safari/537.36 Device/yudi Model/2307BRPDCC XiaoMi/MiuiBrowser/14.10.6", + "expect": { + "vendor": "Xiaomi", + "model": "2307BRPDCC", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 6 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 13; en-US; 23046RP50C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.6.2.1316 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "23046RP50C", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Pad 6S Pro 12.4", + "ua": "Mozilla/5.0 (Linux; Android 14; 24018RPACC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "24018RPACC", + "type": "tablet" + } + }, + { + "desc": "Xiaomi POCO X2", + "ua": "Mozilla/5.0 (Linux; Android 10; POCO X2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "POCO X2", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO X3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; M2102J20SI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2102J20SI", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO X3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; M2102J20SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2102J20SG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO X3 NFC", + "ua": "Mozilla/5.0 (Linux; Android 12; M2007J20CG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2007J20CG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO M2 Pro", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; POCO M2 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 YaBrowser/22.11.7.42.00 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "POCO M2 Pro", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO M3", + "ua": "Mozilla/5.0 (Linux; Android 10; M2010J19CI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2010J19CI", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCOPHONE F1", + "ua": "Mozilla/5.0 (Linux; Android 10; POCOPHONE F1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "POCOPHONE F1", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi 4A", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Redmi 4A Build/MMB29M; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi 4A", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi 10C", + "ua": "Mozilla/5.0 (Linux; Android 12; 220333QAG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "220333QAG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi K30 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 5G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi K30 5G", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi K30 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi K30 Pro", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi Note 3", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Redmi Note 3 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.116 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 3", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi Note 9 Pro Max", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9 Pro Max) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.99 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 9 Pro Max", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 9S", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 9S", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 10 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; M2103K19C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2103K19C", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 13; M2101K6P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2101K6P", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; M2101K6G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2101K6G", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 8", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 8", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 12 Turbo", + "ua": "Mozilla/5.0 (Linux; Android 13; 23049RAD8C; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/16.7.1.1", + "expect": { + "vendor": "Xiaomi", + "model": "23049RAD8C", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Pad", + "ua": "Mozilla/5.0 (Linux; U; Android 12; id-id; Redmi Pad Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36 XiaoMi/MiuiBrowser/14.1.1-gn", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Pad", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad", + "ua": "Mozilla/5.0 (Linux; Android 14; 22081283G Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Xiaomi", + "model": "22081283G", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad Pro", + "ua": "Mozilla/5.0 (Linux; Android 14; 2405CRPFDG Build/UKQ1.240116.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.97 Safari/537.36 [FB_IAB/FB4A;FBAV/476.0.0.49.74;] FBNV/1", + "expect": { + "vendor": "Xiaomi", + "model": "2405CRPFDG", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad SE", + "ua": "Dalvik/2.1.0 (Linux; U; Android 14; 23073RPBFG Build/UKQ1.231003.002)", + "expect": { + "vendor": "Xiaomi", + "model": "23073RPBFG", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad SE 8.7", + "ua": "Mozilla/5.0 (Linux; Android 14; 24076RP19G Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Mobile Safari/537.36 Line/14.18.1/IAB", + "expect": { + "vendor": "Xiaomi", + "model": "24076RP19G", + "type": "tablet" + } + }, + { + "desc": "Xiaomi TV", + "ua": "Mozilla/5.0 (Linux; Android 10; MiTV-MOOQ0 Build/QTG3.200305.006; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.61 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MiTV-MOOQ0", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/specs/devices/zte.json b/test/specs/devices/zte.json new file mode 100644 index 0000000..5b43bea --- /dev/null +++ b/test/specs/devices/zte.json @@ -0,0 +1,11 @@ +[ + { + "desc": "ZTE Blade A6", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE BLADE A0620 Build/NMF26F; ru-ru) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.2.0.50586AP", + "expect": { + "vendor": "ZTE", + "model": "BLADE A0620", + "type": "mobile" + } + } +] \ No newline at end of file From b4bc86ac6d887d64b959bd73a16c7141d57f602b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 21 Nov 2024 23:18:38 +0700 Subject: [PATCH 13/73] Improve device detection: Lenovo --- src/main/ua-parser.js | 6 +- test/specs/devices/lenovo.json | 1042 +++++++++++++++++++++++++++++++- 2 files changed, 1037 insertions(+), 11 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index a3b867e..067a3e3 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -588,8 +588,8 @@ ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo - /(ideatab[-\w ]+)/i, - /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i + /(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i, + /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [ // Nokia @@ -701,7 +701,7 @@ /(hp) ([\w ]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia - /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo + /(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i, // Lenovo /(jolla)/i, // Jolla /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ diff --git a/test/specs/devices/lenovo.json b/test/specs/devices/lenovo.json index 2ffc886..526a3b5 100644 --- a/test/specs/devices/lenovo.json +++ b/test/specs/devices/lenovo.json @@ -1,10 +1,154 @@ -[ +[ { - "desc": "Lenovo Tab 2", - "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Lenovo TAB 2 A7-30HC Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Safari/537.36", + "desc": "Lenovo A7", + "ua": "Mozilla/5.0 (Linux; U; Android 9; en-US; Lenovo L19111 Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/13.2.8.1301 Mobile Safari/537.36", "expect": { "vendor": "Lenovo", - "model": "TAB 2 A7", + "model": "L19111", + "type": "mobile" + } + }, + { + "desc": "Lenovo A8", + "ua": "Mozilla/5.0 (Linux; Android 10; Lenovo L10041) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.73 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L10041", + "type": "mobile" + } + }, + { + "desc": "Lenovo dtab Compact 42A", + "ua": "Mozilla/5.0 (Linux; Android 12; d-42A Build/SKQ1.220201.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.125 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "d-42A", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab A7-50", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo A3500-HV Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "A3500-HV", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab A2109A", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; ru-ru; A2109A Build/JDQ39; CyanogenMod-10.1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "A2109A", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab S6000", + "ua": "Mozilla/5.0 (Linux; Android 6.0; S6000 Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/55.0.2883.91 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "S6000", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab S6000", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; IdeaTab S6000-H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 YaBrowser/18.11.1.1011.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "IdeaTab S6000-H", + "type": "tablet" + } + }, + { + "desc": "Lenovo K5 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 9;zh-cn; Lenovo L38041 Build/PKQ1.190127.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.117 MobileLenovoBrowser/9.1.3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L38041", + "type": "mobile" + } + }, + { + "desc": "Lenovo K9", + "ua": "Mozilla/5.0 (Linux; U; Android 8.1.0; en-US; Lenovo L38043 Build/O11019) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11.4.8.1012 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L38043", + "type": "mobile" + } + }, + { + "desc": "Lenovo K10 Plus", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo L39051) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.66 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L39051", + "type": "mobile" + } + }, + { + "desc": "Lenovo K12", + "ua": "Mozilla/5.0 (Linux; Android 10; Lenovo XT2081-4 Build/QCZ30.30-Q3-45-17; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/409.0.0.27.106;]", + "expect": { + "vendor": "Lenovo", + "model": "XT2081-4", + "type": "mobile" + } + }, + { + "desc": "Lenovo K12", + "ua": "Mozilla/5.0 (Linux; U; Android 10; Lenovo K12 Build/QOGS30.569-83-18; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.130 Mobile Safari/537.36 OPR/69.0.2254.66073", + "expect": { + "vendor": "Lenovo", + "model": "K12", + "type": "mobile" + } + }, + { + "desc": "Lenovo Legion 2 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; Lenovo L70081 Build/RKQ1.201112.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.58 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L70081", + "type": "mobile" + } + }, + { + "desc": "Lenovo Legion Y90", + "ua": "Mozilla/5.0 (Linux; U; Android 12;en-us; Lenovo L71061/SKQ1.211113.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.132 MobileLenovoBrowser/8.6.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L71061", + "type": "mobile" + } + }, + { + "desc": "Lenovo Legion Y700", + "ua": "Mozilla/5.0 (Linux; U; Android 13;zh-cn; Lenovo TB-9707F Build/TKQ1.221013.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.117 MobileLenovoBrowser/2.1.7 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-9707F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Legion Y700", + "ua": "Mozilla/5.0 (Linux; Android 12; TB320FC) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB320FC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Moto Tab", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; TB-X704A Build/NMF26F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X704A", "type": "tablet" } }, @@ -17,6 +161,141 @@ "type": "mobile" } }, + { + "desc": "Lenovo S5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo L58041) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L58041", + "type": "mobile" + } + }, + { + "desc": "Lenovo Smart Tab M8", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 10; Lenovo TB-8505XS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 YaBrowser/21.11.7.71.00 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8505XS", + "type": "tablet" + } + }, + { + "desc": "Lenovo Smart Tab M8", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 10; Lenovo TB-8505FS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.166 YaBrowser/21.8.4.111.00 (beta) SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8505FS", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 2", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Lenovo TAB 2 A7-30HC Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7-30HC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 2 A7", + "ua": "Mozilla/5.0 (Linux; Android 7.0.99; Lenovo TAB 2 A7-30DC Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.141 Safari/537.36 OPR/45.1.2246.125351", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7-30DC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 2 A10", + "ua": "Mozilla/5.0 (Linux; U; Android 5.0.1; Lenovo TAB 2 A10-70L Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.116 Safari/537.36 OPR/29.0.2254.120398", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A10-70L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 2 A10-30", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; TB2-X30F Build/LenovoTB2-X30F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Mobile Safari/537.36 EdgA/90.0.818.49", + "expect": { + "vendor": "Lenovo", + "model": "TB2-X30F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 7", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Lenovo TB3-730X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB3-730X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 7 Essential", + "ua": "Mozilla/5.0 (Linux; Android 5.1; Lenovo TB3-710I Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.127 Safari/537.36 GSA/5.4.28.19.arm", + "expect": { + "vendor": "Lenovo", + "model": "TB3-710I", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 7 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; en-US; Lenovo TB-7703X Build/S100) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.2.5.1102 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7703X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 8 Dual", + "ua": "Mozilla/5.0 (Linux; Android 6.0; 602LV Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/93.0.4577.82 Safari/537.36 GSA/12.36.22.23.arm64", + "expect": { + "vendor": "Lenovo", + "model": "602LV", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 8 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; Lenovo TB-8703F Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/9.8 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8703F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 8 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; Lenovo TB-8703X Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/65.0.3325.109 Safari/537.36 OPR/33.0.2254.125672", + "expect": { + "vendor": "Lenovo", + "model": "TB-8703X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 10 Business", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; Lenovo TB3-X70F Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Safari/537.36 OPR/32.0.2254.123747", + "expect": { + "vendor": "Lenovo", + "model": "TB3-X70F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 10 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; Lenovo TB3-X70L Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/86.0.4240.185 Safari/537.36 OPR/52.1.2254.54298", + "expect": { + "vendor": "Lenovo", + "model": "TB3-X70L", + "type": "tablet" + } + }, { "desc": "Lenovo Tab 3 Pro", "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X90F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", @@ -40,7 +319,115 @@ "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo TAB 2 A7-30HC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", "expect": { "vendor": "Lenovo", - "model": "TAB 2 A7", + "model": "TAB 2 A7-30HC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Lenovo TB-8504F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Mobile Safari/537.36 OPR/64.2.3282.60128", + "expect": { + "vendor": "Lenovo", + "model": "TB-8504F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8", + "ua": "Mozilla/5.0 (Linux; U; Android 8.1.0; Lenovo TB-8504X Build/OPM1.171019.019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36 OPR/52.2.2254.54723", + "expect": { + "vendor": "Lenovo", + "model": "TB-8504X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8 Plus", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 8.1.0; Lenovo TB-8704F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 YaApp_Android/21.21.0/apad YaSearchBrowser/21.21.0/apad BroPP/1.0 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8704F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8 Plus", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; TB-8704V Build/OPM1.171019.019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/104.0.5112.97 Safari/537.36 [FB_IAB/FB4A;FBAV/380.0.0.29.109;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-8704V", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8 Plus", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 8.1.0; Lenovo TB-8704X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 YaBrowser/19.10.4.187.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8704X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8 REL", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo TB-8X04F Build/NMF26F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.100 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8X04F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 10", + "ua": "Mozilla/5.0 (Linux; U; Android 8.1.0; Lenovo TB-X304L Build/OPM1.171019.026; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.149 Safari/537.36 OPR/47.0.2254.146760", + "expect": { + "vendor": "Lenovo", + "model": "TB-X304L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 10 Plus", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.1.1; Lenovo TB-X704L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 YaBrowser/20.12.4.100.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X704L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 10 Plus", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.1.1; Lenovo TB-X704F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 YaBrowser/20.8.5.97.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X704F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 6", + "ua": "Mozilla/5.0 (Linux; Android 11; A101LV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.61 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "A101LV", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 7", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Lenovo TB-7504X Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/119.0.6045.193 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/436.0.0.35.101;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-7504X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 7 Essential", + "ua": "Mozilla/5.0 (Linux; U; Android 7.0; Lenovo TB-7304I Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Safari/537.36 OPR/54.0.2254.56148", + "expect": { + "vendor": "Lenovo", + "model": "TB-7304I", "type": "tablet" } }, @@ -53,6 +440,177 @@ "type": "tablet" } }, + { + "desc": "Lenovo Tab 10 10.1", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo TB-X103F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X103F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab E7", + "ua": "Mozilla/5.0 (Linux; arm; Android 8.1.0; Lenovo TB-7104I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 BroPP/1.0 SA/3 Mobile Safari/537.36 YandexSearch/7.52/apad YandexSearchBrowser/7.52", + "expect": { + "vendor": "Lenovo", + "model": "TB-7104I", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab E8", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.0; Lenovo TB-8304F1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 YaBrowser/19.7.4.97.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8304F1", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab K10", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-X6C6X Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X6C6X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab K10", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-X6C6F Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.83 Safari/537.36 [FB_IAB/FB4A;FBAV/488.0.0.78.79;IABMV/1;] FBNV/5", + "expect": { + "vendor": "Lenovo", + "model": "TB-X6C6F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab K11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 10; Lenovo TB-J606N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 YaApp_Android/22.31.1/apad YaSearchBrowser/22.31.1/apad BroPP/1.0 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J606N", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab K11 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-J607Z Build/SKQ1.211103.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.58 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J607Z", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M7", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-7305X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Mobile Safari/537.36 OPR/63.3.3216.58675", + "expect": { + "vendor": "Lenovo", + "model": "TB-7305X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M7", + "ua": "Mozilla/5.0 (Linux; arm; Android 9; Lenovo TB-7305I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 YaApp_Android/20.85.0/apad YaSearchBrowser/20.85.0/apad BroPP/1.0 SA/1 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7305I", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M7 (Gen 3)", + "ua": "Mozilla/5.0 (Linux; Android 11; Lenovo TB-7306F Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-7306F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M7 (Gen 3)", + "ua": "Mozilla/5.0 (Linux; arm; Android 11; Lenovo TB-7306X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 YaBrowser/20.12.5.127.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7306X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8", + "ua": "Mozilla/5.0 (Linux; Android 10; Lenovo TB-8505X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8505X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-8505F Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36 GSA/10.82.8.21.arm64", + "expect": { + "vendor": "Lenovo", + "model": "TB-8505F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8 (Gen 3)", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-TW; Lenovo TB-8506X Build/RP1A.200720.011) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.4.0.1306 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8506X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8 (Gen 4)", + "ua": "Mozilla/5.0 (Linux; Android 13; TB300FU Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/417.0.0.9.97;]", + "expect": { + "vendor": "Lenovo", + "model": "TB300FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8 (Gen 4) (2024)", + "ua": "Mozilla/5.0 (Linux; Android 13; TB301FU Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.170 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/472.0.0.45.79;]", + "expect": { + "vendor": "Lenovo", + "model": "TB301FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8 FHD", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-8705X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.99 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8705X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; Android 12; TB310FU) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB310FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; 13; TB310XU) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB310XU", + "type": "tablet" + } + }, { "desc": "Lenovo Tab M10", "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X606F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 YaBrowser/20.9.4.99.01 Safari/537.36", @@ -63,12 +621,480 @@ } }, { - "desc": "Lenovo IdeaTab S6000", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; IdeaTab S6000-H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 YaBrowser/18.11.1.1011.01 Safari/537.36", + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Android 14; Mobile; Lenovo TB-X505F; rv:131.0) Gecko/131.0 Firefox/131.0", "expect": { "vendor": "Lenovo", - "model": "IdeaTab S6000-H", + "model": "TB-X505F", "type": "tablet" } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; Android 14; Lenovo TB-X505L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6554.180 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X505L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-X605F Build/PKQ1.190319.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Safari/537.36 [FB_IAB/FB4A;FBAV/298.0.0.46.116;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-X605F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; U; Android 10; Lenovo TB-X505X Build/QKQ1.191224.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/81.0.4044.138 Safari/537.36 OPR/52.2.2254.54723", + "expect": { + "vendor": "Lenovo", + "model": "TB-X505X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 (Gen 3) ", + "ua": "Mozilla/5.0 (Linux; Android 12; TB328XU Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.58 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB328XU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 (Gen 3) ", + "ua": "Mozilla/5.0 (Linux; Android 12; TB328FU Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.57 Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]", + "expect": { + "vendor": "Lenovo", + "model": "TB328FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD", + "ua": "Mozilla/5.0 (Linux; Android 13; Lenovo TB-X605FC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6481.193 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X605FC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-X605LC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X605LC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X605L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 YaBrowser/20.12.0.141.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X605L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD Plus", + "ua": "Mozilla/5.0 (Linux; Android 14; Lenovo TB-X606F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6496.93 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD Plus", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-X606FA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5813.205 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606FA", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD Plus", + "ua": "Mozilla/5.0 (Linux; Android 10; Lenovo TB-X606X Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 HD", + "ua": "Mozilla/5.0 (Linux; U; Android 10; it-it; Lenovo TB-X306F Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36 PHX/6.2", + "expect": { + "vendor": "Lenovo", + "model": "TB-X306F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 HD", + "ua": "Mozilla/5.0 (Linux; U; Android 10; it-it; Lenovo TB-X306F Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36 PHX/6.2", + "expect": { + "vendor": "Lenovo", + "model": "TB-X306F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 Plus (Gen 3)", + "ua": "Mozilla/5.0 (Linux; U; Android 10; Lenovo TB-X306X Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/90.0.4430.210 Safari/537.36 OPR/55.1.2254.56965", + "expect": { + "vendor": "Lenovo", + "model": "TB-X306X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M11", + "ua": "Mozilla/5.0 (Linux; Android 14; TB330FU Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.60 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB330FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P10", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X705L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 YaBrowser/21.3.3.160.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X705L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; Lenovo TB-J606L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.2311.135 YaBrowser/21.11.5.121.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J606L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-cn; Lenovo TB-J606F Build/RKQ1.210303.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.72 MQQBrowser/12.1 Mobile Safari/537.36 COVC/045830", + "expect": { + "vendor": "Lenovo", + "model": "TB-J606F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Plus", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-J616X Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-J616X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 (Gen 2)", + "ua": "Mozilla/5.0 (Linux; Android 14; TB350FU Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.46 Safari/537.36 [FB_IAB/FB4A;FBAV/490.0.0.63.82;IABMV/1;]", + "expect": { + "vendor": "Lenovo", + "model": "TB350FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Plus", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-J616F Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/129.0.6668.9 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J616F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-CN; Lenovo TB-J706F Build/RKQ1.201112.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/5.8.6.223 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J706F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; Lenovo TB-J706L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 EdgA/103.0.1264.71", + "expect": { + "vendor": "Lenovo", + "model": "TB-J706L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Pro (Gen 2)", + "ua": "Mozilla/5.0 (Linux; Android 13; TB132FU Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB132FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P12", + "ua": "Mozilla/5.0 (Linux; Android 14; TB370FU Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.106 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB370FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P12 Pro", + "ua": "Mozilla/5.0 (Linux; Android 13; Lenovo TB-Q706F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-Q706F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P12 Pro", + "ua": "Mozilla/5.0 (Linux; Android 13; Lenovo TB-Q706Z Build/TKQ1.221013.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-Q706Z", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab QT K11 WiFi", + "ua": "Mozilla/5.0 (Linux; arm; Android 12; Lenovo TB-J6C6F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.114 YaBrowser/22.9.3.82.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J6C6F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab QT K11 Pro WiFi", + "ua": "Mozilla/5.0 (Linux; Android 11; Lenovo TB-J607F Build/RKQ1.201217.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J607F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab V7", + "ua": "Mozilla/5.0 (Linux; U; Android 9; en-US; Lenovo PB-6505M Build/PKQ1) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.9.9.1155 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "PB-6505M", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab V7", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo PB-6505Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 YaBrowser/20.9.3.85.00 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "PB-6505Y", + "type": "tablet" + } + }, + { + "desc": "Lenovo X3 Lite", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo X3 Lite) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.88 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "X3 Lite", + "type": "mobile" + } + }, + { + "desc": "Lenovo Yoga Smart Tab", + "ua": "Mozilla/5.0 (Android 11; Mobile; Lenovo YT-X705X; rv:129.0) Gecko/129.0 Firefox/129.0", + "expect": { + "vendor": "Lenovo", + "model": "YT-X705X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Smart Tab", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 10; Lenovo YT-X705F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 YaBrowser/20.2.4.153.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT-X705F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Smart Tab", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo YT-X705L Build/PKQ1.181218.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Safari/537.36 GSA/11.38.8.23.arm64", + "expect": { + "vendor": "Lenovo", + "model": "YT-X705L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; Lenovo YT3-X50L Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.149 Safari/537.36 OPR/46.0.2254.145391", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X50L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; Lenovo YT3-X50L Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.149 Safari/537.36 OPR/46.0.2254.145391", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X50L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X50M Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X50M", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 8", + "ua": "Mozilla/5.0(Linux; U; Android 5.1.1; pt-BR; Lenovo YT3-850F Build/LMY47V) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-850F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 8", + "ua": "Mozilla/5.0(Linux; U; Android 5.1.1; lv-LV; Lenovo YT3-850L Build/LMY47V) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-850L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 10", + "ua": "Mozilla/5.0(Linux; U; Android 5.1.1; vi-VN; Lenovo YT3-850M Build/LMY47V) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-850M", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 Plus", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo YT-X703L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 OPR/64.2.3282.60128", + "expect": { + "vendor": "Lenovo", + "model": "YT-X703L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 Plus", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; YT-X703F Build/NJH47F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.141 Safari/537.36 OPR/45.0.2246.125120", + "expect": { + "vendor": "Lenovo", + "model": "YT-X703F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 12; Lenovo YT-J706X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.42 YaBrowser/24.1.1.42.01 (beta) Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT-J706X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 8", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.2; ru-ru; Lenovo B6000; Android/4.4.2; Release/08.26.2015) AppleWebKit/534.30 (KHTML, like Gecko) Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "B6000", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 8", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo B6000-H Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 GSA/7.24.32.16.arm", + "expect": { + "vendor": "Lenovo", + "model": "B6000-H", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 8", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; es-us; Lenovo B6000-F/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.2.2 Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "B6000-F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 10", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; ru-ru; Lenovo B8000-F Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "B8000-F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 10", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; ru-ru; Lenovo B8000-H Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30 Mobile UCBrowser/3.4.3.532", + "expect": { + "vendor": "Lenovo", + "model": "B8000-H", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 10 HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-US; Lenovo B8080-H Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.0.0.1088 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "B8080-H", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 10 HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; ru-ru; Lenovo B8080-F/JLS36C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.3 Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "B8080-F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Z6", + "ua": "Mozilla/5.0 (Linux; U; Android 9;zh-cn; Lenovo L78121 Build/PKQ1.190319.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.117 MobileLenovoBrowser/9.1.3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L78121", + "type": "mobile" + } } ] \ No newline at end of file From bcf249da06e150c71074291d8597c6c7ebf11e6c Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 22 Nov 2024 20:21:07 +0700 Subject: [PATCH 14/73] Fix #767 #763 - Improve type definition for `headers` --- package.json | 3 +++ src/main/ua-parser.d.ts | 12 ++++++++---- test/mocha-test.js | 8 ++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 5a53978..aa887d2 100755 --- a/package.json +++ b/package.json @@ -221,8 +221,11 @@ "@babel/traverse": "7.23.2", "@jazzer.js/core": "^1.4.0", "@playwright/test": "~1.32.2", + "@types/node": "^22.9.1", + "@types/node-fetch": "^2.6.12", "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", diff --git a/src/main/ua-parser.d.ts b/src/main/ua-parser.d.ts index 150d867..03be66e 100644 --- a/src/main/ua-parser.d.ts +++ b/src/main/ua-parser.d.ts @@ -2,6 +2,9 @@ // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman +import type { IncomingHttpHeaders } from 'http'; +import type { Headers as FetchAPIHeaders } from 'node-fetch'; + declare namespace UAParser { interface IData { @@ -50,11 +53,12 @@ declare namespace UAParser { type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[]; type UAParserProps = 'browser' | 'cpu' | 'device' | 'engine' | 'os'; type UAParserExt = Partial> | Partial>[]; + type UAParserHeaders = Record | IncomingHttpHeaders | FetchAPIHeaders; - export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: Record): IResult; - export function UAParser(uastring?: string, headers?: Record): IResult; - export function UAParser(extensions?: UAParserExt, headers?: Record): IResult; - export function UAParser(headers?: Record): IResult; + export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: UAParserHeaders): IResult; + export function UAParser(uastring?: string, headers?: UAParserHeaders): IResult; + export function UAParser(extensions?: UAParserExt, headers?: UAParserHeaders): IResult; + export function UAParser(headers?: UAParserHeaders): IResult; export class UAParser { diff --git a/test/mocha-test.js b/test/mocha-test.js index 9b35330..ecd7fe0 100644 --- a/test/mocha-test.js +++ b/test/mocha-test.js @@ -10,6 +10,7 @@ var cpus = require('./specs/cpu-all.json'); var devices = readJsonFiles('test/specs/devices'); var engines = require('./specs/engine-all.json'); var os = require('./specs/os-all.json'); +var { Headers } = require('node-fetch'); function readJsonFiles(dir) { var list = []; @@ -354,6 +355,13 @@ describe('Read user-agent data from req.headers', function () { let engine = UAParser(req.headers).engine; assert.strictEqual(engine.name, "EdgeHTML"); }); + + it('Fetch API\'s Header can be passed directly into headers', () => { + const reqHeaders = new Headers(); + reqHeaders.append('User-Agent', 'Midori/0.2.2 (X11; Linux i686; U; en-us) WebKit/531.2+'); + const { browser } = UAParser(reqHeaders); + assert.strictEqual(browser.is('Midori'), true); + }); }); describe('Map UA-CH headers', function () { From f5ee90fcf89d06079454b2e9479bd41c9093e714 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 22 Nov 2024 22:29:03 +0700 Subject: [PATCH 15/73] Reorganize test files --- package-lock.json | 72 +++++++++++- test/mocha-test-extension.js | 10 +- test/mocha-test.js | 105 ++++++++---------- test/specs/{ => browser}/browser-all.json | 0 test/specs/{ => cpu}/cpu-all.json | 0 test/specs/{devices => device}/_others.json | 0 test/specs/{devices => device}/acer.json | 0 test/specs/{devices => device}/advan.json | 0 test/specs/{devices => device}/alcatel.json | 0 test/specs/{devices => device}/amazon.json | 0 test/specs/{devices => device}/apple.json | 0 test/specs/{devices => device}/asus.json | 0 .../specs/{devices => device}/blackberry.json | 0 test/specs/{devices => device}/cat.json | 0 test/specs/{devices => device}/energizer.json | 0 test/specs/{devices => device}/facebook.json | 0 test/specs/{devices => device}/fairphone.json | 0 test/specs/{devices => device}/google.json | 0 test/specs/{devices => device}/hmd.json | 0 test/specs/{devices => device}/honor.json | 0 test/specs/{devices => device}/htc.json | 0 test/specs/{devices => device}/huawei.json | 0 test/specs/{devices => device}/imo.json | 0 test/specs/{devices => device}/infinix.json | 0 test/specs/{devices => device}/itel.json | 0 test/specs/{devices => device}/jolla.json | 0 test/specs/{devices => device}/kobo.json | 0 test/specs/{devices => device}/lenovo.json | 0 test/specs/{devices => device}/lg.json | 0 test/specs/{devices => device}/meizu.json | 0 test/specs/{devices => device}/micromax.json | 0 test/specs/{devices => device}/microsoft.json | 0 test/specs/{devices => device}/motorola.json | 0 test/specs/{devices => device}/nintendo.json | 0 test/specs/{devices => device}/nokia.json | 0 test/specs/{devices => device}/nothing.json | 0 test/specs/{devices => device}/nvidia.json | 0 test/specs/{devices => device}/oneplus.json | 0 test/specs/{devices => device}/oppo.json | 0 test/specs/{devices => device}/ouya.json | 0 test/specs/{devices => device}/panasonic.json | 0 test/specs/{devices => device}/pico.json | 0 test/specs/{devices => device}/polytron.json | 0 test/specs/{devices => device}/realme.json | 0 test/specs/{devices => device}/roku.json | 0 test/specs/{devices => device}/samsung.json | 0 test/specs/{devices => device}/sharp.json | 0 test/specs/{devices => device}/smartfren.json | 0 test/specs/{devices => device}/sony.json | 0 test/specs/{devices => device}/tcl.json | 0 test/specs/{devices => device}/technisat.json | 0 test/specs/{devices => device}/tecno.json | 0 test/specs/{devices => device}/tesla.json | 0 test/specs/{devices => device}/ulefone.json | 0 test/specs/{devices => device}/vivo.json | 0 test/specs/{devices => device}/xiaomi.json | 0 test/specs/{devices => device}/zte.json | 0 test/specs/{ => engine}/engine-all.json | 0 .../{browser-clis.json => extension/cli.json} | 0 .../crawler.json} | 0 .../email.json} | 0 .../extra-devices.json} | 0 .../fetcher.json} | 0 .../library.json} | 0 .../mediaplayer.json} | 0 test/specs/{ => os}/os-all.json | 0 66 files changed, 121 insertions(+), 66 deletions(-) rename test/specs/{ => browser}/browser-all.json (100%) rename test/specs/{ => cpu}/cpu-all.json (100%) rename test/specs/{devices => device}/_others.json (100%) rename test/specs/{devices => device}/acer.json (100%) rename test/specs/{devices => device}/advan.json (100%) rename test/specs/{devices => device}/alcatel.json (100%) rename test/specs/{devices => device}/amazon.json (100%) rename test/specs/{devices => device}/apple.json (100%) rename test/specs/{devices => device}/asus.json (100%) rename test/specs/{devices => device}/blackberry.json (100%) rename test/specs/{devices => device}/cat.json (100%) rename test/specs/{devices => device}/energizer.json (100%) rename test/specs/{devices => device}/facebook.json (100%) rename test/specs/{devices => device}/fairphone.json (100%) rename test/specs/{devices => device}/google.json (100%) rename test/specs/{devices => device}/hmd.json (100%) rename test/specs/{devices => device}/honor.json (100%) rename test/specs/{devices => device}/htc.json (100%) rename test/specs/{devices => device}/huawei.json (100%) rename test/specs/{devices => device}/imo.json (100%) rename test/specs/{devices => device}/infinix.json (100%) rename test/specs/{devices => device}/itel.json (100%) rename test/specs/{devices => device}/jolla.json (100%) rename test/specs/{devices => device}/kobo.json (100%) rename test/specs/{devices => device}/lenovo.json (100%) rename test/specs/{devices => device}/lg.json (100%) rename test/specs/{devices => device}/meizu.json (100%) rename test/specs/{devices => device}/micromax.json (100%) rename test/specs/{devices => device}/microsoft.json (100%) rename test/specs/{devices => device}/motorola.json (100%) rename test/specs/{devices => device}/nintendo.json (100%) rename test/specs/{devices => device}/nokia.json (100%) rename test/specs/{devices => device}/nothing.json (100%) rename test/specs/{devices => device}/nvidia.json (100%) rename test/specs/{devices => device}/oneplus.json (100%) rename test/specs/{devices => device}/oppo.json (100%) rename test/specs/{devices => device}/ouya.json (100%) rename test/specs/{devices => device}/panasonic.json (100%) rename test/specs/{devices => device}/pico.json (100%) rename test/specs/{devices => device}/polytron.json (100%) rename test/specs/{devices => device}/realme.json (100%) rename test/specs/{devices => device}/roku.json (100%) rename test/specs/{devices => device}/samsung.json (100%) rename test/specs/{devices => device}/sharp.json (100%) rename test/specs/{devices => device}/smartfren.json (100%) rename test/specs/{devices => device}/sony.json (100%) rename test/specs/{devices => device}/tcl.json (100%) rename test/specs/{devices => device}/technisat.json (100%) rename test/specs/{devices => device}/tecno.json (100%) rename test/specs/{devices => device}/tesla.json (100%) rename test/specs/{devices => device}/ulefone.json (100%) rename test/specs/{devices => device}/vivo.json (100%) rename test/specs/{devices => device}/xiaomi.json (100%) rename test/specs/{devices => device}/zte.json (100%) rename test/specs/{ => engine}/engine-all.json (100%) rename test/specs/{browser-clis.json => extension/cli.json} (100%) rename test/specs/{browser-crawlers.json => extension/crawler.json} (100%) rename test/specs/{browser-emails.json => extension/email.json} (100%) rename test/specs/{extension-device.json => extension/extra-devices.json} (100%) rename test/specs/{browser-fetchers.json => extension/fetcher.json} (100%) rename test/specs/{browser-libraries.json => extension/library.json} (100%) rename test/specs/{extension-mediaplayer.json => extension/mediaplayer.json} (100%) rename test/specs/{ => os}/os-all.json (100%) diff --git a/package-lock.json b/package-lock.json index 56374f4..3e7e547 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,8 +35,11 @@ "@babel/traverse": "7.23.2", "@jazzer.js/core": "^1.4.0", "@playwright/test": "~1.32.2", + "@types/node": "^22.9.1", + "@types/node-fetch": "^2.6.12", "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", @@ -781,10 +784,23 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", - "dev": true + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz", + "integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } }, "node_modules/@types/normalize-package-data": { "version": "2.4.2", @@ -3525,6 +3541,26 @@ "integrity": "sha512-YsjmaKGPDkmhoNKIpkChtCsPVaRE0a274IdERKnuc/E8K1UJdBZ4/mvI006OijlQZHCfpRNOH3dfHQs92se8gg==", "dev": true }, + "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/node-releases": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", @@ -4576,6 +4612,12 @@ "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", @@ -4649,6 +4691,12 @@ "node": ">=0.8.0" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -4710,6 +4758,22 @@ "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/test/mocha-test-extension.js b/test/mocha-test-extension.js index 246bf35..6ba195b 100644 --- a/test/mocha-test-extension.js +++ b/test/mocha-test-extension.js @@ -4,11 +4,11 @@ const parseJS = require('@babel/parser').parse; const traverse = require('@babel/traverse').default; const safe = require('safe-regex'); const { UAParser } = require('../src/main/ua-parser'); -const clis = require('./specs/browser-clis.json'); -const crawlers = require('./specs/browser-crawlers.json'); -const emails = require('./specs/browser-emails.json'); -const fetchers = require('./specs/browser-fetchers.json'); -const libraries = require('./specs/browser-libraries.json'); +const clis = require('./specs/extension/cli.json'); +const crawlers = require('./specs/extension/crawler.json'); +const emails = require('./specs/extension/email.json'); +const fetchers = require('./specs/extension/fetcher.json'); +const libraries = require('./specs/extension/library.json'); const { Bots, CLIs, Crawlers, Emails, Fetchers, Libraries } = require('../src/extensions/ua-parser-extensions'); describe('Extensions', () => { diff --git a/test/mocha-test.js b/test/mocha-test.js index ecd7fe0..8f6d529 100644 --- a/test/mocha-test.js +++ b/test/mocha-test.js @@ -5,11 +5,11 @@ var requirejs = require('requirejs'); var parseJS = require('@babel/parser').parse; var traverse = require('@babel/traverse').default; var {UAParser} = require('../src/main/ua-parser'); -var browsers = require('./specs/browser-all.json'); -var cpus = require('./specs/cpu-all.json'); -var devices = readJsonFiles('test/specs/devices'); -var engines = require('./specs/engine-all.json'); -var os = require('./specs/os-all.json'); +var browsers = require('./specs/browser/browser-all.json'); +var cpus = require('./specs/cpu/cpu-all.json'); +var devices = readJsonFiles('test/specs/device'); +var engines = require('./specs/engine/engine-all.json'); +var os = require('./specs/os/os-all.json'); var { Headers } = require('node-fetch'); function readJsonFiles(dir) { @@ -20,39 +20,6 @@ function readJsonFiles(dir) { return list; }; -var parser = new UAParser(); -var methods = [ - { - title : 'getBrowser', - label : 'browser', - list : browsers, - properties : ['name', 'major', 'version', 'type'] - }, - { - title : 'getCPU', - label : 'cpu', - list : cpus, - properties : ['architecture'] - }, - { - title : 'getDevice', - label : 'device', - list : devices, - properties : ['model', 'type', 'vendor'] - }, - { - title : 'getEngine', - label : 'engine', - list : engines, - properties : ['name', 'version'] - }, - { - title : 'getOS', - label : 'os', - list : os, - properties : ['name', 'version'] -}]; - describe('UAParser()', function () { var ua = 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6'; assert.deepEqual(UAParser(ua), new UAParser().setUA(ua).getResult()); @@ -66,26 +33,50 @@ describe('UAParser.setUA method does not throw with undefined ua argument', func assert.doesNotThrow(() => new UAParser().setUA(undefined).getResult()); }); -for (var i in methods) { - describe(methods[i]['title'], function () { - for (var j in methods[i]['list']) { - if (!!methods[i]['list'][j].ua) { - describe('[' + methods[i]['list'][j].desc + ']', function () { - describe('"' + methods[i]['list'][j].ua + '"', function () { - var expect = methods[i]['list'][j].expect; - var result = parser.setUA(methods[i]['list'][j].ua).getResult()[methods[i]['label']]; - - methods[i]['properties'].forEach(function(m) { - it('should return ' + methods[i]['label'] + ' ' + m + ': ' + expect[m], function () { - assert.strictEqual(result[m], expect[m] != 'undefined' ? expect[m] : undefined); - }); +describe('UAParser get*() methods', () => { + [ + { + title : 'getBrowser()', + label : 'browser', + list : browsers + }, + { + title : 'getCPU()', + label : 'cpu', + list : cpus + }, + { + title : 'getDevice()', + label : 'device', + list : devices + }, + { + title : 'getEngine()', + label : 'engine', + list : engines + }, + { + title : 'getOS()', + label : 'os', + list : os + } + ] + .forEach(method => { + describe(`[${method.title}]`, () => { + method.list.forEach(unit => { + describe(`[${unit.desc}]: "${unit.ua}"`, () => { + const actual = UAParser(unit.ua)[method.label]; + Object.entries(unit.expect).forEach(entry => { + const [key, val] = entry; + it(`Should return ${key}: ${val}`, () => { + assert.strictEqual(String(val), String(actual[key])); }); }); }); - } - } + }); + }); }); -} +}); describe('Returns', function () { it('getResult() should returns JSON', function(done) { @@ -192,9 +183,9 @@ describe('Testing regexes', function () { describe('Begin testing', function () { it('all regexes in main file', function () { - regexes.forEach(function (regex) { - describe('Test against `safe-regex` : ' + regex, function () { - it('should be safe from potentially vulnerable regex', function () { + describe('Test against `safe-regex` module', function () { + regexes.forEach(function (regex) { + it(`Should pass \`safe-regex\`: ${regex}`, function () { assert.strictEqual(safe(regex), true); }); }); diff --git a/test/specs/browser-all.json b/test/specs/browser/browser-all.json similarity index 100% rename from test/specs/browser-all.json rename to test/specs/browser/browser-all.json diff --git a/test/specs/cpu-all.json b/test/specs/cpu/cpu-all.json similarity index 100% rename from test/specs/cpu-all.json rename to test/specs/cpu/cpu-all.json diff --git a/test/specs/devices/_others.json b/test/specs/device/_others.json similarity index 100% rename from test/specs/devices/_others.json rename to test/specs/device/_others.json diff --git a/test/specs/devices/acer.json b/test/specs/device/acer.json similarity index 100% rename from test/specs/devices/acer.json rename to test/specs/device/acer.json diff --git a/test/specs/devices/advan.json b/test/specs/device/advan.json similarity index 100% rename from test/specs/devices/advan.json rename to test/specs/device/advan.json diff --git a/test/specs/devices/alcatel.json b/test/specs/device/alcatel.json similarity index 100% rename from test/specs/devices/alcatel.json rename to test/specs/device/alcatel.json diff --git a/test/specs/devices/amazon.json b/test/specs/device/amazon.json similarity index 100% rename from test/specs/devices/amazon.json rename to test/specs/device/amazon.json diff --git a/test/specs/devices/apple.json b/test/specs/device/apple.json similarity index 100% rename from test/specs/devices/apple.json rename to test/specs/device/apple.json diff --git a/test/specs/devices/asus.json b/test/specs/device/asus.json similarity index 100% rename from test/specs/devices/asus.json rename to test/specs/device/asus.json diff --git a/test/specs/devices/blackberry.json b/test/specs/device/blackberry.json similarity index 100% rename from test/specs/devices/blackberry.json rename to test/specs/device/blackberry.json diff --git a/test/specs/devices/cat.json b/test/specs/device/cat.json similarity index 100% rename from test/specs/devices/cat.json rename to test/specs/device/cat.json diff --git a/test/specs/devices/energizer.json b/test/specs/device/energizer.json similarity index 100% rename from test/specs/devices/energizer.json rename to test/specs/device/energizer.json diff --git a/test/specs/devices/facebook.json b/test/specs/device/facebook.json similarity index 100% rename from test/specs/devices/facebook.json rename to test/specs/device/facebook.json diff --git a/test/specs/devices/fairphone.json b/test/specs/device/fairphone.json similarity index 100% rename from test/specs/devices/fairphone.json rename to test/specs/device/fairphone.json diff --git a/test/specs/devices/google.json b/test/specs/device/google.json similarity index 100% rename from test/specs/devices/google.json rename to test/specs/device/google.json diff --git a/test/specs/devices/hmd.json b/test/specs/device/hmd.json similarity index 100% rename from test/specs/devices/hmd.json rename to test/specs/device/hmd.json diff --git a/test/specs/devices/honor.json b/test/specs/device/honor.json similarity index 100% rename from test/specs/devices/honor.json rename to test/specs/device/honor.json diff --git a/test/specs/devices/htc.json b/test/specs/device/htc.json similarity index 100% rename from test/specs/devices/htc.json rename to test/specs/device/htc.json diff --git a/test/specs/devices/huawei.json b/test/specs/device/huawei.json similarity index 100% rename from test/specs/devices/huawei.json rename to test/specs/device/huawei.json diff --git a/test/specs/devices/imo.json b/test/specs/device/imo.json similarity index 100% rename from test/specs/devices/imo.json rename to test/specs/device/imo.json diff --git a/test/specs/devices/infinix.json b/test/specs/device/infinix.json similarity index 100% rename from test/specs/devices/infinix.json rename to test/specs/device/infinix.json diff --git a/test/specs/devices/itel.json b/test/specs/device/itel.json similarity index 100% rename from test/specs/devices/itel.json rename to test/specs/device/itel.json diff --git a/test/specs/devices/jolla.json b/test/specs/device/jolla.json similarity index 100% rename from test/specs/devices/jolla.json rename to test/specs/device/jolla.json diff --git a/test/specs/devices/kobo.json b/test/specs/device/kobo.json similarity index 100% rename from test/specs/devices/kobo.json rename to test/specs/device/kobo.json diff --git a/test/specs/devices/lenovo.json b/test/specs/device/lenovo.json similarity index 100% rename from test/specs/devices/lenovo.json rename to test/specs/device/lenovo.json diff --git a/test/specs/devices/lg.json b/test/specs/device/lg.json similarity index 100% rename from test/specs/devices/lg.json rename to test/specs/device/lg.json diff --git a/test/specs/devices/meizu.json b/test/specs/device/meizu.json similarity index 100% rename from test/specs/devices/meizu.json rename to test/specs/device/meizu.json diff --git a/test/specs/devices/micromax.json b/test/specs/device/micromax.json similarity index 100% rename from test/specs/devices/micromax.json rename to test/specs/device/micromax.json diff --git a/test/specs/devices/microsoft.json b/test/specs/device/microsoft.json similarity index 100% rename from test/specs/devices/microsoft.json rename to test/specs/device/microsoft.json diff --git a/test/specs/devices/motorola.json b/test/specs/device/motorola.json similarity index 100% rename from test/specs/devices/motorola.json rename to test/specs/device/motorola.json diff --git a/test/specs/devices/nintendo.json b/test/specs/device/nintendo.json similarity index 100% rename from test/specs/devices/nintendo.json rename to test/specs/device/nintendo.json diff --git a/test/specs/devices/nokia.json b/test/specs/device/nokia.json similarity index 100% rename from test/specs/devices/nokia.json rename to test/specs/device/nokia.json diff --git a/test/specs/devices/nothing.json b/test/specs/device/nothing.json similarity index 100% rename from test/specs/devices/nothing.json rename to test/specs/device/nothing.json diff --git a/test/specs/devices/nvidia.json b/test/specs/device/nvidia.json similarity index 100% rename from test/specs/devices/nvidia.json rename to test/specs/device/nvidia.json diff --git a/test/specs/devices/oneplus.json b/test/specs/device/oneplus.json similarity index 100% rename from test/specs/devices/oneplus.json rename to test/specs/device/oneplus.json diff --git a/test/specs/devices/oppo.json b/test/specs/device/oppo.json similarity index 100% rename from test/specs/devices/oppo.json rename to test/specs/device/oppo.json diff --git a/test/specs/devices/ouya.json b/test/specs/device/ouya.json similarity index 100% rename from test/specs/devices/ouya.json rename to test/specs/device/ouya.json diff --git a/test/specs/devices/panasonic.json b/test/specs/device/panasonic.json similarity index 100% rename from test/specs/devices/panasonic.json rename to test/specs/device/panasonic.json diff --git a/test/specs/devices/pico.json b/test/specs/device/pico.json similarity index 100% rename from test/specs/devices/pico.json rename to test/specs/device/pico.json diff --git a/test/specs/devices/polytron.json b/test/specs/device/polytron.json similarity index 100% rename from test/specs/devices/polytron.json rename to test/specs/device/polytron.json diff --git a/test/specs/devices/realme.json b/test/specs/device/realme.json similarity index 100% rename from test/specs/devices/realme.json rename to test/specs/device/realme.json diff --git a/test/specs/devices/roku.json b/test/specs/device/roku.json similarity index 100% rename from test/specs/devices/roku.json rename to test/specs/device/roku.json diff --git a/test/specs/devices/samsung.json b/test/specs/device/samsung.json similarity index 100% rename from test/specs/devices/samsung.json rename to test/specs/device/samsung.json diff --git a/test/specs/devices/sharp.json b/test/specs/device/sharp.json similarity index 100% rename from test/specs/devices/sharp.json rename to test/specs/device/sharp.json diff --git a/test/specs/devices/smartfren.json b/test/specs/device/smartfren.json similarity index 100% rename from test/specs/devices/smartfren.json rename to test/specs/device/smartfren.json diff --git a/test/specs/devices/sony.json b/test/specs/device/sony.json similarity index 100% rename from test/specs/devices/sony.json rename to test/specs/device/sony.json diff --git a/test/specs/devices/tcl.json b/test/specs/device/tcl.json similarity index 100% rename from test/specs/devices/tcl.json rename to test/specs/device/tcl.json diff --git a/test/specs/devices/technisat.json b/test/specs/device/technisat.json similarity index 100% rename from test/specs/devices/technisat.json rename to test/specs/device/technisat.json diff --git a/test/specs/devices/tecno.json b/test/specs/device/tecno.json similarity index 100% rename from test/specs/devices/tecno.json rename to test/specs/device/tecno.json diff --git a/test/specs/devices/tesla.json b/test/specs/device/tesla.json similarity index 100% rename from test/specs/devices/tesla.json rename to test/specs/device/tesla.json diff --git a/test/specs/devices/ulefone.json b/test/specs/device/ulefone.json similarity index 100% rename from test/specs/devices/ulefone.json rename to test/specs/device/ulefone.json diff --git a/test/specs/devices/vivo.json b/test/specs/device/vivo.json similarity index 100% rename from test/specs/devices/vivo.json rename to test/specs/device/vivo.json diff --git a/test/specs/devices/xiaomi.json b/test/specs/device/xiaomi.json similarity index 100% rename from test/specs/devices/xiaomi.json rename to test/specs/device/xiaomi.json diff --git a/test/specs/devices/zte.json b/test/specs/device/zte.json similarity index 100% rename from test/specs/devices/zte.json rename to test/specs/device/zte.json diff --git a/test/specs/engine-all.json b/test/specs/engine/engine-all.json similarity index 100% rename from test/specs/engine-all.json rename to test/specs/engine/engine-all.json diff --git a/test/specs/browser-clis.json b/test/specs/extension/cli.json similarity index 100% rename from test/specs/browser-clis.json rename to test/specs/extension/cli.json diff --git a/test/specs/browser-crawlers.json b/test/specs/extension/crawler.json similarity index 100% rename from test/specs/browser-crawlers.json rename to test/specs/extension/crawler.json diff --git a/test/specs/browser-emails.json b/test/specs/extension/email.json similarity index 100% rename from test/specs/browser-emails.json rename to test/specs/extension/email.json diff --git a/test/specs/extension-device.json b/test/specs/extension/extra-devices.json similarity index 100% rename from test/specs/extension-device.json rename to test/specs/extension/extra-devices.json diff --git a/test/specs/browser-fetchers.json b/test/specs/extension/fetcher.json similarity index 100% rename from test/specs/browser-fetchers.json rename to test/specs/extension/fetcher.json diff --git a/test/specs/browser-libraries.json b/test/specs/extension/library.json similarity index 100% rename from test/specs/browser-libraries.json rename to test/specs/extension/library.json diff --git a/test/specs/extension-mediaplayer.json b/test/specs/extension/mediaplayer.json similarity index 100% rename from test/specs/extension-mediaplayer.json rename to test/specs/extension/mediaplayer.json diff --git a/test/specs/os-all.json b/test/specs/os/os-all.json similarity index 100% rename from test/specs/os-all.json rename to test/specs/os/os-all.json From 60cc84d58c3733980c70787629586395b87e0099 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 24 Nov 2024 12:19:21 +0700 Subject: [PATCH 16/73] [sub:extensions] Add new bots: Apache-HttpClient, go-http-client, got, GuzzleHttp, Java-http-client, libwww-perl, lua-resty-http, Needle, OkHttp, node-fetch, PHP-SOAP, PostmanRuntime, superagent --- src/extensions/ua-parser-extensions.js | 7 +- src/extensions/ua-parser-extensions.mjs | 7 +- test/mocha-test-extension.js | 2 +- test/specs/extension/library.json | 130 ++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 5 deletions(-) diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 2766271..5b62e3e 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -375,8 +375,11 @@ const MediaPlayers = Object.freeze({ const Libraries = Object.freeze({ browser : [ - // Axios/jsdom/Scrapy/Java/urllib/requests - [/\b(axios|jsdom|scrapy|java|python-urllib|python-requests)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, LIBRARY]] + // Apache-HttpClient/Axios/go-http-client/got/GuzzleHttp/Java[-HttpClient]/jsdom/libwww-perl/lua-resty-http/Needle/node-fetch/OkHttp/PHP-SOAP/PostmanRuntime/python-urllib/python-requests/Scrapy/superagent + [ + /^(apache-httpclient|axios|(?:go|java)-http-client|got|guzzlehttp|java|libwww-perl|lua-resty-http|needle|node-(?:fetch|superagent)|okhttp|php-soap|postmanruntime|python-(?:urllib|requests)|scrapy)\/([\w\.]+)/i, + /(jsdom|(?<=\()java)\/([\w\.]+)/i + ], [NAME, VERSION, [TYPE, LIBRARY]] ] }); diff --git a/src/extensions/ua-parser-extensions.mjs b/src/extensions/ua-parser-extensions.mjs index 20fbee6..33f9b99 100644 --- a/src/extensions/ua-parser-extensions.mjs +++ b/src/extensions/ua-parser-extensions.mjs @@ -379,8 +379,11 @@ const MediaPlayers = Object.freeze({ const Libraries = Object.freeze({ browser : [ - // Axios/jsdom/Scrapy/Java/urllib/requests - [/\b(axios|jsdom|scrapy|java|python-urllib|python-requests)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, LIBRARY]] + // Apache-HttpClient/Axios/go-http-client/got/GuzzleHttp/Java[-HttpClient]/jsdom/libwww-perl/lua-resty-http/Needle/node-fetch/OkHttp/PHP-SOAP/PostmanRuntime/python-urllib/python-requests/Scrapy/superagent + [ + /^(apache-httpclient|axios|(?:go|java)-http-client|got|guzzlehttp|java|libwww-perl|lua-resty-http|needle|node-(?:fetch|superagent)|okhttp|php-soap|postmanruntime|python-(?:urllib|requests)|scrapy)\/([\w\.]+)/i, + /(jsdom|(?<=\()java)\/([\w\.]+)/i + ], [NAME, VERSION, [TYPE, LIBRARY]] ] }); diff --git a/test/mocha-test-extension.js b/test/mocha-test-extension.js index 6ba195b..c32c1b8 100644 --- a/test/mocha-test-extension.js +++ b/test/mocha-test-extension.js @@ -22,7 +22,7 @@ describe('Extensions', () => { .forEach((list) => { describe(list[0], () => { list[1].forEach((agent) => { - it(`Can detect ${agent.desc}`, () => { + it(`Can detect ${agent.desc}: "${agent.ua}"`, () => { let browser = UAParser(agent.ua, list[2]).browser; assert.strictEqual(String(browser.name), agent.expect.name); assert.strictEqual(String(browser.version), agent.expect.version); diff --git a/test/specs/extension/library.json b/test/specs/extension/library.json index 1ebdcdc..f691105 100644 --- a/test/specs/extension/library.json +++ b/test/specs/extension/library.json @@ -1,4 +1,14 @@ [ + { + "desc" : "Apache-HttpClient", + "ua" : "Apache-HttpClient/4.5.14 (Java/17.0.12)", + "expect" : + { + "name" : "Apache-HttpClient", + "version" : "4.5.14", + "type" : "library" + } + }, { "desc" : "Axios", "ua" : "axios/1.7.2", @@ -9,6 +19,36 @@ "type" : "library" } }, + { + "desc" : "go-http-client", + "ua" : "go-http-client/1.1", + "expect" : + { + "name" : "go-http-client", + "version" : "1.1", + "type" : "library" + } + }, + { + "desc" : "got", + "ua" : "got/9.6.0 (https://github.com/sindresorhus/got)", + "expect" : + { + "name" : "got", + "version" : "9.6.0", + "type" : "library" + } + }, + { + "desc" : "GuzzleHttp", + "ua" : "GuzzleHttp/6.5.5 curl/7.70.0 PHP/7.4.22", + "expect" : + { + "name" : "GuzzleHttp", + "version" : "6.5.5", + "type" : "library" + } + }, { "desc" : "Java", "ua" : "Java/1.6.0_14", @@ -19,6 +59,16 @@ "type" : "library" } }, + { + "desc" : "Java HTTPClient", + "ua" : "Java-http-client/11.0.6", + "expect" : + { + "name" : "Java-http-client", + "version" : "11.0.6", + "type" : "library" + } + }, { "desc" : "jsdom", "ua" : "Mozilla/5.0 (unknown OS) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/11.12.0", @@ -29,6 +79,76 @@ "type" : "library" } }, + { + "desc" : "libwww-perl", + "ua" : "libwww-perl/6.05", + "expect" : + { + "name" : "libwww-perl", + "version" : "6.05", + "type" : "library" + } + }, + { + "desc" : "lua-resty-http", + "ua" : "lua-resty-http/0.07 (Lua)", + "expect" : + { + "name" : "lua-resty-http", + "version" : "0.07", + "type" : "library" + } + }, + { + "desc" : "Needle", + "ua" : "Needle/3.2.0 (Node.js v18.14.2; win32 x64)", + "expect" : + { + "name" : "Needle", + "version" : "3.2.0", + "type" : "library" + } + }, + { + "desc" : "OkHttp", + "ua" : "okhttp/3.2.0", + "expect" : + { + "name" : "okhttp", + "version" : "3.2.0", + "type" : "library" + } + }, + { + "desc" : "node-fetch", + "ua" : "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)", + "expect" : + { + "name" : "node-fetch", + "version" : "1.0", + "type" : "library" + } + }, + { + "desc" : "PHP-SOAP", + "ua" : "PHP-SOAP/7.4.33", + "expect" : + { + "name" : "PHP-SOAP", + "version" : "7.4.33", + "type" : "library" + } + }, + { + "desc" : "PostmanRuntime", + "ua" : "PostmanRuntime/7.26.5", + "expect" : + { + "name" : "PostmanRuntime", + "version" : "7.26.5", + "type" : "library" + } + }, { "desc" : "Python urllib", "ua" : "Python-urllib/2.6", @@ -58,5 +178,15 @@ "version" : "1.5.0", "type" : "library" } + }, + { + "desc" : "superagent", + "ua" : "node-superagent/5.0.2", + "expect" : + { + "name" : "node-superagent", + "version" : "5.0.2", + "type" : "library" + } } ] From c37f3863c08932ed3c0e8e9d8c4cb01a470f8c66 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 26 Nov 2024 20:13:07 +0700 Subject: [PATCH 17/73] [sub:extensions] Rearrange mediaplayer regexes --- src/extensions/ua-parser-extensions.js | 122 +++++++------------------ test/specs/extension/mediaplayer.json | 36 +------- 2 files changed, 36 insertions(+), 122 deletions(-) diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 5b62e3e..79dd0b0 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -267,104 +267,48 @@ const InApps = Object.freeze({ const MediaPlayers = Object.freeze({ browser : [[ - - /(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia - /(coremedia) v([\w\._]+)/i - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i, - // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC + /(apple(?:coremedia|tv))\/([\w\._]+)/i, // Generic Apple CoreMedia + /(coremedia) v([\w\._]+)/i, + // Ares/Nexplayer/OSSProxy + /(ares|clementine|music player daemon|nexplayer|ossproxy) ([\w\.-]+)/i, + // Aqualung/Lyssna/BSPlayer/Clementine/MPD + // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/GnomeMplayer/MoC // NSPlayer/PSP-InternetRadioPlayer/Videos - /(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD - /(lg player|nexplayer)\s([\d\.]+)/i, - /player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - /(nexplayer)\s([\w\.-]+)/i // Nexplayer + // Nero Home/Nero Scout/Nokia + // QuickTime/RealMedia/RadioApp/RadioClientApplication/ + // SoundTap/Totem/Stagefright/Streamium + // XBMC/gvfs/Xine/XMMS/irapp + /^(aqualung|audacious|audimusicstream|amarok|bass|bsplayer|core|gnomemplayer|gvfs|irapp|lyssna|music on console|nero (?:home|scout)|nokia\d+|nsplayer|psp-internetradioplayer|quicktime|rma|radioapp|radioclientapplication|soundtap|stagefright|streamium|totem|videos|xbmc|xine|xmms)\/([\w\.-]+)/i, + /(lg player|nexplayer) ([\d\.]+)/i, + /player\/(nexplayer|lg player) ([\w\.-]+)/i, // NexPlayer/LG Player + /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i, // Gstreamer + /(htc streaming player) [\w_]+ \/ ([\d\.]+)/i, // HTC Streaming Player + /(lavf)([\d\.]+)/i, // Lavf (FFMPEG) + // MPlayer SVN + /(mplayer)(?: |\/)(?:(?:sherpya-){0,1}svn)(?:-| )(r\d+(?:-\d+[\w\.-]+))/i, + / (songbird)\/([\w\.-]+)/i, // Songbird/Philips-Songbird + /(winamp)(?:3 version|mpeg| ) ([\w\.-]+)/i, // Winamp + /(vlc)(?:\/| media player - version )([\w\.-]+)/i, // VLC Videolan + /^(foobar2000|itunes|smp)\/([\d\.]+)/i, // Foobar2000/iTunes/SMP + /com\.(riseupradioalarm)\/([\d\.]*)/i, // RiseUP Radio Alarm + /(mplayer)(?:\s|\/| unknown-)([\w\.\-]+)/i, // MPlayer + // Windows Media Server + /(windows)\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ home media server/i ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ /(flrp)\/([\w\.-]+)/i // Flip Player ], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [ - - /(fstream|nativehost|queryseekspider)/i // FStream/NativeHost/QuerySeekSpider + // MPlayer (no other info)/Media Player Classic/Nero ShowTime + // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) + // inlight radio / YourMuze + /(fstream|media player classic|inlight radio|mplayer|nativehost|nero showtime|ocms-bot|queryseekspider|tapinradio|tunein radio|winamp|yourmuze)/i ], [NAME, [TYPE, MEDIAPLAYER]], [ - /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i - // Gstreamer - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ + /(htc_one_s|windows-media-player|wmplayer)\/([\w\.-]+)/i, // HTC One S / Windows Media Player + ], [[NAME, /[_-]/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - /(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player - /(lavf)([\d\.]+)/i // Lavf (FFMPEG) - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(htc_one_s)\/([\d\.]+)/i, // HTC One S - ], [[NAME, /_/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i, - // MPlayer SVN - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer - /(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)/i, // MPlayer (no other info) - /(yourmuze)/i, // YourMuze - /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime - ], [NAME, [TYPE, MEDIAPLAYER]], [ - - /(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(nokia\d+)\/([\w\.-]+)/i // Nokia - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(winamp)3 version ([\w\.-]+)/i, // Winamp - /(winamp)\s([\w\.-]+)/i, - /(winamp)mpeg\/([\w\.-]+)/i - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) - // inlight radio - ], [NAME, [TYPE, MEDIAPLAYER]], [ - - /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i - // QuickTime/RealMedia/RadioApp/RadioClientApplication/ - // SoundTap/Totem/Stagefright/Streamium - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(smp)([\d\.]+)/i // SMP - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(vlc) media player - version ([\w\.]+)/i, // VLC Videolan - /(vlc)\/([\w\.-]+)/i, - /(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp - /(foobar2000)\/([\d\.]+)/i, // Foobar2000 - /(itunes)\/([\d\.]+)/i // iTunes - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(wmplayer)\/([\w\.-]+)/i, // Windows Media Player - /(windows-media-player)\/([\w\.-]+)/i - ], [[NAME, /-/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - - /windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i, - // Windows Media Server - ], [VERSION, [NAME, 'Windows'], [TYPE, MEDIAPLAYER]], [ - - /(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(rad.io)\s([\d\.]+)/i, // Rad.io - /(radio.(?:de|at|fr))\s([\d\.]+)/i + /(rad.io|radio.(?:de|at|fr)) ([\d\.]+)/i // Rad.io ], [[NAME, 'rad.io'], VERSION, [TYPE, MEDIAPLAYER]] ] }); diff --git a/test/specs/extension/mediaplayer.json b/test/specs/extension/mediaplayer.json index d40ba04..d093048 100644 --- a/test/specs/extension/mediaplayer.json +++ b/test/specs/extension/mediaplayer.json @@ -24,9 +24,9 @@ "ua" : "AppleTV/3.0.2 (Macintosh; Intel Mac OS X 10.4.7) AppleWebKit/528.18", "expect" : { - "name" : "WebKit", - "version" : "528.18", - "major" : "528" + "name" : "AppleTV", + "version" : "3.0.2", + "major" : "3" } }, { @@ -109,16 +109,6 @@ "major" : "1" } }, - { - "desc" : "Dalvik", - "ua" : "Dalvik/1.2.0 (Linux; U; Android 2.2.1; GT-S5830L Build/FROYO)", - "expect" : - { - "name" : "Dalvik", - "version" : "1.2.0", - "major" : "1" - } - }, { "desc" : "NexPlayer", "ua" : "E97510d/ Player/NexPlayer 4.0", @@ -189,16 +179,6 @@ "major" : "3" } }, - { - "desc" : "Java", - "ua" : "Java/1.4.1_04", - "expect" : - { - "name" : "Java", - "version" : "1.4.1_04", - "major" : "1" - } - }, { "desc" : "LG Player", "ua" : "LG Player 1.0; Android", @@ -509,16 +489,6 @@ "major" : "3" } }, - { - "desc" : "Wget", - "ua" : "Wget/1.12 (darwin10.7.0)", - "expect" : - { - "name" : "Wget", - "version" : "1.12", - "major" : "1" - } - }, { "desc" : "Winamp", "ua" : "Winamp 2.81", From 20e195de8b1677be52196c90ea0ea241519eb7f4 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 26 Nov 2024 20:45:23 +0700 Subject: [PATCH 18/73] Move os test spec into separate files --- src/enums/ua-parser-enums.js | 1 + test/specs/os/aix.json | 11 + test/specs/os/amigaos.json | 11 + test/specs/os/android-x86.json | 11 + test/specs/os/android.json | 20 + test/specs/os/arch.json | 11 + test/specs/os/bada.json | 11 + test/specs/os/beos.json | 11 + test/specs/os/blackberry.json | 20 + test/specs/os/centos.json | 11 + test/specs/os/chrome-os.json | 20 + test/specs/os/chromecast-android.json | 11 + test/specs/os/chromecast-fuchsia.json | 11 + test/specs/os/chromecast-linux.json | 11 + test/specs/os/chromecast-smartspeaker.json | 11 + test/specs/os/contiki.json | 11 + test/specs/os/debian.json | 56 + test/specs/os/deepin.json | 11 + test/specs/os/dragonfly.json | 11 + test/specs/os/elementary-os.json | 11 + test/specs/os/fedora.json | 29 + test/specs/os/firefox-os.json | 29 + test/specs/os/freebsd.json | 11 + test/specs/os/fuchsia.json | 11 + test/specs/os/gentoo.json | 39 + test/specs/os/ghostbsd.json | 11 + test/specs/os/haiku.json | 11 + test/specs/os/harmonyos.json | 11 + test/specs/os/hp-ux.json | 11 + test/specs/os/hurd.json | 11 + test/specs/os/ios.json | 56 + test/specs/os/joli.json | 11 + test/specs/os/kaios.json | 11 + test/specs/os/kubuntu.json | 11 + test/specs/os/linpus.json | 11 + test/specs/os/linspire.json | 11 + test/specs/os/linux.json | 11 + test/specs/os/macos.json | 38 + test/specs/os/maemo.json | 11 + test/specs/os/mandriva.json | 11 + test/specs/os/manjaro.json | 11 + test/specs/os/meego.json | 11 + test/specs/os/minix.json | 11 + test/specs/os/mint.json | 29 + test/specs/os/morphos.json | 11 + test/specs/os/netbsd.json | 11 + test/specs/os/netrange.json | 11 + test/specs/os/nettv.json | 11 + test/specs/os/nintendo.json | 11 + test/specs/os/openbsd.json | 11 + test/specs/os/openharmony.json | 11 + test/specs/os/os-all.json | 1322 -------------------- test/specs/os/os2.json | 11 + test/specs/os/palm.json | 11 + test/specs/os/pclinuxos.json | 11 + test/specs/os/pico.json | 26 + test/specs/os/plan9.json | 11 + test/specs/os/playstation.json | 20 + test/specs/os/qnx.json | 11 + test/specs/os/raspbian.json | 20 + test/specs/os/redhat.json | 38 + test/specs/os/rim-tablet-os.json | 11 + test/specs/os/risc-os.json | 11 + test/specs/os/sabayon.json | 11 + test/specs/os/sailfish.json | 11 + test/specs/os/serenityos.json | 11 + test/specs/os/series40.json | 11 + test/specs/os/slackware.json | 11 + test/specs/os/solaris.json | 20 + test/specs/os/suse.json | 11 + test/specs/os/symbian.json | 20 + test/specs/os/tizen.json | 29 + test/specs/os/ubuntu.json | 20 + test/specs/os/unix.json | 11 + test/specs/os/watchos.json | 29 + test/specs/os/webos.json | 65 + test/specs/os/windows-mobile.json | 20 + test/specs/os/windows-phone.json | 29 + test/specs/os/windows.json | 146 +++ test/specs/os/xbox.json | 47 + test/specs/os/zenwalk.json | 11 + 81 files changed, 1471 insertions(+), 1322 deletions(-) create mode 100644 test/specs/os/aix.json create mode 100644 test/specs/os/amigaos.json create mode 100644 test/specs/os/android-x86.json create mode 100644 test/specs/os/android.json create mode 100644 test/specs/os/arch.json create mode 100644 test/specs/os/bada.json create mode 100644 test/specs/os/beos.json create mode 100644 test/specs/os/blackberry.json create mode 100644 test/specs/os/centos.json create mode 100644 test/specs/os/chrome-os.json create mode 100644 test/specs/os/chromecast-android.json create mode 100644 test/specs/os/chromecast-fuchsia.json create mode 100644 test/specs/os/chromecast-linux.json create mode 100644 test/specs/os/chromecast-smartspeaker.json create mode 100644 test/specs/os/contiki.json create mode 100644 test/specs/os/debian.json create mode 100644 test/specs/os/deepin.json create mode 100644 test/specs/os/dragonfly.json create mode 100644 test/specs/os/elementary-os.json create mode 100644 test/specs/os/fedora.json create mode 100644 test/specs/os/firefox-os.json create mode 100644 test/specs/os/freebsd.json create mode 100644 test/specs/os/fuchsia.json create mode 100644 test/specs/os/gentoo.json create mode 100644 test/specs/os/ghostbsd.json create mode 100644 test/specs/os/haiku.json create mode 100644 test/specs/os/harmonyos.json create mode 100644 test/specs/os/hp-ux.json create mode 100644 test/specs/os/hurd.json create mode 100644 test/specs/os/ios.json create mode 100644 test/specs/os/joli.json create mode 100644 test/specs/os/kaios.json create mode 100644 test/specs/os/kubuntu.json create mode 100644 test/specs/os/linpus.json create mode 100644 test/specs/os/linspire.json create mode 100644 test/specs/os/linux.json create mode 100644 test/specs/os/macos.json create mode 100644 test/specs/os/maemo.json create mode 100644 test/specs/os/mandriva.json create mode 100644 test/specs/os/manjaro.json create mode 100644 test/specs/os/meego.json create mode 100644 test/specs/os/minix.json create mode 100644 test/specs/os/mint.json create mode 100644 test/specs/os/morphos.json create mode 100644 test/specs/os/netbsd.json create mode 100644 test/specs/os/netrange.json create mode 100644 test/specs/os/nettv.json create mode 100644 test/specs/os/nintendo.json create mode 100644 test/specs/os/openbsd.json create mode 100644 test/specs/os/openharmony.json delete mode 100644 test/specs/os/os-all.json create mode 100644 test/specs/os/os2.json create mode 100644 test/specs/os/palm.json create mode 100644 test/specs/os/pclinuxos.json create mode 100644 test/specs/os/pico.json create mode 100644 test/specs/os/plan9.json create mode 100644 test/specs/os/playstation.json create mode 100644 test/specs/os/qnx.json create mode 100644 test/specs/os/raspbian.json create mode 100644 test/specs/os/redhat.json create mode 100644 test/specs/os/rim-tablet-os.json create mode 100644 test/specs/os/risc-os.json create mode 100644 test/specs/os/sabayon.json create mode 100644 test/specs/os/sailfish.json create mode 100644 test/specs/os/serenityos.json create mode 100644 test/specs/os/series40.json create mode 100644 test/specs/os/slackware.json create mode 100644 test/specs/os/solaris.json create mode 100644 test/specs/os/suse.json create mode 100644 test/specs/os/symbian.json create mode 100644 test/specs/os/tizen.json create mode 100644 test/specs/os/ubuntu.json create mode 100644 test/specs/os/unix.json create mode 100644 test/specs/os/watchos.json create mode 100644 test/specs/os/webos.json create mode 100644 test/specs/os/windows-mobile.json create mode 100644 test/specs/os/windows-phone.json create mode 100644 test/specs/os/windows.json create mode 100644 test/specs/os/xbox.json create mode 100644 test/specs/os/zenwalk.json diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 37066fc..42a1462 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -323,6 +323,7 @@ const OS = Object.freeze({ IOS: 'iOS', JOLI: 'Joli', KAIOS: 'KaiOS', + KUBUNTU: 'Kubuntu', LINPUS: 'Linpus', LINSPIRE: 'Linspire', LINUX: 'Linux', diff --git a/test/specs/os/aix.json b/test/specs/os/aix.json new file mode 100644 index 0000000..02ccda8 --- /dev/null +++ b/test/specs/os/aix.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "AIX", + "ua" : "Mozilla/5.0 (X11; U; AIX 000138384C00; en-US; rv:1.0.1) Gecko/20030213 Netscape/7.0", + "expect" : + { + "name" : "AIX", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/amigaos.json b/test/specs/os/amigaos.json new file mode 100644 index 0000000..398d9b2 --- /dev/null +++ b/test/specs/os/amigaos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "AmigaOS", + "ua" : "Mozilla/4.0 (compatible; AWEB 3.4 SE; AmigaOS)", + "expect" : + { + "name" : "AmigaOS", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/android-x86.json b/test/specs/os/android-x86.json new file mode 100644 index 0000000..e83d3ca --- /dev/null +++ b/test/specs/os/android-x86.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Android-x86", + "ua" : "Mozilla/5.0 (Linux; Android 7.1.2; Generic Android-x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 OPR/61.2.3076.56749", + "expect" : + { + "name" : "Android-x86", + "version" : "7.1.2" + } + } +] \ No newline at end of file diff --git a/test/specs/os/android.json b/test/specs/os/android.json new file mode 100644 index 0000000..440fafe --- /dev/null +++ b/test/specs/os/android.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Android", + "ua" : "Mozilla/5.0 (Linux; U; Android 2.2.2; en-us; VM670 Build/FRG83G) AppleWebKit/533.1 (KHTML, like Gecko)", + "expect" : + { + "name" : "Android", + "version" : "2.2.2" + } + }, + { + "desc" : "KTB-Nexus 5", + "ua" : "APP-My App/1.0 (Linux; Android 4.2.1; Nexus 5 Build/JOP40D)", + "expect" : + { + "name" : "Android", + "version" : "4.2.1" + } + } +] \ No newline at end of file diff --git a/test/specs/os/arch.json b/test/specs/os/arch.json new file mode 100644 index 0000000..0aad667 --- /dev/null +++ b/test/specs/os/arch.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Arch", + "ua" : "Uzbl (Webkit 1.1.10) (Arch Linux)", + "expect" : + { + "name" : "Arch", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/bada.json b/test/specs/os/bada.json new file mode 100644 index 0000000..1125641 --- /dev/null +++ b/test/specs/os/bada.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Bada", + "ua" : "Mozilla/5.0 (SAMSUNG; SAMSUNG-GT-S5253/S5253DDKC1; U; Bada/1.0; en-us) AppleWebKit/533.1 (KHTML, like Gecko) Dolfin/2.0 Mobile WQVGA SMM-MMS/1.2.0 OPN-B", + "expect" : + { + "name" : "Bada", + "version" : "1.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/beos.json b/test/specs/os/beos.json new file mode 100644 index 0000000..045e54f --- /dev/null +++ b/test/specs/os/beos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "BeOS", + "ua" : "Mozilla/5.0 (BeOS; U; BeOS BePC; en-US; rv:1.8.1.8pre) Gecko/20070926 SeaMonkey/1.1.5pre", + "expect" : + { + "name" : "BeOS", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/blackberry.json b/test/specs/os/blackberry.json new file mode 100644 index 0000000..1865ab6 --- /dev/null +++ b/test/specs/os/blackberry.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "BlackBerry", + "ua" : "BlackBerry9300/5.0.0.912 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/378", + "expect" : + { + "name" : "BlackBerry", + "version" : "5.0.0.912" + } + }, + { + "desc" : "BlackBerry 10", + "ua" : "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.3+ (KHTML, like Gecko) Version/10.0.9.386 Mobile Safari/537.3+", + "expect" : + { + "name" : "BlackBerry", + "version" : "10" + } + } +] \ No newline at end of file diff --git a/test/specs/os/centos.json b/test/specs/os/centos.json new file mode 100644 index 0000000..4fe25b0 --- /dev/null +++ b/test/specs/os/centos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "CentOS", + "ua" : "Konqueror/15.13 (CentOS Linux 7.4; cs-CZ;)", + "expect" : + { + "name" : "CentOS", + "version" : "7.4" + } + } +] \ No newline at end of file diff --git a/test/specs/os/chrome-os.json b/test/specs/os/chrome-os.json new file mode 100644 index 0000000..69bc878 --- /dev/null +++ b/test/specs/os/chrome-os.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Chrome OS", + "ua" : "Mozilla/5.0 (X11; CrOS x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.0.0 Safari/537.36", + "expect" : + { + "name" : "Chrome OS", + "version" : "undefined" + } + }, + { + "desc" : "Chromium OS", + "ua" : "Mozilla/5.0 (X11; CrOS x86_64 10575.58.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36", + "expect" : + { + "name" : "Chrome OS", + "version" : "10575.58.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/chromecast-android.json b/test/specs/os/chromecast-android.json new file mode 100644 index 0000000..c0969dd --- /dev/null +++ b/test/specs/os/chromecast-android.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Google Chromecast with Google TV", + "ua" : "Mozilla/5.0 (Linux; Android 12.0; Build/STTL.240206.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.0 Safari/537.36 CrKey/1.56.500000 DeviceType/AndroidTV", + "expect" : + { + "name" : "Chromecast Android", + "version" : "12.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/chromecast-fuchsia.json b/test/specs/os/chromecast-fuchsia.json new file mode 100644 index 0000000..5bfecf8 --- /dev/null +++ b/test/specs/os/chromecast-fuchsia.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Google Chromecast Nest Hub", + "ua" : "Mozilla/5.0 (Fuchsia) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 CrKey/1.56.500000", + "expect" : + { + "name" : "Chromecast Fuchsia", + "version" : "1.56.500000" + } + } +] \ No newline at end of file diff --git a/test/specs/os/chromecast-linux.json b/test/specs/os/chromecast-linux.json new file mode 100644 index 0000000..6082346 --- /dev/null +++ b/test/specs/os/chromecast-linux.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Google Chromecast Legacy Linux-Based", + "ua" : "Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.81 Safari/537.36 CrKey/1.42.183786", + "expect" : + { + "name" : "Chromecast Linux", + "version" : "1.42.183786" + } + } +] \ No newline at end of file diff --git a/test/specs/os/chromecast-smartspeaker.json b/test/specs/os/chromecast-smartspeaker.json new file mode 100644 index 0000000..eb6f15b --- /dev/null +++ b/test/specs/os/chromecast-smartspeaker.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Google Chromecast Mini Smart Speaker", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/SmartSpeaker", + "expect" : + { + "name" : "Chromecast SmartSpeaker", + "version" : "1.56.500000" + } + } +] \ No newline at end of file diff --git a/test/specs/os/contiki.json b/test/specs/os/contiki.json new file mode 100644 index 0000000..b8b0503 --- /dev/null +++ b/test/specs/os/contiki.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Contiki", + "ua" : "Contiki/1.0 (Commodore 64; http://dunkels.com/adam/contiki/)", + "expect" : + { + "name" : "Contiki", + "version" : "1.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/debian.json b/test/specs/os/debian.json new file mode 100644 index 0000000..4ae949a --- /dev/null +++ b/test/specs/os/debian.json @@ -0,0 +1,56 @@ +[ + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) (Debian)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (X11; Linux x86_64; Debian GNU/Linux 8.1 (jessie)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.0 Maxthon/1.0.5.3 Safari/537.36", + "expect" : + { + "name" : "Debian", + "version" : "8.1" + } + }, + { + "desc" : "Debian", + "ua" : "ELinks/0.12~pre5-4 (textmode; Debian; Linux 3.2.0-4-amd64 x86_64 192x47-2)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" + } + }, + { + "desc" : "Debian", + "ua" : "w3m/0.5.3+debian-19", + "expect" : + { + "name" : "debian", + "version" : "19" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.3) Gecko/2008092814 (Debian-3.0.1-1)", + "expect" : + { + "name" : "Debian", + "version" : "3.0.1-1" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux 2.6.24.4; X11) KHTML/3.5.9 (like Gecko) (Debian package 4:3.5.9.dfsg.1-2+b1)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/deepin.json b/test/specs/os/deepin.json new file mode 100644 index 0000000..b41e2a3 --- /dev/null +++ b/test/specs/os/deepin.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Deepin", + "ua" : "Mozilla/5.0 (X11; Linux x86_64; Deepin 15.5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36 NFSBrowser/5.0.0.1886", + "expect" : + { + "name" : "Deepin", + "version" : "15.5" + } + } +] \ No newline at end of file diff --git a/test/specs/os/dragonfly.json b/test/specs/os/dragonfly.json new file mode 100644 index 0000000..f8f3c58 --- /dev/null +++ b/test/specs/os/dragonfly.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "DragonFly", + "ua" : "Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1) Gecko/20090720 Firefox/3.5.1", + "expect" : + { + "name" : "DragonFly", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/elementary-os.json b/test/specs/os/elementary-os.json new file mode 100644 index 0000000..1fd5db7 --- /dev/null +++ b/test/specs/os/elementary-os.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "elementary OS", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/604.1 (KHTML, like Gecko) Version/11.0 Safari/604.1 elementary OS/0.4 (Loki) Epiphany/3.18.11", + "expect" : + { + "name" : "elementary OS", + "version" : "0.4" + } + } +] \ No newline at end of file diff --git a/test/specs/os/fedora.json b/test/specs/os/fedora.json new file mode 100644 index 0000000..a7abe1f --- /dev/null +++ b/test/specs/os/fedora.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Fedora", + "ua" : "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0", + "expect" : + { + "name" : "Fedora", + "version" : "undefined" + } + }, + { + "desc" : "Fedora", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:2.0) Gecko/20110404 Fedora/16-dev Firefox/4.0", + "expect" : + { + "name" : "Fedora", + "version" : "16-dev" + } + }, + { + "desc" : "Fedora", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; sk; rv:1.9.0.4) Gecko/2008111217 Fedora/3.0.4-1.fc10 Firefox/3.0.4", + "expect" : + { + "name" : "Fedora", + "version" : "3.0.4-1.fc10" + } + } +] \ No newline at end of file diff --git a/test/specs/os/firefox-os.json b/test/specs/os/firefox-os.json new file mode 100644 index 0000000..faf081a --- /dev/null +++ b/test/specs/os/firefox-os.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Firefox OS", + "ua" : "Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0", + "expect" : + { + "name" : "Firefox OS", + "version" : "14.0" + } + }, + { + "desc" : "Firefox OS on Tablet", + "ua" : "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect" : + { + "name" : "Firefox OS", + "version" : "26.0" + } + }, + { + "desc" : "Firefox OS on TV", + "ua" : "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", + "expect" : + { + "name" : "Firefox OS", + "version" : "44.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/freebsd.json b/test/specs/os/freebsd.json new file mode 100644 index 0000000..74544a0 --- /dev/null +++ b/test/specs/os/freebsd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "FreeBSD", + "ua" : "Mozilla/5.0 (X11; U; FreeBSD x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16", + "expect" : + { + "name" : "FreeBSD", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/fuchsia.json b/test/specs/os/fuchsia.json new file mode 100644 index 0000000..0759cba --- /dev/null +++ b/test/specs/os/fuchsia.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Fuchsia", + "ua" : "Mozilla/5.0 (X11; Fuchsia x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3557.0 Safari/537.36", + "expect" : + { + "name" : "Fuchsia", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/gentoo.json b/test/specs/os/gentoo.json new file mode 100644 index 0000000..8fa207b --- /dev/null +++ b/test/specs/os/gentoo.json @@ -0,0 +1,39 @@ +[ + + { + "desc" : "Gentoo", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.16) Gecko/20080716 (Gentoo) Galeon/2.0.6", + "expect" : + { + "name" : "Gentoo", + "version" : "undefined" + } + }, + { + "desc" : "Gentoo", + "ua" : "Xombrero (X11; U; Gentoo Linux amd64; en-US) Webkit/2.8.5", + "expect" : + { + "name" : "Gentoo", + "version" : "amd64" + } + }, + { + "desc" : "Gentoo", + "ua" : "Xombrero/1.6.4 (Linux amd64; en; Gentoo)", + "expect" : + { + "name" : "Gentoo", + "version" : "undefined" + } + }, + { + "desc" : "Gentoo", + "ua" : "Links (2.8; Linux 3.17.2-gentoo-x86 i686; GNU C 4.8.2; x)", + "expect" : + { + "name" : "gentoo", + "version" : "x86" + } + } +] \ No newline at end of file diff --git a/test/specs/os/ghostbsd.json b/test/specs/os/ghostbsd.json new file mode 100644 index 0000000..5e36d81 --- /dev/null +++ b/test/specs/os/ghostbsd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "GhostBSD", + "ua" : "Mozilla/5.0 (X11; GhostBSD/10.3; x86_64; rv:50.0.1) Gecko/20100101 Firefox/50.0.1", + "expect" : + { + "name" : "GhostBSD", + "version" : "10.3" + } + } +] \ No newline at end of file diff --git a/test/specs/os/haiku.json b/test/specs/os/haiku.json new file mode 100644 index 0000000..7005087 --- /dev/null +++ b/test/specs/os/haiku.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Haiku", + "ua" : "Mozilla/5.0 (Macintosh; Intel Haiku R1 x86) AppleWebKit/602.1.1 (KHTML, like Gecko) WebPositive/1.2 Version/8.0 Safari/602.1.1", + "expect" : + { + "name" : "Haiku", + "version" : "R1" + } + } +] \ No newline at end of file diff --git a/test/specs/os/harmonyos.json b/test/specs/os/harmonyos.json new file mode 100644 index 0000000..1fa13ef --- /dev/null +++ b/test/specs/os/harmonyos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "HarmonyOS", + "ua" : "Mozilla/5.0 (Linux; Android 10; HarmonyOS; YAL-AL10; HMSCore 6.3.0.327; GMSCore 21.48.15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 HuaweiBrowser/12.0.3.310 Mobile Safari/537.36", + "expect" : + { + "name" : "HarmonyOS", + "version" : "10" + } + } +] \ No newline at end of file diff --git a/test/specs/os/hp-ux.json b/test/specs/os/hp-ux.json new file mode 100644 index 0000000..8414740 --- /dev/null +++ b/test/specs/os/hp-ux.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "HP-UX", + "ua" : "Mozilla/5.0 (X11; U; HP-UX 9000/785; es-ES; rv:1.0.1) Gecko/20020827 Netscape/7.0", + "expect" : + { + "name" : "HP-UX", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/hurd.json b/test/specs/os/hurd.json new file mode 100644 index 0000000..0170728 --- /dev/null +++ b/test/specs/os/hurd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Hurd", + "ua" : "Mozilla/5.0 (X11; Hurd 0.9 i386; en-US) libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/3.7.0 Safari/696.96", + "expect" : + { + "name" : "Hurd", + "version" : "0.9" + } + } +] \ No newline at end of file diff --git a/test/specs/os/ios.json b/test/specs/os/ios.json new file mode 100644 index 0000000..66cff1e --- /dev/null +++ b/test/specs/os/ios.json @@ -0,0 +1,56 @@ +[ + { + "desc" : "iOS in App", + "ua" : "AppName/version CFNetwork/version Darwin/version", + "expect" : + { + "name" : "iOS", + "version" : "undefined" + } + }, + { + "desc" : "iOS with Chrome", + "ua" : "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3", + "expect" : + { + "name" : "iOS", + "version" : "5.1.1" + } + }, + { + "desc" : "iOS with Opera Mini", + "ua" : "Opera/9.80 (iPhone; Opera Mini/7.1.32694/27.1407; U; en) Presto/2.8.119 Version/11.10", + "expect" : + { + "name" : "iOS", + "version" : "undefined" + } + }, + { + "desc": "iOS with FaceBook Mobile App", + "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", + "expect": + { + "name" : "iOS", + "version" : "13.6.1" + } + }, + { + "desc": "iOS with Slack App", + "ua": "com.tinyspeck.chatlyio/23.04.10 (iPhone; iOS 16.4.1; Scale/3.00)", + "expect": + { + "name" : "iOS", + "version" : "16.4.1" + } + }, + { + "desc" : "iOS BE App", + "ua" : "APP-BE Test/1.0 (iPad; Apple; CPU iPhone OS 7_0_2 like Mac OS X)", + "expect" : + { + "name" : "iOS", + "version" : "7.0.2" + } + } +] \ No newline at end of file diff --git a/test/specs/os/joli.json b/test/specs/os/joli.json new file mode 100644 index 0000000..e9815fd --- /dev/null +++ b/test/specs/os/joli.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Joli", + "ua" : "Mozilla/5.0 (X11; Jolicloud Linux i686) AppleWebKit/537.6 (KHTML, like Gecko) Joli OS/1.2 Chromium/23.0.1240.0 Chrome/23.0.1240.0 Safari/537.6", + "expect" : + { + "name" : "Joli", + "version" : "1.2" + } + } +] \ No newline at end of file diff --git a/test/specs/os/kaios.json b/test/specs/os/kaios.json new file mode 100644 index 0000000..f59572d --- /dev/null +++ b/test/specs/os/kaios.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "KaiOS", + "ua" : "Mozilla/5.0 (Mobile; Nokia_8110_4G; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5", + "expect" : + { + "name" : "KAIOS", + "version" : "2.5" + } + } +] \ No newline at end of file diff --git a/test/specs/os/kubuntu.json b/test/specs/os/kubuntu.json new file mode 100644 index 0000000..2634256 --- /dev/null +++ b/test/specs/os/kubuntu.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Kubuntu", + "ua" : "Mozilla/5.0 (compatible; Konqueror/4.4; Linux 2.6.32-22-generic; X11; en_US) KHTML/4.4.3 (like Gecko) Kubuntu", + "expect" : + { + "name" : "Kubuntu", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/linpus.json b/test/specs/os/linpus.json new file mode 100644 index 0000000..40c8169 --- /dev/null +++ b/test/specs/os/linpus.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Linpus", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9b5pre) Gecko/2008032619 Linpus/3.0-0.49", + "expect" : + { + "name" : "Linpus", + "version" : "3.0-0.49" + } + } +] \ No newline at end of file diff --git a/test/specs/os/linspire.json b/test/specs/os/linspire.json new file mode 100644 index 0000000..4d2497b --- /dev/null +++ b/test/specs/os/linspire.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Linspire", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.4) Gecko/20060803 Firefox/1.5.0.4 Linspire/1.5.0.4", + "expect" : + { + "name" : "Linspire", + "version" : "1.5.0.4" + } + } +] \ No newline at end of file diff --git a/test/specs/os/linux.json b/test/specs/os/linux.json new file mode 100644 index 0000000..ad86c4e --- /dev/null +++ b/test/specs/os/linux.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Linux", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36", + "expect" : + { + "name" : "Linux", + "version" : "x86_64" + } + } +] \ No newline at end of file diff --git a/test/specs/os/macos.json b/test/specs/os/macos.json new file mode 100644 index 0000000..43f90db --- /dev/null +++ b/test/specs/os/macos.json @@ -0,0 +1,38 @@ +[ + { + "desc" : "Mac OS on PowerPC", + "ua" : "Mozilla/4.0 (compatible; MSIE 5.0b1; Mac_PowerPC)", + "expect" : + { + "name" : "macOS", + "version" : "undefined" + } + }, + { + "desc" : "Mac OS X on x86, x86_64, or aarch64 using Firefox", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "macOS", + "version" : "x.y" + } + }, + { + "desc" : "Mac OS X on PowerPC using Firefox", + "ua" : "Mozilla/5.0 (Macintosh; PPC Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "macOS", + "version" : "x.y" + } + }, + { + "desc" : "Mac OS", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36", + "expect" : + { + "name" : "macOS", + "version" : "10.6.8" + } + } +] \ No newline at end of file diff --git a/test/specs/os/maemo.json b/test/specs/os/maemo.json new file mode 100644 index 0000000..92dfe78 --- /dev/null +++ b/test/specs/os/maemo.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Nokia N900 Linux mobile, on the Fennec browser", + "ua" : "Mozilla/5.0 (Maemo; Linux armv7l; rv:10.0) Gecko/20100101 Firefox/10.0 Fennec/10.0", + "expect" : + { + "name" : "Maemo", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/mandriva.json b/test/specs/os/mandriva.json new file mode 100644 index 0000000..3dbccf7 --- /dev/null +++ b/test/specs/os/mandriva.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Mandriva", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.22) Gecko/20110907 Mandriva Linux/1.9.2.22-0.1mdv2010.2 (2010.2) Firefox/3.6.22", + "expect" : + { + "name" : "Mandriva", + "version" : "1.9.2.22-0.1mdv2010.2" + } + } +] \ No newline at end of file diff --git a/test/specs/os/manjaro.json b/test/specs/os/manjaro.json new file mode 100644 index 0000000..ede015f --- /dev/null +++ b/test/specs/os/manjaro.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Manjaro", + "ua" : "Mozilla/5.0 (X11; Manjaro 19.0.2; Arch; x64; rv:84.0) Gecko/20100101 Firefox/84.0", + "expect" : + { + "name" : "Manjaro", + "version" : "19.0.2" + } + } +] \ No newline at end of file diff --git a/test/specs/os/meego.json b/test/specs/os/meego.json new file mode 100644 index 0000000..a506cde --- /dev/null +++ b/test/specs/os/meego.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "MeeGo", + "ua" : "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", + "expect" : + { + "name" : "MeeGo", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/minix.json b/test/specs/os/minix.json new file mode 100644 index 0000000..d39a514 --- /dev/null +++ b/test/specs/os/minix.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Minix", + "ua" : "Mozilla/5.0 (X11; Original ; Minix 3.3 ; rv:3.0)", + "expect" : + { + "name" : "Minix", + "version" : "3.3" + } + } +] \ No newline at end of file diff --git a/test/specs/os/mint.json b/test/specs/os/mint.json new file mode 100644 index 0000000..e87641e --- /dev/null +++ b/test/specs/os/mint.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Mint", + "ua" : "Opera/9.80 (X11; Linux x86_64; Edition Linux Mint) Presto/2.12.388 Version/12.16", + "expect" : + { + "name" : "Mint", + "version" : "undefined" + } + }, + { + "desc" : "Mint", + "ua" : "Opera/9.64 (X11; Linux i686; U; Linux Mint; nb) Presto/2.1.1", + "expect" : + { + "name" : "Mint", + "version" : "undefined" + } + }, + { + "desc" : "Mint", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.5) Gecko/2008121622 Linux Mint/6 (Felicia) Firefox/3.0.4", + "expect" : + { + "name" : "Mint", + "version" : "6" + } + } +] \ No newline at end of file diff --git a/test/specs/os/morphos.json b/test/specs/os/morphos.json new file mode 100644 index 0000000..f255eeb --- /dev/null +++ b/test/specs/os/morphos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "MorphOS", + "ua" : "AmigaVoyager/3.4.4 (MorphOS/PPC native)", + "expect" : + { + "name" : "MorphOS", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/netbsd.json b/test/specs/os/netbsd.json new file mode 100644 index 0000000..3a7657a --- /dev/null +++ b/test/specs/os/netbsd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "NetBSD", + "ua" : "ELinks (0.4.3; NetBSD 3.0.2PATCH sparc64; 141x19)", + "expect" : + { + "name" : "NetBSD", + "version" : "3.0.2PATCH" + } + } +] \ No newline at end of file diff --git a/test/specs/os/netrange.json b/test/specs/os/netrange.json new file mode 100644 index 0000000..a7ff0a9 --- /dev/null +++ b/test/specs/os/netrange.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Netrange Smart TV", + "ua" : "Mozilla/5.0 (Linux; U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2207.0 LOEWE-SL410/5.2.0.0 HbbTV/1.4.1 (; LOEWE; SL410; LOH/5.2.0.0;;) FVC/3.0 (LOEWE; SL410;) CE-HTML/1.0 Config (L:deu,CC:DEU) NETRANGEMMH", + "expect" : + { + "name" : "NETRANGE", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/nettv.json b/test/specs/os/nettv.json new file mode 100644 index 0000000..2584e40 --- /dev/null +++ b/test/specs/os/nettv.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "NetTV 3.2.1", + "ua" : "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.2.1; en) Presto/2.6.33 Version/10.70", + "expect" : + { + "name" : "NETTV", + "version" : "3.2.1" + } + } +] \ No newline at end of file diff --git a/test/specs/os/nintendo.json b/test/specs/os/nintendo.json new file mode 100644 index 0000000..b8ac8a3 --- /dev/null +++ b/test/specs/os/nintendo.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Nintendo Switch", + "ua" : "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", + "expect" : + { + "name" : "Nintendo", + "version" : "Switch" + } + } +] \ No newline at end of file diff --git a/test/specs/os/openbsd.json b/test/specs/os/openbsd.json new file mode 100644 index 0000000..25164de --- /dev/null +++ b/test/specs/os/openbsd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "OpenBSD", + "ua" : "Mozilla/5.0 (X11; U; OpenBSD i386; en-US; rv:1.9.1) Gecko/20090702 Firefox/3.5", + "expect" : + { + "name" : "OpenBSD", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/openharmony.json b/test/specs/os/openharmony.json new file mode 100644 index 0000000..b0606a1 --- /dev/null +++ b/test/specs/os/openharmony.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "OpenHarmony", + "ua" : "Mozilla/5.0 (Phone; OpenHarmony 4.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 ArkWeb/4.1.6.1 Mobile", + "expect" : + { + "name" : "OpenHarmony", + "version" : "4.1" + } + } +] \ No newline at end of file diff --git a/test/specs/os/os-all.json b/test/specs/os/os-all.json deleted file mode 100644 index b93dc33..0000000 --- a/test/specs/os/os-all.json +++ /dev/null @@ -1,1322 +0,0 @@ -[ - { - "desc" : "Windows 95", - "ua" : "Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)", - "expect" : - { - "name" : "Windows", - "version" : "95" - } - }, - { - "desc" : "Windows 98", - "ua" : "Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)", - "expect" : - { - "name" : "Windows", - "version" : "98" - } - }, - { - "desc" : "Windows ME", - "ua" : "Mozilla/5.0 (Windows; U; Win 9x 4.90) Gecko/20020502 CS 2000 7.0/7.0", - "expect" : - { - "name" : "Windows", - "version" : "ME" - } - }, - { - "desc" : "Windows 2000", - "ua" : "Mozilla/3.0 (compatible; MSIE 3.0; Windows NT 5.0)", - "expect" : - { - "name" : "Windows", - "version" : "2000" - } - }, - { - "desc" : "Windows XP", - "ua" : "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 5.2)", - "expect" : - { - "name" : "Windows", - "version" : "XP" - } - }, - { - "desc" : "Windows Vista", - "ua" : "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; fr-FR)", - "expect" : - { - "name" : "Windows", - "version" : "Vista" - } - }, - { - "desc" : "Windows 7", - "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)", - "expect" : - { - "name" : "Windows", - "version" : "7" - } - }, - { - "desc" : "Windows 8", - "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Win64; x64; Trident/6.0; .NET4.0E; .NET4.0C)", - "expect" : - { - "name" : "Windows", - "version" : "8" - } - }, - { - "desc" : "Windows 10", - "ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0", - "expect" : - { - "name" : "Windows", - "version" : "10" - } - }, - { - "desc" : "WeChat Desktop for Windows Built-in Browser", - "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400", - "expect" : - { - "name" : "Windows", - "version" : "7" - } - }, - { - "desc" : "WeChat Desktop for Windows Built-in Browser major version in 4", - "ua" : "mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/81.0.4044.138 safari/537.36 nettype/wifi micromessenger/7.0.20.1781(0x6700143b) windowswechat", - "expect" : - { - "name" : "Windows", - "version" : "7" - } - }, - { - "desc" : "Windows RT", - "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0)", - "expect" : - { - "name" : "Windows", - "version" : "RT" - } - }, - { - "desc" : "Windows CE", - "ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)", - "expect" : - { - "name" : "Windows", - "version" : "CE" - } - }, - { - "desc" : "Windows Mobile", - "ua" : "Mozilla/5.0 (ZTE-E_N72/N72V1.0.0B02;U;Windows Mobile/6.1;Profile/MIDP-2.0 Configuration/CLDC-1.1;320*240;CTC/2.0) IE/6.0 (compatible; MSIE 4.01; Windows CE; PPC)/UC Browser7.7.1.88", - "expect" : - { - "name" : "Windows Mobile", - "version" : "6.1" - } - }, - { - "desc" : "Windows Mobile", - "ua" : "Opera/9.80 (Windows Mobile; WCE; Opera Mobi/WMD-50433; U; en) Presto/2.4.13 Version/10.00", - "expect" : - { - "name" : "Windows Mobile", - "version" : "undefined" - } - }, - { - "desc" : "Windows Phone", - "ua" : "Opera/9.80 (Windows Phone; Opera Mini/7.6.8/35.7518; U; ru) Presto/2.8.119 Version/11.10", - "expect" : - { - "name" : "Windows Phone", - "version" : "undefined" - } - }, - { - "desc" : "Windows Phone OS", - "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; DELL; Venue Pro)", - "expect" : - { - "name" : "Windows Phone OS", - "version" : "7.0" - } - }, - { - "desc" : "Windows Phone 8", - "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; HTC; Windows Phone 8X by HTC)", - "expect" : - { - "name" : "Windows Phone", - "version" : "8.0" - } - }, - { - "desc" : "Windows NT on x86 or aarch64 CPU using Firefox", - "ua" : "Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0", - "expect" : - { - "name" : "Windows", - "version" : "NT x" - } - }, - { - "desc" : "Windows NT on x64 CPU using Firefox", - "ua" : "Mozilla/5.0 (Windows NT x.y; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0", - "expect" : - { - "name" : "Windows", - "version" : "NT x" - } - }, - { - "desc" : "BlackBerry", - "ua" : "BlackBerry9300/5.0.0.912 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/378", - "expect" : - { - "name" : "BlackBerry", - "version" : "5.0.0.912" - } - }, - { - "desc" : "BlackBerry 10", - "ua" : "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.3+ (KHTML, like Gecko) Version/10.0.9.386 Mobile Safari/537.3+", - "expect" : - { - "name" : "BlackBerry", - "version" : "10" - } - }, - { - "desc" : "Tizen", - "ua" : "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", - "expect" : - { - "name" : "Tizen", - "version" : "2.3" - } - }, - { - "desc" : "Tizen", - "ua" : "Mozilla/5.0 (Linux; Tizen 2.3; SAMSUNG SM-Z130H) AppleWebKit/537.3 (KHTML, like Gecko) Version/2.3 Mobile Safari/537.3", - "expect" : - { - "name" : "Tizen", - "version" : "2.3" - } - }, - { - "desc" : "Tizen 6.0", - "ua" : "HbbTV/1.5.1 (+DRM;Samsung;SmartTV2021:UAU7000;T-KSU2EDEUC-1506.0;KantSU2e;urn:samsungtv:familyname:21_KANTSU2E_UHD_BASIC:2021;) Tizen/6.0 (+TVPLUS+SmartHubLink) Chrome/76 LaTivu_1.0.1_2021 RVID/17", - "expect" : - { - "name" : "Tizen", - "version" : "6.0" - } - }, - { - "desc" : "Android", - "ua" : "Mozilla/5.0 (Linux; U; Android 2.2.2; en-us; VM670 Build/FRG83G) AppleWebKit/533.1 (KHTML, like Gecko)", - "expect" : - { - "name" : "Android", - "version" : "2.2.2" - } - }, - { - "desc" : "HarmonyOS", - "ua" : "Mozilla/5.0 (Linux; Android 10; HarmonyOS; YAL-AL10; HMSCore 6.3.0.327; GMSCore 21.48.15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 HuaweiBrowser/12.0.3.310 Mobile Safari/537.36", - "expect" : - { - "name" : "HarmonyOS", - "version" : "10" - } - }, - { - "desc" : "Sailfish", - "ua" : "Mozilla/5.0 (Linux; U; Sailfish 3.0; Mobile; rv:45.0) Gecko/45.0 Firefox/45.0 SailfishBrowser/1.0", - "expect" : - { - "name" : "Sailfish", - "version" : "3.0" - } - }, - { - "desc" : "WebOS", - "ua" : "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.5; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0", - "expect" : - { - "name" : "webOS", - "version" : "3.0.5" - } - }, - { - "desc" : "WebOS", - "ua" : "Mozilla/5.0 (webOS/1.4.5; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pre/1.0", - "expect" : - { - "name" : "webOS", - "version" : "1.4.5" - } - }, - { - "desc" : "WebOS TV 5.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 WebAppManager", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "WebOS TV 4.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.34 Safari/537.36 WebAppManager", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "WebOS TV 3.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.2.1 Chrome/38.0.2125.122 Safari/537.36 WebAppManager", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "WebOS TV 2.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/538.2 (KHTML, like Gecko) Large Screen WebAppManager Safari/538.2", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "WebOS TV 1.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.41 (KHTML, like Gecko) Large Screen WebAppManager Safari/537.41", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "QNX", - "ua" : "Mozilla/5.0 (Photon; U; QNX x86pc; en-US; rv:1.8.1.20) Gecko/20090127 BonEcho/2.0.0.20", - "expect" : - { - "name" : "QNX", - "version" : "x86pc" - } - }, - { - "desc" : "Bada", - "ua" : "Mozilla/5.0 (SAMSUNG; SAMSUNG-GT-S5253/S5253DDKC1; U; Bada/1.0; en-us) AppleWebKit/533.1 (KHTML, like Gecko) Dolfin/2.0 Mobile WQVGA SMM-MMS/1.2.0 OPN-B", - "expect" : - { - "name" : "Bada", - "version" : "1.0" - } - }, - { - "desc" : "RIM Tablet OS", - "ua" : "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+", - "expect" : - { - "name" : "RIM Tablet OS", - "version" : "2.1.0" - } - }, - { - "desc" : "Nokia N900 Linux mobile, on the Fennec browser", - "ua" : "Mozilla/5.0 (Maemo; Linux armv7l; rv:10.0) Gecko/20100101 Firefox/10.0 Fennec/10.0", - "expect" : - { - "name" : "Maemo", - "version" : "undefined" - } - }, - { - "desc" : "MeeGo", - "ua" : "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", - "expect" : - { - "name" : "MeeGo", - "version" : "undefined" - } - }, - { - "desc" : "Symbian", - "ua" : "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba", - "expect" : - { - "name" : "Symbian", - "version" : "9.4" - } - }, - { - "desc" : "Symbian", - "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaC7-00/024.001; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba", - "expect" : - { - "name" : "Symbian", - "version" : "5.2" - } - }, - { - "desc" : "Series40", - "ua" : "Mozilla/5.0 (Series40; Nokia2055/03.20; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/2.2.0.0.34", - "expect" : - { - "name" : "Series40", - "version" : "undefined" - } - }, - { - "desc" : "Firefox OS", - "ua" : "Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0", - "expect" : - { - "name" : "Firefox OS", - "version" : "14.0" - } - }, - { - "desc" : "Firefox OS on Tablet", - "ua" : "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", - "expect" : - { - "name" : "Firefox OS", - "version" : "26.0" - } - }, - { - "desc" : "Firefox OS on TV", - "ua" : "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", - "expect" : - { - "name" : "Firefox OS", - "version" : "44.0" - } - }, - { - "desc" : "Google Chromecast with Google TV", - "ua" : "Mozilla/5.0 (Linux; Android 12.0; Build/STTL.240206.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.0 Safari/537.36 CrKey/1.56.500000 DeviceType/AndroidTV", - "expect" : - { - "name" : "Chromecast Android", - "version" : "12.0" - } - }, - { - "desc" : "Google Chromecast Nest Hub", - "ua" : "Mozilla/5.0 (Fuchsia) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 CrKey/1.56.500000", - "expect" : - { - "name" : "Chromecast Fuchsia", - "version" : "1.56.500000" - } - }, - { - "desc" : "Google Chromecast Mini Smart Speaker", - "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/SmartSpeaker", - "expect" : - { - "name" : "Chromecast SmartSpeaker", - "version" : "1.56.500000" - } - }, - { - "desc" : "Google Chromecast Legacy Linux-Based", - "ua" : "Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.81 Safari/537.36 CrKey/1.42.183786", - "expect" : - { - "name" : "Chromecast Linux", - "version" : "1.42.183786" - } - }, - { - "desc" : "Nintendo Switch", - "ua" : "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", - "expect" : - { - "name" : "Nintendo", - "version" : "Switch" - } - }, - { - "desc" : "PlayStation 4", - "ua" : "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", - "expect" : - { - "name" : "PlayStation", - "version" : "4" - } - }, - { - "desc" : "PlayStation 5", - "ua" : "Mozilla/5.0 (PlayStation 5/SmartTV) AppleWebKit/605.1.15 (KHTML, like Gecko)", - "expect" : - { - "name" : "PlayStation", - "version" : "5" - } - }, - { - "desc": "Pico 4", - "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.8.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.38 Chrome/105.0.5195.68 VR Safari/537.36", - "expect": { - "name" : "PICO", - "version" : "5.8.2" - } - }, - { - "desc": "Pico 4", - "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0", - "expect": { - "name" : "PICO", - "version" : "5.4.0" - } - }, - { - "desc": "Pico Neo3 Link", - "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", - "expect": { - "name" : "Pico", - "version" : "5.8.4.0" - } - }, - { - "desc" : "Xbox 360", - "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox 360) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "expect" : - { - "name" : "Xbox", - "version" : "360" - } - }, - { - "desc" : "Xbox One", - "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19041", - "expect" : - { - "name" : "Xbox", - "version" : "One" - } - }, - { - "desc" : "Xbox X", - "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02", - "expect" : - { - "name" : "Xbox", - "version" : "X" - } - }, - { - "desc" : "Xbox Series X", - "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox Series X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02 ", - "expect" : - { - "name" : "Xbox", - "version" : "Series X" - } - }, - { - "desc" : "Xbox Series S", - "ua" : "Mozilla/5.0 (Compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Xbox; Xbox Series S)", - "expect" : - { - "name" : "Xbox", - "version" : "Series S" - } - }, - { - "desc" : "Mint", - "ua" : "Opera/9.80 (X11; Linux x86_64; Edition Linux Mint) Presto/2.12.388 Version/12.16", - "expect" : - { - "name" : "Mint", - "version" : "undefined" - } - }, - { - "desc" : "Mint", - "ua" : "Opera/9.64 (X11; Linux i686; U; Linux Mint; nb) Presto/2.1.1", - "expect" : - { - "name" : "Mint", - "version" : "undefined" - } - }, - { - "desc" : "Mint", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.5) Gecko/2008121622 Linux Mint/6 (Felicia) Firefox/3.0.4", - "expect" : - { - "name" : "Mint", - "version" : "6" - } - }, - { - "desc" : "Ubuntu", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.22+ (KHTML, like Gecko) Chromium/17.0.963.56 Chrome/17.0.963.56 Safari/535.22+ Ubuntu/12.04 (3.4.1-0ubuntu1) Epiphany/3.4.1", - "expect" : - { - "name" : "Ubuntu", - "version" : "12.04" - } - }, - { - "desc" : "Ubuntu", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/31.0.1650.63 Chrome/31.0.1650.63 Safari/537.36", - "expect" : - { - "name" : "Ubuntu", - "version" : "undefined" - } - }, - { - "desc" : "Kubuntu", - "ua" : "Mozilla/5.0 (compatible; Konqueror/4.4; Linux 2.6.32-22-generic; X11; en_US) KHTML/4.4.3 (like Gecko) Kubuntu", - "expect" : - { - "name" : "Kubuntu", - "version" : "undefined" - } - }, - { - "desc" : "Debian", - "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) (Debian)", - "expect" : - { - "name" : "Debian", - "version" : "undefined" - } - }, - { - "desc" : "Debian", - "ua" : "Mozilla/5.0 (X11; Linux x86_64; Debian GNU/Linux 8.1 (jessie)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.0 Maxthon/1.0.5.3 Safari/537.36", - "expect" : - { - "name" : "Debian", - "version" : "8.1" - } - }, - { - "desc" : "Debian", - "ua" : "ELinks/0.12~pre5-4 (textmode; Debian; Linux 3.2.0-4-amd64 x86_64 192x47-2)", - "expect" : - { - "name" : "Debian", - "version" : "undefined" - } - }, - { - "desc" : "Debian", - "ua" : "w3m/0.5.3+debian-19", - "expect" : - { - "name" : "debian", - "version" : "19" - } - }, - { - "desc" : "Debian", - "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.3) Gecko/2008092814 (Debian-3.0.1-1)", - "expect" : - { - "name" : "Debian", - "version" : "3.0.1-1" - } - }, - { - "desc" : "Debian", - "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux 2.6.24.4; X11) KHTML/3.5.9 (like Gecko) (Debian package 4:3.5.9.dfsg.1-2+b1)", - "expect" : - { - "name" : "Debian", - "version" : "undefined" - } - }, - { - "desc" : "OpenSUSE", - "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110420 SUSE/3.6.17-0.2.1 Firefox/3.6.17", - "expect" : - { - "name" : "SUSE", - "version" : "3.6.17-0.2.1" - } - }, - { - "desc" : "Gentoo", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.16) Gecko/20080716 (Gentoo) Galeon/2.0.6", - "expect" : - { - "name" : "Gentoo", - "version" : "undefined" - } - }, - { - "desc" : "Gentoo", - "ua" : "Xombrero (X11; U; Gentoo Linux amd64; en-US) Webkit/2.8.5", - "expect" : - { - "name" : "Gentoo", - "version" : "amd64" - } - }, - { - "desc" : "Gentoo", - "ua" : "Xombrero/1.6.4 (Linux amd64; en; Gentoo)", - "expect" : - { - "name" : "Gentoo", - "version" : "undefined" - } - }, - { - "desc" : "Gentoo", - "ua" : "Links (2.8; Linux 3.17.2-gentoo-x86 i686; GNU C 4.8.2; x)", - "expect" : - { - "name" : "gentoo", - "version" : "x86" - } - }, - { - "desc" : "Arch", - "ua" : "Uzbl (Webkit 1.1.10) (Arch Linux)", - "expect" : - { - "name" : "Arch", - "version" : "undefined" - } - }, - { - "desc" : "Slackware", - "ua" : "Mozilla/5.0 Slackware/13.37 (X11; U; Linux x86_64; en-US) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41", - "expect" : - { - "name" : "Slackware", - "version" : "13.37" - } - }, - { - "desc" : "Fedora", - "ua" : "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0", - "expect" : - { - "name" : "Fedora", - "version" : "undefined" - } - }, - { - "desc" : "Fedora", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:2.0) Gecko/20110404 Fedora/16-dev Firefox/4.0", - "expect" : - { - "name" : "Fedora", - "version" : "16-dev" - } - }, - { - "desc" : "Fedora", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; sk; rv:1.9.0.4) Gecko/2008111217 Fedora/3.0.4-1.fc10 Firefox/3.0.4", - "expect" : - { - "name" : "Fedora", - "version" : "3.0.4-1.fc10" - } - }, - { - "desc" : "Mandriva", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.22) Gecko/20110907 Mandriva Linux/1.9.2.22-0.1mdv2010.2 (2010.2) Firefox/3.6.22", - "expect" : - { - "name" : "Mandriva", - "version" : "1.9.2.22-0.1mdv2010.2" - } - }, - { - "desc" : "Chrome OS", - "ua" : "Mozilla/5.0 (X11; CrOS x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.0.0 Safari/537.36", - "expect" : - { - "name" : "Chrome OS", - "version" : "undefined" - } - }, - { - "desc" : "Chromium OS", - "ua" : "Mozilla/5.0 (X11; CrOS x86_64 10575.58.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36", - "expect" : - { - "name" : "Chrome OS", - "version" : "10575.58.0" - } - }, - { - "desc" : "Fuchsia", - "ua" : "Mozilla/5.0 (X11; Fuchsia x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3557.0 Safari/537.36", - "expect" : - { - "name" : "Fuchsia", - "version" : "undefined" - } - }, - { - "desc" : "Solaris", - "ua" : "Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7) Gecko/20070606", - "expect" : - { - "name" : "Solaris", - "version" : "sun4u" - } - }, - { - "desc" : "FreeBSD", - "ua" : "Mozilla/5.0 (X11; U; FreeBSD x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16", - "expect" : - { - "name" : "FreeBSD", - "version" : "undefined" - } - }, - { - "desc" : "OpenBSD", - "ua" : "Mozilla/5.0 (X11; U; OpenBSD i386; en-US; rv:1.9.1) Gecko/20090702 Firefox/3.5", - "expect" : - { - "name" : "OpenBSD", - "version" : "undefined" - } - }, - { - "desc" : "NetBSD", - "ua" : "ELinks (0.4.3; NetBSD 3.0.2PATCH sparc64; 141x19)", - "expect" : - { - "name" : "NetBSD", - "version" : "3.0.2PATCH" - } - }, - { - "desc" : "DragonFly", - "ua" : "Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1) Gecko/20090720 Firefox/3.5.1", - "expect" : - { - "name" : "DragonFly", - "version" : "undefined" - } - }, - { - "desc" : "iOS in App", - "ua" : "AppName/version CFNetwork/version Darwin/version", - "expect" : - { - "name" : "iOS", - "version" : "undefined" - } - }, - { - "desc" : "iOS with Chrome", - "ua" : "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3", - "expect" : - { - "name" : "iOS", - "version" : "5.1.1" - } - }, - { - "desc" : "iOS with Opera Mini", - "ua" : "Opera/9.80 (iPhone; Opera Mini/7.1.32694/27.1407; U; en) Presto/2.8.119 Version/11.10", - "expect" : - { - "name" : "iOS", - "version" : "undefined" - } - }, - { - "desc": "iOS with FaceBook Mobile App", - "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", - "expect": - { - "name" : "iOS", - "version" : "13.6.1" - } - }, - { - "desc": "iOS with Slack App", - "ua": "com.tinyspeck.chatlyio/23.04.10 (iPhone; iOS 16.4.1; Scale/3.00)", - "expect": - { - "name" : "iOS", - "version" : "16.4.1" - } - }, - { - "desc" : "watchOS", - "ua" : "server-bag [Watch OS,8.4,19S546,Watch3,4]", - "expect" : - { - "name" : "watchOS", - "version" : "8.4" - } - }, - { - "desc" : "watchOS", - "ua" : "atc/1.0 watchOS/7.4.1 model/Watch3,3 hwp/t8004 build/18T201 (6; dt:155)", - "expect" : - { - "name" : "watchOS", - "version" : "7.4.1" - } - }, - { - "desc" : "watchOS", - "ua" : "Watch4,3/5.3.8 (16U680)", - "expect" : - { - "name" : "watchOS", - "version" : "5.3.8" - } - }, - { - "desc" : "Mac OS on PowerPC", - "ua" : "Mozilla/4.0 (compatible; MSIE 5.0b1; Mac_PowerPC)", - "expect" : - { - "name" : "macOS", - "version" : "undefined" - } - }, - { - "desc" : "Mac OS X on x86, x86_64, or aarch64 using Firefox", - "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", - "expect" : - { - "name" : "macOS", - "version" : "x.y" - } - }, - { - "desc" : "Mac OS X on PowerPC using Firefox", - "ua" : "Mozilla/5.0 (Macintosh; PPC Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", - "expect" : - { - "name" : "macOS", - "version" : "x.y" - } - }, - { - "desc" : "Mac OS", - "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36", - "expect" : - { - "name" : "macOS", - "version" : "10.6.8" - } - }, - { - "desc" : "Haiku", - "ua" : "Mozilla/5.0 (Macintosh; Intel Haiku R1 x86) AppleWebKit/602.1.1 (KHTML, like Gecko) WebPositive/1.2 Version/8.0 Safari/602.1.1", - "expect" : - { - "name" : "Haiku", - "version" : "R1" - } - }, - { - "desc" : "KaiOS", - "ua" : "Mozilla/5.0 (Mobile; Nokia_8110_4G; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5", - "expect" : - { - "name" : "KAIOS", - "version" : "2.5" - } - }, - { - "desc" : "iTunes Windows Vista", - "ua" : "iTunes/10.7 (Windows; Microsoft Windows Vista Home Premium Edition Service Pack 1 (Build 6001)) AppleWebKit/536.26.9", - "expect" : - { - "name" : "Windows", - "version" : "Vista" - } - }, - { - "desc" : "iOS BE App", - "ua" : "APP-BE Test/1.0 (iPad; Apple; CPU iPhone OS 7_0_2 like Mac OS X)", - "expect" : - { - "name" : "iOS", - "version" : "7.0.2" - } - }, - { - "desc" : "KTB-Nexus 5", - "ua" : "APP-My App/1.0 (Linux; Android 4.2.1; Nexus 5 Build/JOP40D)", - "expect" : - { - "name" : "Android", - "version" : "4.2.1" - } - }, - { - "desc" : "Solaris", - "ua" : "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", - "expect" : - { - "name" : "Solaris", - "version" : "4.1.4" - } - }, - { - "desc" : "Raspbian", - "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/72.0.3626.121 HeadlessChrome/72.0.3626.121 Safari/537.36", - "expect" : - { - "name" : "Raspbian", - "version" : "undefined" - } - }, - { - "desc" : "Raspbian", - "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15 Raspbian/9.0 (1:3.8.2.0-0rpi28) Epiphany/3.8.2", - "expect" : - { - "name" : "Raspbian", - "version" : "9.0" - } - }, - { - "desc" : "AIX", - "ua" : "Mozilla/5.0 (X11; U; AIX 000138384C00; en-US; rv:1.0.1) Gecko/20030213 Netscape/7.0", - "expect" : - { - "name" : "AIX", - "version" : "undefined" - } - }, - { - "desc" : "Plan9", - "ua" : "NCSA_Mosaic/5.0 (X11;Plan 9 4.0)", - "expect" : - { - "name" : "Plan 9", - "version" : "4.0" - } - }, - { - "desc" : "Minix", - "ua" : "Mozilla/5.0 (X11; Original ; Minix 3.3 ; rv:3.0)", - "expect" : - { - "name" : "Minix", - "version" : "3.3" - } - }, - { - "desc" : "BeOS", - "ua" : "Mozilla/5.0 (BeOS; U; BeOS BePC; en-US; rv:1.8.1.8pre) Gecko/20070926 SeaMonkey/1.1.5pre", - "expect" : - { - "name" : "BeOS", - "version" : "undefined" - } - }, - { - "desc" : "OS/2", - "ua" : "Links (2.1pre14; OS/2 1 i386; 80x33)", - "expect" : - { - "name" : "OS/2", - "version" : "undefined" - } - }, - { - "desc" : "AmigaOS", - "ua" : "Mozilla/4.0 (compatible; AWEB 3.4 SE; AmigaOS)", - "expect" : - { - "name" : "AmigaOS", - "version" : "undefined" - } - }, - { - "desc" : "MorphOS", - "ua" : "AmigaVoyager/3.4.4 (MorphOS/PPC native)", - "expect" : - { - "name" : "MorphOS", - "version" : "undefined" - } - }, - { - "desc" : "UNIX", - "ua" : "Surf/0.4.1 (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)", - "expect" : - { - "name" : "Unix", - "version" : "undefined" - } - }, - { - "desc" : "Joli", - "ua" : "Mozilla/5.0 (X11; Jolicloud Linux i686) AppleWebKit/537.6 (KHTML, like Gecko) Joli OS/1.2 Chromium/23.0.1240.0 Chrome/23.0.1240.0 Safari/537.6", - "expect" : - { - "name" : "Joli", - "version" : "1.2" - } - }, - { - "desc" : "CentOS", - "ua" : "Konqueror/15.13 (CentOS Linux 7.4; cs-CZ;)", - "expect" : - { - "name" : "CentOS", - "version" : "7.4" - } - }, - { - "desc" : "PCLinuxOS", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101209 PCLinuxOS/1.9.2.13-1pclos2010 (2010) Firefox/3.6.13", - "expect" : - { - "name" : "PCLinuxOS", - "version" : "1.9.2.13-1pclos2010" - } - }, - { - "desc" : "RedHat", - "ua" : "Mozilla/5.0 (compatible; Konqueror/4.3; Linux) KHTML/4.3.4 (like Gecko) Red Hat Enterprise Linux/4.3.4-11.el6_1.4", - "expect" : - { - "name" : "Red Hat", - "version" : "4.3.4-11.el6_1.4" - } - }, - { - "desc" : "RedHat", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.13pre) Gecko/20070717 Red Hat/1.0.9-4.el4 SeaMonkey/1.0.9", - "expect" : - { - "name" : "Red Hat", - "version" : "1.0.9-4.el4" - } - }, - { - "desc" : "RedHat", - "ua" : "iTunes/4.7.1 (Linux; N; Red Hat; x86_64-linux; EN; utf8) SqueezeCenter, Squeezebox Server, Logitech Media Server/7.9.1/1522157629", - "expect" : - { - "name" : "Red Hat", - "version" : "undefined" - } - }, - { - "desc" : "RedHat", - "ua" : "curl/7.20.0 (x86_64-redhat-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5", - "expect" : - { - "name" : "redhat", - "version" : "undefined" - } - }, - { - "desc" : "RISC OS", - "ua" : "Mozilla/1.10 [en] (Compatible; RISC OS 3.70; Oregano 1.10)", - "expect" : - { - "name" : "RISC OS", - "version" : "3.70" - } - }, - { - "desc" : "Zenwalk", - "ua" : "Flock/2.16 (Zenwalk 7.3; es_PR;)", - "expect" : - { - "name" : "Zenwalk", - "version" : "7.3" - } - }, - { - "desc" : "Hurd", - "ua" : "Mozilla/5.0 (X11; Hurd 0.9 i386; en-US) libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/3.7.0 Safari/696.96", - "expect" : - { - "name" : "Hurd", - "version" : "0.9" - } - }, - { - "desc" : "Linux", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36", - "expect" : - { - "name" : "Linux", - "version" : "x86_64" - } - }, - { - "desc" : "Deepin", - "ua" : "Mozilla/5.0 (X11; Linux x86_64; Deepin 15.5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36 NFSBrowser/5.0.0.1886", - "expect" : - { - "name" : "Deepin", - "version" : "15.5" - } - }, - { - "desc" : "Palm OS", - "ua" : "Mozilla/4.76 [en] (PalmOS; U; WebPro3.0; Palm-Arz1)", - "expect" : - { - "name" : "Palm", - "version" : "undefined" - } - }, - { - "desc" : "Panasonic Viera", - "ua" : "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", - "expect" : - { - "name" : "VIERA", - "version" : "undefined" - } - }, - { - "desc" : "Netrange Smart TV", - "ua" : "Mozilla/5.0 (Linux; U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2207.0 LOEWE-SL410/5.2.0.0 HbbTV/1.4.1 (; LOEWE; SL410; LOH/5.2.0.0;;) FVC/3.0 (LOEWE; SL410;) CE-HTML/1.0 Config (L:deu,CC:DEU) NETRANGEMMH", - "expect" : - { - "name" : "NETRANGE", - "version" : "undefined" - } - }, - { - "desc" : "NetTV 3.2.1", - "ua" : "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.2.1; en) Presto/2.6.33 Version/10.70", - "expect" : - { - "name" : "NETTV", - "version" : "3.2.1" - } - }, - { - "desc" : "HP-UX", - "ua" : "Mozilla/5.0 (X11; U; HP-UX 9000/785; es-ES; rv:1.0.1) Gecko/20020827 Netscape/7.0", - "expect" : - { - "name" : "HP-UX", - "version" : "undefined" - } - }, - { - "desc" : "Contiki", - "ua" : "Contiki/1.0 (Commodore 64; http://dunkels.com/adam/contiki/)", - "expect" : - { - "name" : "Contiki", - "version" : "1.0" - } - }, - { - "desc" : "Linpus", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9b5pre) Gecko/2008032619 Linpus/3.0-0.49", - "expect" : - { - "name" : "Linpus", - "version" : "3.0-0.49" - } - }, - { - "desc" : "Manjaro", - "ua" : "Mozilla/5.0 (X11; Manjaro 19.0.2; Arch; x64; rv:84.0) Gecko/20100101 Firefox/84.0", - "expect" : - { - "name" : "Manjaro", - "version" : "19.0.2" - } - }, - { - "desc" : "elementary OS", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/604.1 (KHTML, like Gecko) Version/11.0 Safari/604.1 elementary OS/0.4 (Loki) Epiphany/3.18.11", - "expect" : - { - "name" : "elementary OS", - "version" : "0.4" - } - }, - { - "desc" : "GhostBSD", - "ua" : "Mozilla/5.0 (X11; GhostBSD/10.3; x86_64; rv:50.0.1) Gecko/20100101 Firefox/50.0.1", - "expect" : - { - "name" : "GhostBSD", - "version" : "10.3" - } - }, - { - "desc" : "Android-x86", - "ua" : "Mozilla/5.0 (Linux; Android 7.1.2; Generic Android-x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 OPR/61.2.3076.56749", - "expect" : - { - "name" : "Android-x86", - "version" : "7.1.2" - } - }, - { - "desc" : "Sabayon", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Sabayon Chrome/19.0.1084.46 Safari/536.5", - "expect" : - { - "name" : "Sabayon", - "version" : "undefined" - } - }, - { - "desc" : "Linspire", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.4) Gecko/20060803 Firefox/1.5.0.4 Linspire/1.5.0.4", - "expect" : - { - "name" : "Linspire", - "version" : "1.5.0.4" - } - }, - { - "desc" : "SerenityOS", - "ua" : "Mozilla/4.0 (SerenityOS; x86) LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb", - "expect" : - { - "name" : "SerenityOS", - "version" : "undefined" - } - }, - { - "desc" : "OpenHarmony", - "ua" : "Mozilla/5.0 (Phone; OpenHarmony 4.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 ArkWeb/4.1.6.1 Mobile", - "expect" : - { - "name" : "OpenHarmony", - "version" : "4.1" - } - } -] diff --git a/test/specs/os/os2.json b/test/specs/os/os2.json new file mode 100644 index 0000000..cb38c11 --- /dev/null +++ b/test/specs/os/os2.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "OS/2", + "ua" : "Links (2.1pre14; OS/2 1 i386; 80x33)", + "expect" : + { + "name" : "OS/2", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/palm.json b/test/specs/os/palm.json new file mode 100644 index 0000000..5fc831e --- /dev/null +++ b/test/specs/os/palm.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Palm OS", + "ua" : "Mozilla/4.76 [en] (PalmOS; U; WebPro3.0; Palm-Arz1)", + "expect" : + { + "name" : "Palm", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/pclinuxos.json b/test/specs/os/pclinuxos.json new file mode 100644 index 0000000..521b4be --- /dev/null +++ b/test/specs/os/pclinuxos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "PCLinuxOS", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101209 PCLinuxOS/1.9.2.13-1pclos2010 (2010) Firefox/3.6.13", + "expect" : + { + "name" : "PCLinuxOS", + "version" : "1.9.2.13-1pclos2010" + } + } +] \ No newline at end of file diff --git a/test/specs/os/pico.json b/test/specs/os/pico.json new file mode 100644 index 0000000..456a5fa --- /dev/null +++ b/test/specs/os/pico.json @@ -0,0 +1,26 @@ +[ + { + "desc": "Pico 4", + "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.8.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.38 Chrome/105.0.5195.68 VR Safari/537.36", + "expect": { + "name" : "PICO", + "version" : "5.8.2" + } + }, + { + "desc": "Pico 4", + "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0", + "expect": { + "name" : "PICO", + "version" : "5.4.0" + } + }, + { + "desc": "Pico Neo3 Link", + "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", + "expect": { + "name" : "Pico", + "version" : "5.8.4.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/plan9.json b/test/specs/os/plan9.json new file mode 100644 index 0000000..e3726fb --- /dev/null +++ b/test/specs/os/plan9.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Plan9", + "ua" : "NCSA_Mosaic/5.0 (X11;Plan 9 4.0)", + "expect" : + { + "name" : "Plan 9", + "version" : "4.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/playstation.json b/test/specs/os/playstation.json new file mode 100644 index 0000000..38cf97f --- /dev/null +++ b/test/specs/os/playstation.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "PlayStation 4", + "ua" : "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", + "expect" : + { + "name" : "PlayStation", + "version" : "4" + } + }, + { + "desc" : "PlayStation 5", + "ua" : "Mozilla/5.0 (PlayStation 5/SmartTV) AppleWebKit/605.1.15 (KHTML, like Gecko)", + "expect" : + { + "name" : "PlayStation", + "version" : "5" + } + } +] \ No newline at end of file diff --git a/test/specs/os/qnx.json b/test/specs/os/qnx.json new file mode 100644 index 0000000..fcb3ed1 --- /dev/null +++ b/test/specs/os/qnx.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "QNX", + "ua" : "Mozilla/5.0 (Photon; U; QNX x86pc; en-US; rv:1.8.1.20) Gecko/20090127 BonEcho/2.0.0.20", + "expect" : + { + "name" : "QNX", + "version" : "x86pc" + } + } +] \ No newline at end of file diff --git a/test/specs/os/raspbian.json b/test/specs/os/raspbian.json new file mode 100644 index 0000000..10fd9fb --- /dev/null +++ b/test/specs/os/raspbian.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Raspbian", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/72.0.3626.121 HeadlessChrome/72.0.3626.121 Safari/537.36", + "expect" : + { + "name" : "Raspbian", + "version" : "undefined" + } + }, + { + "desc" : "Raspbian", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15 Raspbian/9.0 (1:3.8.2.0-0rpi28) Epiphany/3.8.2", + "expect" : + { + "name" : "Raspbian", + "version" : "9.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/redhat.json b/test/specs/os/redhat.json new file mode 100644 index 0000000..89f3e25 --- /dev/null +++ b/test/specs/os/redhat.json @@ -0,0 +1,38 @@ +[ + { + "desc" : "RedHat", + "ua" : "Mozilla/5.0 (compatible; Konqueror/4.3; Linux) KHTML/4.3.4 (like Gecko) Red Hat Enterprise Linux/4.3.4-11.el6_1.4", + "expect" : + { + "name" : "Red Hat", + "version" : "4.3.4-11.el6_1.4" + } + }, + { + "desc" : "RedHat", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.13pre) Gecko/20070717 Red Hat/1.0.9-4.el4 SeaMonkey/1.0.9", + "expect" : + { + "name" : "Red Hat", + "version" : "1.0.9-4.el4" + } + }, + { + "desc" : "RedHat", + "ua" : "iTunes/4.7.1 (Linux; N; Red Hat; x86_64-linux; EN; utf8) SqueezeCenter, Squeezebox Server, Logitech Media Server/7.9.1/1522157629", + "expect" : + { + "name" : "Red Hat", + "version" : "undefined" + } + }, + { + "desc" : "RedHat", + "ua" : "curl/7.20.0 (x86_64-redhat-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5", + "expect" : + { + "name" : "redhat", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/rim-tablet-os.json b/test/specs/os/rim-tablet-os.json new file mode 100644 index 0000000..4451c3c --- /dev/null +++ b/test/specs/os/rim-tablet-os.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "RIM Tablet OS", + "ua" : "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+", + "expect" : + { + "name" : "RIM Tablet OS", + "version" : "2.1.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/risc-os.json b/test/specs/os/risc-os.json new file mode 100644 index 0000000..5442784 --- /dev/null +++ b/test/specs/os/risc-os.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "RISC OS", + "ua" : "Mozilla/1.10 [en] (Compatible; RISC OS 3.70; Oregano 1.10)", + "expect" : + { + "name" : "RISC OS", + "version" : "3.70" + } + } +] \ No newline at end of file diff --git a/test/specs/os/sabayon.json b/test/specs/os/sabayon.json new file mode 100644 index 0000000..d44f9e2 --- /dev/null +++ b/test/specs/os/sabayon.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Sabayon", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Sabayon Chrome/19.0.1084.46 Safari/536.5", + "expect" : + { + "name" : "Sabayon", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/sailfish.json b/test/specs/os/sailfish.json new file mode 100644 index 0000000..f96376b --- /dev/null +++ b/test/specs/os/sailfish.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Sailfish", + "ua" : "Mozilla/5.0 (Linux; U; Sailfish 3.0; Mobile; rv:45.0) Gecko/45.0 Firefox/45.0 SailfishBrowser/1.0", + "expect" : + { + "name" : "Sailfish", + "version" : "3.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/serenityos.json b/test/specs/os/serenityos.json new file mode 100644 index 0000000..748546e --- /dev/null +++ b/test/specs/os/serenityos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "SerenityOS", + "ua" : "Mozilla/4.0 (SerenityOS; x86) LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb", + "expect" : + { + "name" : "SerenityOS", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/series40.json b/test/specs/os/series40.json new file mode 100644 index 0000000..1b02c15 --- /dev/null +++ b/test/specs/os/series40.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Series40", + "ua" : "Mozilla/5.0 (Series40; Nokia2055/03.20; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/2.2.0.0.34", + "expect" : + { + "name" : "Series40", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/slackware.json b/test/specs/os/slackware.json new file mode 100644 index 0000000..35f446e --- /dev/null +++ b/test/specs/os/slackware.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Slackware", + "ua" : "Mozilla/5.0 Slackware/13.37 (X11; U; Linux x86_64; en-US) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41", + "expect" : + { + "name" : "Slackware", + "version" : "13.37" + } + } +] \ No newline at end of file diff --git a/test/specs/os/solaris.json b/test/specs/os/solaris.json new file mode 100644 index 0000000..450e47d --- /dev/null +++ b/test/specs/os/solaris.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Solaris", + "ua" : "Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7) Gecko/20070606", + "expect" : + { + "name" : "Solaris", + "version" : "sun4u" + } + }, + { + "desc" : "Solaris", + "ua" : "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", + "expect" : + { + "name" : "Solaris", + "version" : "4.1.4" + } + } +] \ No newline at end of file diff --git a/test/specs/os/suse.json b/test/specs/os/suse.json new file mode 100644 index 0000000..9da3f35 --- /dev/null +++ b/test/specs/os/suse.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "OpenSUSE", + "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110420 SUSE/3.6.17-0.2.1 Firefox/3.6.17", + "expect" : + { + "name" : "SUSE", + "version" : "3.6.17-0.2.1" + } + } +] \ No newline at end of file diff --git a/test/specs/os/symbian.json b/test/specs/os/symbian.json new file mode 100644 index 0000000..24f509e --- /dev/null +++ b/test/specs/os/symbian.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Symbian", + "ua" : "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba", + "expect" : + { + "name" : "Symbian", + "version" : "9.4" + } + }, + { + "desc" : "Symbian", + "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaC7-00/024.001; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba", + "expect" : + { + "name" : "Symbian", + "version" : "5.2" + } + } +] \ No newline at end of file diff --git a/test/specs/os/tizen.json b/test/specs/os/tizen.json new file mode 100644 index 0000000..4f9320d --- /dev/null +++ b/test/specs/os/tizen.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Tizen", + "ua" : "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", + "expect" : + { + "name" : "Tizen", + "version" : "2.3" + } + }, + { + "desc" : "Tizen", + "ua" : "Mozilla/5.0 (Linux; Tizen 2.3; SAMSUNG SM-Z130H) AppleWebKit/537.3 (KHTML, like Gecko) Version/2.3 Mobile Safari/537.3", + "expect" : + { + "name" : "Tizen", + "version" : "2.3" + } + }, + { + "desc" : "Tizen 6.0", + "ua" : "HbbTV/1.5.1 (+DRM;Samsung;SmartTV2021:UAU7000;T-KSU2EDEUC-1506.0;KantSU2e;urn:samsungtv:familyname:21_KANTSU2E_UHD_BASIC:2021;) Tizen/6.0 (+TVPLUS+SmartHubLink) Chrome/76 LaTivu_1.0.1_2021 RVID/17", + "expect" : + { + "name" : "Tizen", + "version" : "6.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/ubuntu.json b/test/specs/os/ubuntu.json new file mode 100644 index 0000000..d3958f9 --- /dev/null +++ b/test/specs/os/ubuntu.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Ubuntu", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.22+ (KHTML, like Gecko) Chromium/17.0.963.56 Chrome/17.0.963.56 Safari/535.22+ Ubuntu/12.04 (3.4.1-0ubuntu1) Epiphany/3.4.1", + "expect" : + { + "name" : "Ubuntu", + "version" : "12.04" + } + }, + { + "desc" : "Ubuntu", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/31.0.1650.63 Chrome/31.0.1650.63 Safari/537.36", + "expect" : + { + "name" : "Ubuntu", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/unix.json b/test/specs/os/unix.json new file mode 100644 index 0000000..18e7332 --- /dev/null +++ b/test/specs/os/unix.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "UNIX", + "ua" : "Surf/0.4.1 (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)", + "expect" : + { + "name" : "Unix", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/watchos.json b/test/specs/os/watchos.json new file mode 100644 index 0000000..ec2c30b --- /dev/null +++ b/test/specs/os/watchos.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "watchOS", + "ua" : "server-bag [Watch OS,8.4,19S546,Watch3,4]", + "expect" : + { + "name" : "watchOS", + "version" : "8.4" + } + }, + { + "desc" : "watchOS", + "ua" : "atc/1.0 watchOS/7.4.1 model/Watch3,3 hwp/t8004 build/18T201 (6; dt:155)", + "expect" : + { + "name" : "watchOS", + "version" : "7.4.1" + } + }, + { + "desc" : "watchOS", + "ua" : "Watch4,3/5.3.8 (16U680)", + "expect" : + { + "name" : "watchOS", + "version" : "5.3.8" + } + } +] \ No newline at end of file diff --git a/test/specs/os/webos.json b/test/specs/os/webos.json new file mode 100644 index 0000000..c31cd3f --- /dev/null +++ b/test/specs/os/webos.json @@ -0,0 +1,65 @@ +[ + { + "desc" : "WebOS", + "ua" : "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.5; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0", + "expect" : + { + "name" : "webOS", + "version" : "3.0.5" + } + }, + { + "desc" : "WebOS", + "ua" : "Mozilla/5.0 (webOS/1.4.5; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pre/1.0", + "expect" : + { + "name" : "webOS", + "version" : "1.4.5" + } + }, + { + "desc" : "WebOS TV 5.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 4.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.34 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 3.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.2.1 Chrome/38.0.2125.122 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 2.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/538.2 (KHTML, like Gecko) Large Screen WebAppManager Safari/538.2", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 1.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.41 (KHTML, like Gecko) Large Screen WebAppManager Safari/537.41", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + } +] \ No newline at end of file diff --git a/test/specs/os/windows-mobile.json b/test/specs/os/windows-mobile.json new file mode 100644 index 0000000..5baf78c --- /dev/null +++ b/test/specs/os/windows-mobile.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Windows Mobile", + "ua" : "Mozilla/5.0 (ZTE-E_N72/N72V1.0.0B02;U;Windows Mobile/6.1;Profile/MIDP-2.0 Configuration/CLDC-1.1;320*240;CTC/2.0) IE/6.0 (compatible; MSIE 4.01; Windows CE; PPC)/UC Browser7.7.1.88", + "expect" : + { + "name" : "Windows Mobile", + "version" : "6.1" + } + }, + { + "desc" : "Windows Mobile", + "ua" : "Opera/9.80 (Windows Mobile; WCE; Opera Mobi/WMD-50433; U; en) Presto/2.4.13 Version/10.00", + "expect" : + { + "name" : "Windows Mobile", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/specs/os/windows-phone.json b/test/specs/os/windows-phone.json new file mode 100644 index 0000000..a6a8b82 --- /dev/null +++ b/test/specs/os/windows-phone.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Windows Phone", + "ua" : "Opera/9.80 (Windows Phone; Opera Mini/7.6.8/35.7518; U; ru) Presto/2.8.119 Version/11.10", + "expect" : + { + "name" : "Windows Phone", + "version" : "undefined" + } + }, + { + "desc" : "Windows Phone OS", + "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; DELL; Venue Pro)", + "expect" : + { + "name" : "Windows Phone OS", + "version" : "7.0" + } + }, + { + "desc" : "Windows Phone 8", + "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; HTC; Windows Phone 8X by HTC)", + "expect" : + { + "name" : "Windows Phone", + "version" : "8.0" + } + } +] \ No newline at end of file diff --git a/test/specs/os/windows.json b/test/specs/os/windows.json new file mode 100644 index 0000000..39e9541 --- /dev/null +++ b/test/specs/os/windows.json @@ -0,0 +1,146 @@ +[ + { + "desc" : "Windows 95", + "ua" : "Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)", + "expect" : + { + "name" : "Windows", + "version" : "95" + } + }, + { + "desc" : "Windows 98", + "ua" : "Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)", + "expect" : + { + "name" : "Windows", + "version" : "98" + } + }, + { + "desc" : "Windows ME", + "ua" : "Mozilla/5.0 (Windows; U; Win 9x 4.90) Gecko/20020502 CS 2000 7.0/7.0", + "expect" : + { + "name" : "Windows", + "version" : "ME" + } + }, + { + "desc" : "Windows 2000", + "ua" : "Mozilla/3.0 (compatible; MSIE 3.0; Windows NT 5.0)", + "expect" : + { + "name" : "Windows", + "version" : "2000" + } + }, + { + "desc" : "Windows XP", + "ua" : "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 5.2)", + "expect" : + { + "name" : "Windows", + "version" : "XP" + } + }, + { + "desc" : "Windows Vista", + "ua" : "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; fr-FR)", + "expect" : + { + "name" : "Windows", + "version" : "Vista" + } + }, + { + "desc" : "Windows 7", + "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)", + "expect" : + { + "name" : "Windows", + "version" : "7" + } + }, + { + "desc" : "Windows 8", + "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Win64; x64; Trident/6.0; .NET4.0E; .NET4.0C)", + "expect" : + { + "name" : "Windows", + "version" : "8" + } + }, + { + "desc" : "Windows 10", + "ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0", + "expect" : + { + "name" : "Windows", + "version" : "10" + } + }, + { + "desc" : "WeChat Desktop for Windows Built-in Browser", + "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400", + "expect" : + { + "name" : "Windows", + "version" : "7" + } + }, + { + "desc" : "WeChat Desktop for Windows Built-in Browser major version in 4", + "ua" : "mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/81.0.4044.138 safari/537.36 nettype/wifi micromessenger/7.0.20.1781(0x6700143b) windowswechat", + "expect" : + { + "name" : "Windows", + "version" : "7" + } + }, + { + "desc" : "Windows RT", + "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0)", + "expect" : + { + "name" : "Windows", + "version" : "RT" + } + }, + { + "desc" : "Windows CE", + "ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)", + "expect" : + { + "name" : "Windows", + "version" : "CE" + } + }, + { + "desc" : "Windows NT on x86 or aarch64 CPU using Firefox", + "ua" : "Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "Windows", + "version" : "NT x" + } + }, + { + "desc" : "Windows NT on x64 CPU using Firefox", + "ua" : "Mozilla/5.0 (Windows NT x.y; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "Windows", + "version" : "NT x" + } + }, + { + "desc" : "iTunes Windows Vista", + "ua" : "iTunes/10.7 (Windows; Microsoft Windows Vista Home Premium Edition Service Pack 1 (Build 6001)) AppleWebKit/536.26.9", + "expect" : + { + "name" : "Windows", + "version" : "Vista" + } + } +] \ No newline at end of file diff --git a/test/specs/os/xbox.json b/test/specs/os/xbox.json new file mode 100644 index 0000000..f8f9f67 --- /dev/null +++ b/test/specs/os/xbox.json @@ -0,0 +1,47 @@ +[ + { + "desc" : "Xbox 360", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox 360) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", + "expect" : + { + "name" : "Xbox", + "version" : "360" + } + }, + { + "desc" : "Xbox One", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19041", + "expect" : + { + "name" : "Xbox", + "version" : "One" + } + }, + { + "desc" : "Xbox X", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02", + "expect" : + { + "name" : "Xbox", + "version" : "X" + } + }, + { + "desc" : "Xbox Series X", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox Series X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02 ", + "expect" : + { + "name" : "Xbox", + "version" : "Series X" + } + }, + { + "desc" : "Xbox Series S", + "ua" : "Mozilla/5.0 (Compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Xbox; Xbox Series S)", + "expect" : + { + "name" : "Xbox", + "version" : "Series S" + } + } +] \ No newline at end of file diff --git a/test/specs/os/zenwalk.json b/test/specs/os/zenwalk.json new file mode 100644 index 0000000..230b5dd --- /dev/null +++ b/test/specs/os/zenwalk.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Zenwalk", + "ua" : "Flock/2.16 (Zenwalk 7.3; es_PR;)", + "expect" : + { + "name" : "Zenwalk", + "version" : "7.3" + } + } +] \ No newline at end of file From aa56b2f4f39fa00e17c52cf207c9bad06f0a9ed8 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 28 Nov 2024 12:53:48 +0700 Subject: [PATCH 19/73] Update `engine.version` to be the same as `browser.version` for Chromium-based browser when UA-CH is available --- src/main/ua-parser.js | 7 ++++++- test/mocha-test.js | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 067a3e3..701375b 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -85,6 +85,7 @@ PREFIX_MOBILE = 'Mobile ', SUFFIX_BROWSER = ' Browser', CHROME = 'Chrome', + CHROMIUM = 'Chromium', CHROMECAST = 'Chromecast', EDGE = 'Edge', FIREFOX = 'Firefox', @@ -1161,17 +1162,21 @@ switch (this.itemType) { case UA_BROWSER: + case UA_ENGINE: var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; if (brands) { for (var i in brands) { var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]), brandVersion = brands[i].version; - if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) { + if (this.itemType == UA_BROWSER && !/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && brandName != CHROMIUM))) { this.set(NAME, brandName) .set(VERSION, brandVersion) .set(MAJOR, majorize(brandVersion)); prevName = brandName; } + if (this.itemType == UA_ENGINE && brandName == CHROMIUM) { + this.set(VERSION, brandVersion); + } } } break; diff --git a/test/mocha-test.js b/test/mocha-test.js index 8f6d529..9c50a82 100644 --- a/test/mocha-test.js +++ b/test/mocha-test.js @@ -9,7 +9,7 @@ var browsers = require('./specs/browser/browser-all.json'); var cpus = require('./specs/cpu/cpu-all.json'); var devices = readJsonFiles('test/specs/device'); var engines = require('./specs/engine/engine-all.json'); -var os = require('./specs/os/os-all.json'); +var os = readJsonFiles('test/specs/os'); var { Headers } = require('node-fetch'); function readJsonFiles(dir) { @@ -395,9 +395,9 @@ describe('Map UA-CH headers', function () { assert.strictEqual(device.model, "Pixel 99"); assert.strictEqual(device.vendor, undefined); assert.strictEqual(uap.engine.name, 'Blink'); - assert.strictEqual(uap.engine.version, '110.0.0.0'); + assert.strictEqual(uap.engine.version, '93.0.1.2'); assert.strictEqual(engine.name, 'Blink'); - assert.strictEqual(engine.version, '110.0.0.0'); + assert.strictEqual(engine.version, '93.0.1.2'); assert.strictEqual(uap.os.name, "Windows"); assert.strictEqual(uap.os.version, "11"); assert.strictEqual(os.name, "Windows"); From 1a057b4be24068e640264f4348f3d70d46d61704 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 28 Nov 2024 23:24:19 +0700 Subject: [PATCH 20/73] Reorganize test files & directories --- package.json | 8 ++++---- test/{specs => data/ua}/browser/browser-all.json | 0 test/{specs => data/ua}/cpu/cpu-all.json | 0 test/{specs => data/ua}/device/_others.json | 0 test/{specs => data/ua}/device/acer.json | 0 test/{specs => data/ua}/device/advan.json | 0 test/{specs => data/ua}/device/alcatel.json | 0 test/{specs => data/ua}/device/amazon.json | 0 test/{specs => data/ua}/device/apple.json | 0 test/{specs => data/ua}/device/asus.json | 0 test/{specs => data/ua}/device/blackberry.json | 0 test/{specs => data/ua}/device/cat.json | 0 test/{specs => data/ua}/device/energizer.json | 0 test/{specs => data/ua}/device/facebook.json | 0 test/{specs => data/ua}/device/fairphone.json | 0 test/{specs => data/ua}/device/google.json | 0 test/{specs => data/ua}/device/hmd.json | 0 test/{specs => data/ua}/device/honor.json | 0 test/{specs => data/ua}/device/htc.json | 0 test/{specs => data/ua}/device/huawei.json | 0 test/{specs => data/ua}/device/imo.json | 0 test/{specs => data/ua}/device/infinix.json | 0 test/{specs => data/ua}/device/itel.json | 0 test/{specs => data/ua}/device/jolla.json | 0 test/{specs => data/ua}/device/kobo.json | 0 test/{specs => data/ua}/device/lenovo.json | 0 test/{specs => data/ua}/device/lg.json | 0 test/{specs => data/ua}/device/meizu.json | 0 test/{specs => data/ua}/device/micromax.json | 0 test/{specs => data/ua}/device/microsoft.json | 0 test/{specs => data/ua}/device/motorola.json | 0 test/{specs => data/ua}/device/nintendo.json | 0 test/{specs => data/ua}/device/nokia.json | 0 test/{specs => data/ua}/device/nothing.json | 0 test/{specs => data/ua}/device/nvidia.json | 0 test/{specs => data/ua}/device/oneplus.json | 0 test/{specs => data/ua}/device/oppo.json | 0 test/{specs => data/ua}/device/ouya.json | 0 test/{specs => data/ua}/device/panasonic.json | 0 test/{specs => data/ua}/device/pico.json | 0 test/{specs => data/ua}/device/polytron.json | 0 test/{specs => data/ua}/device/realme.json | 0 test/{specs => data/ua}/device/roku.json | 0 test/{specs => data/ua}/device/samsung.json | 0 test/{specs => data/ua}/device/sharp.json | 0 test/{specs => data/ua}/device/smartfren.json | 0 test/{specs => data/ua}/device/sony.json | 0 test/{specs => data/ua}/device/tcl.json | 0 test/{specs => data/ua}/device/technisat.json | 0 test/{specs => data/ua}/device/tecno.json | 0 test/{specs => data/ua}/device/tesla.json | 0 test/{specs => data/ua}/device/ulefone.json | 0 test/{specs => data/ua}/device/vivo.json | 0 test/{specs => data/ua}/device/xiaomi.json | 0 test/{specs => data/ua}/device/zte.json | 0 test/{specs => data/ua}/engine/engine-all.json | 0 test/{specs => data/ua}/extension/cli.json | 0 test/{specs => data/ua}/extension/crawler.json | 0 test/{specs => data/ua}/extension/email.json | 0 .../ua}/extension/extra-devices.json | 0 test/{specs => data/ua}/extension/fetcher.json | 0 test/{specs => data/ua}/extension/library.json | 0 test/{specs => data/ua}/extension/mediaplayer.json | 0 test/{specs => data/ua}/os/aix.json | 0 test/{specs => data/ua}/os/amigaos.json | 0 test/{specs => data/ua}/os/android-x86.json | 0 test/{specs => data/ua}/os/android.json | 0 test/{specs => data/ua}/os/arch.json | 0 test/{specs => data/ua}/os/bada.json | 0 test/{specs => data/ua}/os/beos.json | 0 test/{specs => data/ua}/os/blackberry.json | 0 test/{specs => data/ua}/os/centos.json | 0 test/{specs => data/ua}/os/chrome-os.json | 0 test/{specs => data/ua}/os/chromecast-android.json | 0 test/{specs => data/ua}/os/chromecast-fuchsia.json | 0 test/{specs => data/ua}/os/chromecast-linux.json | 0 .../ua}/os/chromecast-smartspeaker.json | 0 test/{specs => data/ua}/os/contiki.json | 0 test/{specs => data/ua}/os/debian.json | 0 test/{specs => data/ua}/os/deepin.json | 0 test/{specs => data/ua}/os/dragonfly.json | 0 test/{specs => data/ua}/os/elementary-os.json | 0 test/{specs => data/ua}/os/fedora.json | 0 test/{specs => data/ua}/os/firefox-os.json | 0 test/{specs => data/ua}/os/freebsd.json | 0 test/{specs => data/ua}/os/fuchsia.json | 0 test/{specs => data/ua}/os/gentoo.json | 0 test/{specs => data/ua}/os/ghostbsd.json | 0 test/{specs => data/ua}/os/haiku.json | 0 test/{specs => data/ua}/os/harmonyos.json | 0 test/{specs => data/ua}/os/hp-ux.json | 0 test/{specs => data/ua}/os/hurd.json | 0 test/{specs => data/ua}/os/ios.json | 0 test/{specs => data/ua}/os/joli.json | 0 test/{specs => data/ua}/os/kaios.json | 0 test/{specs => data/ua}/os/kubuntu.json | 0 test/{specs => data/ua}/os/linpus.json | 0 test/{specs => data/ua}/os/linspire.json | 0 test/{specs => data/ua}/os/linux.json | 0 test/{specs => data/ua}/os/macos.json | 0 test/{specs => data/ua}/os/maemo.json | 0 test/{specs => data/ua}/os/mandriva.json | 0 test/{specs => data/ua}/os/manjaro.json | 0 test/{specs => data/ua}/os/meego.json | 0 test/{specs => data/ua}/os/minix.json | 0 test/{specs => data/ua}/os/mint.json | 0 test/{specs => data/ua}/os/morphos.json | 0 test/{specs => data/ua}/os/netbsd.json | 0 test/{specs => data/ua}/os/netrange.json | 0 test/{specs => data/ua}/os/nettv.json | 0 test/{specs => data/ua}/os/nintendo.json | 0 test/{specs => data/ua}/os/openbsd.json | 0 test/{specs => data/ua}/os/openharmony.json | 0 test/{specs => data/ua}/os/os2.json | 0 test/{specs => data/ua}/os/palm.json | 0 test/{specs => data/ua}/os/pclinuxos.json | 0 test/{specs => data/ua}/os/pico.json | 0 test/{specs => data/ua}/os/plan9.json | 0 test/{specs => data/ua}/os/playstation.json | 0 test/{specs => data/ua}/os/qnx.json | 0 test/{specs => data/ua}/os/raspbian.json | 0 test/{specs => data/ua}/os/redhat.json | 0 test/{specs => data/ua}/os/rim-tablet-os.json | 0 test/{specs => data/ua}/os/risc-os.json | 0 test/{specs => data/ua}/os/sabayon.json | 0 test/{specs => data/ua}/os/sailfish.json | 0 test/{specs => data/ua}/os/serenityos.json | 0 test/{specs => data/ua}/os/series40.json | 0 test/{specs => data/ua}/os/slackware.json | 0 test/{specs => data/ua}/os/solaris.json | 0 test/{specs => data/ua}/os/suse.json | 0 test/{specs => data/ua}/os/symbian.json | 0 test/{specs => data/ua}/os/tizen.json | 0 test/{specs => data/ua}/os/ubuntu.json | 0 test/{specs => data/ua}/os/unix.json | 0 test/{specs => data/ua}/os/watchos.json | 0 test/{specs => data/ua}/os/webos.json | 0 test/{specs => data/ua}/os/windows-mobile.json | 0 test/{specs => data/ua}/os/windows-phone.json | 0 test/{specs => data/ua}/os/windows.json | 0 test/{specs => data/ua}/os/xbox.json | 0 test/{specs => data/ua}/os/zenwalk.json | 0 .../browser.spec.mjs} | 11 ++++++++--- test/{jazzer-fuzz-test.js => fuzz/redos.js} | 4 ++-- test/{dts-test.ts => static/dts-lint.ts} | 4 ++-- test/{mocha-test-es6.mjs => unit/es6.mjs} | 4 ++-- .../extensions.js} | 14 +++++++------- test/{mocha-test-helpers.js => unit/helpers.js} | 6 +++--- test/{mocha-test.js => unit/main.js} | 12 ++++++------ 149 files changed, 34 insertions(+), 29 deletions(-) rename test/{specs => data/ua}/browser/browser-all.json (100%) rename test/{specs => data/ua}/cpu/cpu-all.json (100%) rename test/{specs => data/ua}/device/_others.json (100%) rename test/{specs => data/ua}/device/acer.json (100%) rename test/{specs => data/ua}/device/advan.json (100%) rename test/{specs => data/ua}/device/alcatel.json (100%) rename test/{specs => data/ua}/device/amazon.json (100%) rename test/{specs => data/ua}/device/apple.json (100%) rename test/{specs => data/ua}/device/asus.json (100%) rename test/{specs => data/ua}/device/blackberry.json (100%) rename test/{specs => data/ua}/device/cat.json (100%) rename test/{specs => data/ua}/device/energizer.json (100%) rename test/{specs => data/ua}/device/facebook.json (100%) rename test/{specs => data/ua}/device/fairphone.json (100%) rename test/{specs => data/ua}/device/google.json (100%) rename test/{specs => data/ua}/device/hmd.json (100%) rename test/{specs => data/ua}/device/honor.json (100%) rename test/{specs => data/ua}/device/htc.json (100%) rename test/{specs => data/ua}/device/huawei.json (100%) rename test/{specs => data/ua}/device/imo.json (100%) rename test/{specs => data/ua}/device/infinix.json (100%) rename test/{specs => data/ua}/device/itel.json (100%) rename test/{specs => data/ua}/device/jolla.json (100%) rename test/{specs => data/ua}/device/kobo.json (100%) rename test/{specs => data/ua}/device/lenovo.json (100%) rename test/{specs => data/ua}/device/lg.json (100%) rename test/{specs => data/ua}/device/meizu.json (100%) rename test/{specs => data/ua}/device/micromax.json (100%) rename test/{specs => data/ua}/device/microsoft.json (100%) rename test/{specs => data/ua}/device/motorola.json (100%) rename test/{specs => data/ua}/device/nintendo.json (100%) rename test/{specs => data/ua}/device/nokia.json (100%) rename test/{specs => data/ua}/device/nothing.json (100%) rename test/{specs => data/ua}/device/nvidia.json (100%) rename test/{specs => data/ua}/device/oneplus.json (100%) rename test/{specs => data/ua}/device/oppo.json (100%) rename test/{specs => data/ua}/device/ouya.json (100%) rename test/{specs => data/ua}/device/panasonic.json (100%) rename test/{specs => data/ua}/device/pico.json (100%) rename test/{specs => data/ua}/device/polytron.json (100%) rename test/{specs => data/ua}/device/realme.json (100%) rename test/{specs => data/ua}/device/roku.json (100%) rename test/{specs => data/ua}/device/samsung.json (100%) rename test/{specs => data/ua}/device/sharp.json (100%) rename test/{specs => data/ua}/device/smartfren.json (100%) rename test/{specs => data/ua}/device/sony.json (100%) rename test/{specs => data/ua}/device/tcl.json (100%) rename test/{specs => data/ua}/device/technisat.json (100%) rename test/{specs => data/ua}/device/tecno.json (100%) rename test/{specs => data/ua}/device/tesla.json (100%) rename test/{specs => data/ua}/device/ulefone.json (100%) rename test/{specs => data/ua}/device/vivo.json (100%) rename test/{specs => data/ua}/device/xiaomi.json (100%) rename test/{specs => data/ua}/device/zte.json (100%) rename test/{specs => data/ua}/engine/engine-all.json (100%) rename test/{specs => data/ua}/extension/cli.json (100%) rename test/{specs => data/ua}/extension/crawler.json (100%) rename test/{specs => data/ua}/extension/email.json (100%) rename test/{specs => data/ua}/extension/extra-devices.json (100%) rename test/{specs => data/ua}/extension/fetcher.json (100%) rename test/{specs => data/ua}/extension/library.json (100%) rename test/{specs => data/ua}/extension/mediaplayer.json (100%) rename test/{specs => data/ua}/os/aix.json (100%) rename test/{specs => data/ua}/os/amigaos.json (100%) rename test/{specs => data/ua}/os/android-x86.json (100%) rename test/{specs => data/ua}/os/android.json (100%) rename test/{specs => data/ua}/os/arch.json (100%) rename test/{specs => data/ua}/os/bada.json (100%) rename test/{specs => data/ua}/os/beos.json (100%) rename test/{specs => data/ua}/os/blackberry.json (100%) rename test/{specs => data/ua}/os/centos.json (100%) rename test/{specs => data/ua}/os/chrome-os.json (100%) rename test/{specs => data/ua}/os/chromecast-android.json (100%) rename test/{specs => data/ua}/os/chromecast-fuchsia.json (100%) rename test/{specs => data/ua}/os/chromecast-linux.json (100%) rename test/{specs => data/ua}/os/chromecast-smartspeaker.json (100%) rename test/{specs => data/ua}/os/contiki.json (100%) rename test/{specs => data/ua}/os/debian.json (100%) rename test/{specs => data/ua}/os/deepin.json (100%) rename test/{specs => data/ua}/os/dragonfly.json (100%) rename test/{specs => data/ua}/os/elementary-os.json (100%) rename test/{specs => data/ua}/os/fedora.json (100%) rename test/{specs => data/ua}/os/firefox-os.json (100%) rename test/{specs => data/ua}/os/freebsd.json (100%) rename test/{specs => data/ua}/os/fuchsia.json (100%) rename test/{specs => data/ua}/os/gentoo.json (100%) rename test/{specs => data/ua}/os/ghostbsd.json (100%) rename test/{specs => data/ua}/os/haiku.json (100%) rename test/{specs => data/ua}/os/harmonyos.json (100%) rename test/{specs => data/ua}/os/hp-ux.json (100%) rename test/{specs => data/ua}/os/hurd.json (100%) rename test/{specs => data/ua}/os/ios.json (100%) rename test/{specs => data/ua}/os/joli.json (100%) rename test/{specs => data/ua}/os/kaios.json (100%) rename test/{specs => data/ua}/os/kubuntu.json (100%) rename test/{specs => data/ua}/os/linpus.json (100%) rename test/{specs => data/ua}/os/linspire.json (100%) rename test/{specs => data/ua}/os/linux.json (100%) rename test/{specs => data/ua}/os/macos.json (100%) rename test/{specs => data/ua}/os/maemo.json (100%) rename test/{specs => data/ua}/os/mandriva.json (100%) rename test/{specs => data/ua}/os/manjaro.json (100%) rename test/{specs => data/ua}/os/meego.json (100%) rename test/{specs => data/ua}/os/minix.json (100%) rename test/{specs => data/ua}/os/mint.json (100%) rename test/{specs => data/ua}/os/morphos.json (100%) rename test/{specs => data/ua}/os/netbsd.json (100%) rename test/{specs => data/ua}/os/netrange.json (100%) rename test/{specs => data/ua}/os/nettv.json (100%) rename test/{specs => data/ua}/os/nintendo.json (100%) rename test/{specs => data/ua}/os/openbsd.json (100%) rename test/{specs => data/ua}/os/openharmony.json (100%) rename test/{specs => data/ua}/os/os2.json (100%) rename test/{specs => data/ua}/os/palm.json (100%) rename test/{specs => data/ua}/os/pclinuxos.json (100%) rename test/{specs => data/ua}/os/pico.json (100%) rename test/{specs => data/ua}/os/plan9.json (100%) rename test/{specs => data/ua}/os/playstation.json (100%) rename test/{specs => data/ua}/os/qnx.json (100%) rename test/{specs => data/ua}/os/raspbian.json (100%) rename test/{specs => data/ua}/os/redhat.json (100%) rename test/{specs => data/ua}/os/rim-tablet-os.json (100%) rename test/{specs => data/ua}/os/risc-os.json (100%) rename test/{specs => data/ua}/os/sabayon.json (100%) rename test/{specs => data/ua}/os/sailfish.json (100%) rename test/{specs => data/ua}/os/serenityos.json (100%) rename test/{specs => data/ua}/os/series40.json (100%) rename test/{specs => data/ua}/os/slackware.json (100%) rename test/{specs => data/ua}/os/solaris.json (100%) rename test/{specs => data/ua}/os/suse.json (100%) rename test/{specs => data/ua}/os/symbian.json (100%) rename test/{specs => data/ua}/os/tizen.json (100%) rename test/{specs => data/ua}/os/ubuntu.json (100%) rename test/{specs => data/ua}/os/unix.json (100%) rename test/{specs => data/ua}/os/watchos.json (100%) rename test/{specs => data/ua}/os/webos.json (100%) rename test/{specs => data/ua}/os/windows-mobile.json (100%) rename test/{specs => data/ua}/os/windows-phone.json (100%) rename test/{specs => data/ua}/os/windows.json (100%) rename test/{specs => data/ua}/os/xbox.json (100%) rename test/{specs => data/ua}/os/zenwalk.json (100%) rename test/{playwright-test-main.spec.mjs => e2e/browser.spec.mjs} (97%) rename test/{jazzer-fuzz-test.js => fuzz/redos.js} (87%) rename test/{dts-test.ts => static/dts-lint.ts} (91%) rename test/{mocha-test-es6.mjs => unit/es6.mjs} (88%) rename test/{mocha-test-extension.js => unit/extensions.js} (91%) rename test/{mocha-test-helpers.js => unit/helpers.js} (94%) rename test/{mocha-test.js => unit/main.js} (98%) diff --git a/package.json b/package.json index aa887d2..b9d9581 100755 --- a/package.json +++ b/package.json @@ -202,14 +202,14 @@ "scripts": { "build": "./script/build-dist.sh && ./script/build-esm.js", "build+test": "npm run build && npm run test", - "fuzz": "jazzer ./test/jazzer-fuzz-test.js --sync", + "fuzz": "jazzer ./test/fuzz/redos.js --sync", "test": "./script/test-all.sh", - "test:dts-lint": "tsd --typings src/main/ua-parser.d.ts --files test/dts-test.ts", + "test:dts-lint": "tsd --typings src/main/ua-parser.d.ts --files test/static/dts-lint.ts", "test:eslint": "eslint src && eslint script", "test:jshint": "jshint src/main", "test:lockfile-lint": "npx lockfile-lint -p package-lock.json", - "test:mocha": "mocha test/mocha*js", - "test:playwright": "playwright test" + "test:mocha": "mocha test/unit", + "test:playwright": "playwright test test/e2e --browser all" }, "dependencies": { "detect-europe-js": "^0.1.2", diff --git a/test/specs/browser/browser-all.json b/test/data/ua/browser/browser-all.json similarity index 100% rename from test/specs/browser/browser-all.json rename to test/data/ua/browser/browser-all.json diff --git a/test/specs/cpu/cpu-all.json b/test/data/ua/cpu/cpu-all.json similarity index 100% rename from test/specs/cpu/cpu-all.json rename to test/data/ua/cpu/cpu-all.json diff --git a/test/specs/device/_others.json b/test/data/ua/device/_others.json similarity index 100% rename from test/specs/device/_others.json rename to test/data/ua/device/_others.json diff --git a/test/specs/device/acer.json b/test/data/ua/device/acer.json similarity index 100% rename from test/specs/device/acer.json rename to test/data/ua/device/acer.json diff --git a/test/specs/device/advan.json b/test/data/ua/device/advan.json similarity index 100% rename from test/specs/device/advan.json rename to test/data/ua/device/advan.json diff --git a/test/specs/device/alcatel.json b/test/data/ua/device/alcatel.json similarity index 100% rename from test/specs/device/alcatel.json rename to test/data/ua/device/alcatel.json diff --git a/test/specs/device/amazon.json b/test/data/ua/device/amazon.json similarity index 100% rename from test/specs/device/amazon.json rename to test/data/ua/device/amazon.json diff --git a/test/specs/device/apple.json b/test/data/ua/device/apple.json similarity index 100% rename from test/specs/device/apple.json rename to test/data/ua/device/apple.json diff --git a/test/specs/device/asus.json b/test/data/ua/device/asus.json similarity index 100% rename from test/specs/device/asus.json rename to test/data/ua/device/asus.json diff --git a/test/specs/device/blackberry.json b/test/data/ua/device/blackberry.json similarity index 100% rename from test/specs/device/blackberry.json rename to test/data/ua/device/blackberry.json diff --git a/test/specs/device/cat.json b/test/data/ua/device/cat.json similarity index 100% rename from test/specs/device/cat.json rename to test/data/ua/device/cat.json diff --git a/test/specs/device/energizer.json b/test/data/ua/device/energizer.json similarity index 100% rename from test/specs/device/energizer.json rename to test/data/ua/device/energizer.json diff --git a/test/specs/device/facebook.json b/test/data/ua/device/facebook.json similarity index 100% rename from test/specs/device/facebook.json rename to test/data/ua/device/facebook.json diff --git a/test/specs/device/fairphone.json b/test/data/ua/device/fairphone.json similarity index 100% rename from test/specs/device/fairphone.json rename to test/data/ua/device/fairphone.json diff --git a/test/specs/device/google.json b/test/data/ua/device/google.json similarity index 100% rename from test/specs/device/google.json rename to test/data/ua/device/google.json diff --git a/test/specs/device/hmd.json b/test/data/ua/device/hmd.json similarity index 100% rename from test/specs/device/hmd.json rename to test/data/ua/device/hmd.json diff --git a/test/specs/device/honor.json b/test/data/ua/device/honor.json similarity index 100% rename from test/specs/device/honor.json rename to test/data/ua/device/honor.json diff --git a/test/specs/device/htc.json b/test/data/ua/device/htc.json similarity index 100% rename from test/specs/device/htc.json rename to test/data/ua/device/htc.json diff --git a/test/specs/device/huawei.json b/test/data/ua/device/huawei.json similarity index 100% rename from test/specs/device/huawei.json rename to test/data/ua/device/huawei.json diff --git a/test/specs/device/imo.json b/test/data/ua/device/imo.json similarity index 100% rename from test/specs/device/imo.json rename to test/data/ua/device/imo.json diff --git a/test/specs/device/infinix.json b/test/data/ua/device/infinix.json similarity index 100% rename from test/specs/device/infinix.json rename to test/data/ua/device/infinix.json diff --git a/test/specs/device/itel.json b/test/data/ua/device/itel.json similarity index 100% rename from test/specs/device/itel.json rename to test/data/ua/device/itel.json diff --git a/test/specs/device/jolla.json b/test/data/ua/device/jolla.json similarity index 100% rename from test/specs/device/jolla.json rename to test/data/ua/device/jolla.json diff --git a/test/specs/device/kobo.json b/test/data/ua/device/kobo.json similarity index 100% rename from test/specs/device/kobo.json rename to test/data/ua/device/kobo.json diff --git a/test/specs/device/lenovo.json b/test/data/ua/device/lenovo.json similarity index 100% rename from test/specs/device/lenovo.json rename to test/data/ua/device/lenovo.json diff --git a/test/specs/device/lg.json b/test/data/ua/device/lg.json similarity index 100% rename from test/specs/device/lg.json rename to test/data/ua/device/lg.json diff --git a/test/specs/device/meizu.json b/test/data/ua/device/meizu.json similarity index 100% rename from test/specs/device/meizu.json rename to test/data/ua/device/meizu.json diff --git a/test/specs/device/micromax.json b/test/data/ua/device/micromax.json similarity index 100% rename from test/specs/device/micromax.json rename to test/data/ua/device/micromax.json diff --git a/test/specs/device/microsoft.json b/test/data/ua/device/microsoft.json similarity index 100% rename from test/specs/device/microsoft.json rename to test/data/ua/device/microsoft.json diff --git a/test/specs/device/motorola.json b/test/data/ua/device/motorola.json similarity index 100% rename from test/specs/device/motorola.json rename to test/data/ua/device/motorola.json diff --git a/test/specs/device/nintendo.json b/test/data/ua/device/nintendo.json similarity index 100% rename from test/specs/device/nintendo.json rename to test/data/ua/device/nintendo.json diff --git a/test/specs/device/nokia.json b/test/data/ua/device/nokia.json similarity index 100% rename from test/specs/device/nokia.json rename to test/data/ua/device/nokia.json diff --git a/test/specs/device/nothing.json b/test/data/ua/device/nothing.json similarity index 100% rename from test/specs/device/nothing.json rename to test/data/ua/device/nothing.json diff --git a/test/specs/device/nvidia.json b/test/data/ua/device/nvidia.json similarity index 100% rename from test/specs/device/nvidia.json rename to test/data/ua/device/nvidia.json diff --git a/test/specs/device/oneplus.json b/test/data/ua/device/oneplus.json similarity index 100% rename from test/specs/device/oneplus.json rename to test/data/ua/device/oneplus.json diff --git a/test/specs/device/oppo.json b/test/data/ua/device/oppo.json similarity index 100% rename from test/specs/device/oppo.json rename to test/data/ua/device/oppo.json diff --git a/test/specs/device/ouya.json b/test/data/ua/device/ouya.json similarity index 100% rename from test/specs/device/ouya.json rename to test/data/ua/device/ouya.json diff --git a/test/specs/device/panasonic.json b/test/data/ua/device/panasonic.json similarity index 100% rename from test/specs/device/panasonic.json rename to test/data/ua/device/panasonic.json diff --git a/test/specs/device/pico.json b/test/data/ua/device/pico.json similarity index 100% rename from test/specs/device/pico.json rename to test/data/ua/device/pico.json diff --git a/test/specs/device/polytron.json b/test/data/ua/device/polytron.json similarity index 100% rename from test/specs/device/polytron.json rename to test/data/ua/device/polytron.json diff --git a/test/specs/device/realme.json b/test/data/ua/device/realme.json similarity index 100% rename from test/specs/device/realme.json rename to test/data/ua/device/realme.json diff --git a/test/specs/device/roku.json b/test/data/ua/device/roku.json similarity index 100% rename from test/specs/device/roku.json rename to test/data/ua/device/roku.json diff --git a/test/specs/device/samsung.json b/test/data/ua/device/samsung.json similarity index 100% rename from test/specs/device/samsung.json rename to test/data/ua/device/samsung.json diff --git a/test/specs/device/sharp.json b/test/data/ua/device/sharp.json similarity index 100% rename from test/specs/device/sharp.json rename to test/data/ua/device/sharp.json diff --git a/test/specs/device/smartfren.json b/test/data/ua/device/smartfren.json similarity index 100% rename from test/specs/device/smartfren.json rename to test/data/ua/device/smartfren.json diff --git a/test/specs/device/sony.json b/test/data/ua/device/sony.json similarity index 100% rename from test/specs/device/sony.json rename to test/data/ua/device/sony.json diff --git a/test/specs/device/tcl.json b/test/data/ua/device/tcl.json similarity index 100% rename from test/specs/device/tcl.json rename to test/data/ua/device/tcl.json diff --git a/test/specs/device/technisat.json b/test/data/ua/device/technisat.json similarity index 100% rename from test/specs/device/technisat.json rename to test/data/ua/device/technisat.json diff --git a/test/specs/device/tecno.json b/test/data/ua/device/tecno.json similarity index 100% rename from test/specs/device/tecno.json rename to test/data/ua/device/tecno.json diff --git a/test/specs/device/tesla.json b/test/data/ua/device/tesla.json similarity index 100% rename from test/specs/device/tesla.json rename to test/data/ua/device/tesla.json diff --git a/test/specs/device/ulefone.json b/test/data/ua/device/ulefone.json similarity index 100% rename from test/specs/device/ulefone.json rename to test/data/ua/device/ulefone.json diff --git a/test/specs/device/vivo.json b/test/data/ua/device/vivo.json similarity index 100% rename from test/specs/device/vivo.json rename to test/data/ua/device/vivo.json diff --git a/test/specs/device/xiaomi.json b/test/data/ua/device/xiaomi.json similarity index 100% rename from test/specs/device/xiaomi.json rename to test/data/ua/device/xiaomi.json diff --git a/test/specs/device/zte.json b/test/data/ua/device/zte.json similarity index 100% rename from test/specs/device/zte.json rename to test/data/ua/device/zte.json diff --git a/test/specs/engine/engine-all.json b/test/data/ua/engine/engine-all.json similarity index 100% rename from test/specs/engine/engine-all.json rename to test/data/ua/engine/engine-all.json diff --git a/test/specs/extension/cli.json b/test/data/ua/extension/cli.json similarity index 100% rename from test/specs/extension/cli.json rename to test/data/ua/extension/cli.json diff --git a/test/specs/extension/crawler.json b/test/data/ua/extension/crawler.json similarity index 100% rename from test/specs/extension/crawler.json rename to test/data/ua/extension/crawler.json diff --git a/test/specs/extension/email.json b/test/data/ua/extension/email.json similarity index 100% rename from test/specs/extension/email.json rename to test/data/ua/extension/email.json diff --git a/test/specs/extension/extra-devices.json b/test/data/ua/extension/extra-devices.json similarity index 100% rename from test/specs/extension/extra-devices.json rename to test/data/ua/extension/extra-devices.json diff --git a/test/specs/extension/fetcher.json b/test/data/ua/extension/fetcher.json similarity index 100% rename from test/specs/extension/fetcher.json rename to test/data/ua/extension/fetcher.json diff --git a/test/specs/extension/library.json b/test/data/ua/extension/library.json similarity index 100% rename from test/specs/extension/library.json rename to test/data/ua/extension/library.json diff --git a/test/specs/extension/mediaplayer.json b/test/data/ua/extension/mediaplayer.json similarity index 100% rename from test/specs/extension/mediaplayer.json rename to test/data/ua/extension/mediaplayer.json diff --git a/test/specs/os/aix.json b/test/data/ua/os/aix.json similarity index 100% rename from test/specs/os/aix.json rename to test/data/ua/os/aix.json diff --git a/test/specs/os/amigaos.json b/test/data/ua/os/amigaos.json similarity index 100% rename from test/specs/os/amigaos.json rename to test/data/ua/os/amigaos.json diff --git a/test/specs/os/android-x86.json b/test/data/ua/os/android-x86.json similarity index 100% rename from test/specs/os/android-x86.json rename to test/data/ua/os/android-x86.json diff --git a/test/specs/os/android.json b/test/data/ua/os/android.json similarity index 100% rename from test/specs/os/android.json rename to test/data/ua/os/android.json diff --git a/test/specs/os/arch.json b/test/data/ua/os/arch.json similarity index 100% rename from test/specs/os/arch.json rename to test/data/ua/os/arch.json diff --git a/test/specs/os/bada.json b/test/data/ua/os/bada.json similarity index 100% rename from test/specs/os/bada.json rename to test/data/ua/os/bada.json diff --git a/test/specs/os/beos.json b/test/data/ua/os/beos.json similarity index 100% rename from test/specs/os/beos.json rename to test/data/ua/os/beos.json diff --git a/test/specs/os/blackberry.json b/test/data/ua/os/blackberry.json similarity index 100% rename from test/specs/os/blackberry.json rename to test/data/ua/os/blackberry.json diff --git a/test/specs/os/centos.json b/test/data/ua/os/centos.json similarity index 100% rename from test/specs/os/centos.json rename to test/data/ua/os/centos.json diff --git a/test/specs/os/chrome-os.json b/test/data/ua/os/chrome-os.json similarity index 100% rename from test/specs/os/chrome-os.json rename to test/data/ua/os/chrome-os.json diff --git a/test/specs/os/chromecast-android.json b/test/data/ua/os/chromecast-android.json similarity index 100% rename from test/specs/os/chromecast-android.json rename to test/data/ua/os/chromecast-android.json diff --git a/test/specs/os/chromecast-fuchsia.json b/test/data/ua/os/chromecast-fuchsia.json similarity index 100% rename from test/specs/os/chromecast-fuchsia.json rename to test/data/ua/os/chromecast-fuchsia.json diff --git a/test/specs/os/chromecast-linux.json b/test/data/ua/os/chromecast-linux.json similarity index 100% rename from test/specs/os/chromecast-linux.json rename to test/data/ua/os/chromecast-linux.json diff --git a/test/specs/os/chromecast-smartspeaker.json b/test/data/ua/os/chromecast-smartspeaker.json similarity index 100% rename from test/specs/os/chromecast-smartspeaker.json rename to test/data/ua/os/chromecast-smartspeaker.json diff --git a/test/specs/os/contiki.json b/test/data/ua/os/contiki.json similarity index 100% rename from test/specs/os/contiki.json rename to test/data/ua/os/contiki.json diff --git a/test/specs/os/debian.json b/test/data/ua/os/debian.json similarity index 100% rename from test/specs/os/debian.json rename to test/data/ua/os/debian.json diff --git a/test/specs/os/deepin.json b/test/data/ua/os/deepin.json similarity index 100% rename from test/specs/os/deepin.json rename to test/data/ua/os/deepin.json diff --git a/test/specs/os/dragonfly.json b/test/data/ua/os/dragonfly.json similarity index 100% rename from test/specs/os/dragonfly.json rename to test/data/ua/os/dragonfly.json diff --git a/test/specs/os/elementary-os.json b/test/data/ua/os/elementary-os.json similarity index 100% rename from test/specs/os/elementary-os.json rename to test/data/ua/os/elementary-os.json diff --git a/test/specs/os/fedora.json b/test/data/ua/os/fedora.json similarity index 100% rename from test/specs/os/fedora.json rename to test/data/ua/os/fedora.json diff --git a/test/specs/os/firefox-os.json b/test/data/ua/os/firefox-os.json similarity index 100% rename from test/specs/os/firefox-os.json rename to test/data/ua/os/firefox-os.json diff --git a/test/specs/os/freebsd.json b/test/data/ua/os/freebsd.json similarity index 100% rename from test/specs/os/freebsd.json rename to test/data/ua/os/freebsd.json diff --git a/test/specs/os/fuchsia.json b/test/data/ua/os/fuchsia.json similarity index 100% rename from test/specs/os/fuchsia.json rename to test/data/ua/os/fuchsia.json diff --git a/test/specs/os/gentoo.json b/test/data/ua/os/gentoo.json similarity index 100% rename from test/specs/os/gentoo.json rename to test/data/ua/os/gentoo.json diff --git a/test/specs/os/ghostbsd.json b/test/data/ua/os/ghostbsd.json similarity index 100% rename from test/specs/os/ghostbsd.json rename to test/data/ua/os/ghostbsd.json diff --git a/test/specs/os/haiku.json b/test/data/ua/os/haiku.json similarity index 100% rename from test/specs/os/haiku.json rename to test/data/ua/os/haiku.json diff --git a/test/specs/os/harmonyos.json b/test/data/ua/os/harmonyos.json similarity index 100% rename from test/specs/os/harmonyos.json rename to test/data/ua/os/harmonyos.json diff --git a/test/specs/os/hp-ux.json b/test/data/ua/os/hp-ux.json similarity index 100% rename from test/specs/os/hp-ux.json rename to test/data/ua/os/hp-ux.json diff --git a/test/specs/os/hurd.json b/test/data/ua/os/hurd.json similarity index 100% rename from test/specs/os/hurd.json rename to test/data/ua/os/hurd.json diff --git a/test/specs/os/ios.json b/test/data/ua/os/ios.json similarity index 100% rename from test/specs/os/ios.json rename to test/data/ua/os/ios.json diff --git a/test/specs/os/joli.json b/test/data/ua/os/joli.json similarity index 100% rename from test/specs/os/joli.json rename to test/data/ua/os/joli.json diff --git a/test/specs/os/kaios.json b/test/data/ua/os/kaios.json similarity index 100% rename from test/specs/os/kaios.json rename to test/data/ua/os/kaios.json diff --git a/test/specs/os/kubuntu.json b/test/data/ua/os/kubuntu.json similarity index 100% rename from test/specs/os/kubuntu.json rename to test/data/ua/os/kubuntu.json diff --git a/test/specs/os/linpus.json b/test/data/ua/os/linpus.json similarity index 100% rename from test/specs/os/linpus.json rename to test/data/ua/os/linpus.json diff --git a/test/specs/os/linspire.json b/test/data/ua/os/linspire.json similarity index 100% rename from test/specs/os/linspire.json rename to test/data/ua/os/linspire.json diff --git a/test/specs/os/linux.json b/test/data/ua/os/linux.json similarity index 100% rename from test/specs/os/linux.json rename to test/data/ua/os/linux.json diff --git a/test/specs/os/macos.json b/test/data/ua/os/macos.json similarity index 100% rename from test/specs/os/macos.json rename to test/data/ua/os/macos.json diff --git a/test/specs/os/maemo.json b/test/data/ua/os/maemo.json similarity index 100% rename from test/specs/os/maemo.json rename to test/data/ua/os/maemo.json diff --git a/test/specs/os/mandriva.json b/test/data/ua/os/mandriva.json similarity index 100% rename from test/specs/os/mandriva.json rename to test/data/ua/os/mandriva.json diff --git a/test/specs/os/manjaro.json b/test/data/ua/os/manjaro.json similarity index 100% rename from test/specs/os/manjaro.json rename to test/data/ua/os/manjaro.json diff --git a/test/specs/os/meego.json b/test/data/ua/os/meego.json similarity index 100% rename from test/specs/os/meego.json rename to test/data/ua/os/meego.json diff --git a/test/specs/os/minix.json b/test/data/ua/os/minix.json similarity index 100% rename from test/specs/os/minix.json rename to test/data/ua/os/minix.json diff --git a/test/specs/os/mint.json b/test/data/ua/os/mint.json similarity index 100% rename from test/specs/os/mint.json rename to test/data/ua/os/mint.json diff --git a/test/specs/os/morphos.json b/test/data/ua/os/morphos.json similarity index 100% rename from test/specs/os/morphos.json rename to test/data/ua/os/morphos.json diff --git a/test/specs/os/netbsd.json b/test/data/ua/os/netbsd.json similarity index 100% rename from test/specs/os/netbsd.json rename to test/data/ua/os/netbsd.json diff --git a/test/specs/os/netrange.json b/test/data/ua/os/netrange.json similarity index 100% rename from test/specs/os/netrange.json rename to test/data/ua/os/netrange.json diff --git a/test/specs/os/nettv.json b/test/data/ua/os/nettv.json similarity index 100% rename from test/specs/os/nettv.json rename to test/data/ua/os/nettv.json diff --git a/test/specs/os/nintendo.json b/test/data/ua/os/nintendo.json similarity index 100% rename from test/specs/os/nintendo.json rename to test/data/ua/os/nintendo.json diff --git a/test/specs/os/openbsd.json b/test/data/ua/os/openbsd.json similarity index 100% rename from test/specs/os/openbsd.json rename to test/data/ua/os/openbsd.json diff --git a/test/specs/os/openharmony.json b/test/data/ua/os/openharmony.json similarity index 100% rename from test/specs/os/openharmony.json rename to test/data/ua/os/openharmony.json diff --git a/test/specs/os/os2.json b/test/data/ua/os/os2.json similarity index 100% rename from test/specs/os/os2.json rename to test/data/ua/os/os2.json diff --git a/test/specs/os/palm.json b/test/data/ua/os/palm.json similarity index 100% rename from test/specs/os/palm.json rename to test/data/ua/os/palm.json diff --git a/test/specs/os/pclinuxos.json b/test/data/ua/os/pclinuxos.json similarity index 100% rename from test/specs/os/pclinuxos.json rename to test/data/ua/os/pclinuxos.json diff --git a/test/specs/os/pico.json b/test/data/ua/os/pico.json similarity index 100% rename from test/specs/os/pico.json rename to test/data/ua/os/pico.json diff --git a/test/specs/os/plan9.json b/test/data/ua/os/plan9.json similarity index 100% rename from test/specs/os/plan9.json rename to test/data/ua/os/plan9.json diff --git a/test/specs/os/playstation.json b/test/data/ua/os/playstation.json similarity index 100% rename from test/specs/os/playstation.json rename to test/data/ua/os/playstation.json diff --git a/test/specs/os/qnx.json b/test/data/ua/os/qnx.json similarity index 100% rename from test/specs/os/qnx.json rename to test/data/ua/os/qnx.json diff --git a/test/specs/os/raspbian.json b/test/data/ua/os/raspbian.json similarity index 100% rename from test/specs/os/raspbian.json rename to test/data/ua/os/raspbian.json diff --git a/test/specs/os/redhat.json b/test/data/ua/os/redhat.json similarity index 100% rename from test/specs/os/redhat.json rename to test/data/ua/os/redhat.json diff --git a/test/specs/os/rim-tablet-os.json b/test/data/ua/os/rim-tablet-os.json similarity index 100% rename from test/specs/os/rim-tablet-os.json rename to test/data/ua/os/rim-tablet-os.json diff --git a/test/specs/os/risc-os.json b/test/data/ua/os/risc-os.json similarity index 100% rename from test/specs/os/risc-os.json rename to test/data/ua/os/risc-os.json diff --git a/test/specs/os/sabayon.json b/test/data/ua/os/sabayon.json similarity index 100% rename from test/specs/os/sabayon.json rename to test/data/ua/os/sabayon.json diff --git a/test/specs/os/sailfish.json b/test/data/ua/os/sailfish.json similarity index 100% rename from test/specs/os/sailfish.json rename to test/data/ua/os/sailfish.json diff --git a/test/specs/os/serenityos.json b/test/data/ua/os/serenityos.json similarity index 100% rename from test/specs/os/serenityos.json rename to test/data/ua/os/serenityos.json diff --git a/test/specs/os/series40.json b/test/data/ua/os/series40.json similarity index 100% rename from test/specs/os/series40.json rename to test/data/ua/os/series40.json diff --git a/test/specs/os/slackware.json b/test/data/ua/os/slackware.json similarity index 100% rename from test/specs/os/slackware.json rename to test/data/ua/os/slackware.json diff --git a/test/specs/os/solaris.json b/test/data/ua/os/solaris.json similarity index 100% rename from test/specs/os/solaris.json rename to test/data/ua/os/solaris.json diff --git a/test/specs/os/suse.json b/test/data/ua/os/suse.json similarity index 100% rename from test/specs/os/suse.json rename to test/data/ua/os/suse.json diff --git a/test/specs/os/symbian.json b/test/data/ua/os/symbian.json similarity index 100% rename from test/specs/os/symbian.json rename to test/data/ua/os/symbian.json diff --git a/test/specs/os/tizen.json b/test/data/ua/os/tizen.json similarity index 100% rename from test/specs/os/tizen.json rename to test/data/ua/os/tizen.json diff --git a/test/specs/os/ubuntu.json b/test/data/ua/os/ubuntu.json similarity index 100% rename from test/specs/os/ubuntu.json rename to test/data/ua/os/ubuntu.json diff --git a/test/specs/os/unix.json b/test/data/ua/os/unix.json similarity index 100% rename from test/specs/os/unix.json rename to test/data/ua/os/unix.json diff --git a/test/specs/os/watchos.json b/test/data/ua/os/watchos.json similarity index 100% rename from test/specs/os/watchos.json rename to test/data/ua/os/watchos.json diff --git a/test/specs/os/webos.json b/test/data/ua/os/webos.json similarity index 100% rename from test/specs/os/webos.json rename to test/data/ua/os/webos.json diff --git a/test/specs/os/windows-mobile.json b/test/data/ua/os/windows-mobile.json similarity index 100% rename from test/specs/os/windows-mobile.json rename to test/data/ua/os/windows-mobile.json diff --git a/test/specs/os/windows-phone.json b/test/data/ua/os/windows-phone.json similarity index 100% rename from test/specs/os/windows-phone.json rename to test/data/ua/os/windows-phone.json diff --git a/test/specs/os/windows.json b/test/data/ua/os/windows.json similarity index 100% rename from test/specs/os/windows.json rename to test/data/ua/os/windows.json diff --git a/test/specs/os/xbox.json b/test/data/ua/os/xbox.json similarity index 100% rename from test/specs/os/xbox.json rename to test/data/ua/os/xbox.json diff --git a/test/specs/os/zenwalk.json b/test/data/ua/os/zenwalk.json similarity index 100% rename from test/specs/os/zenwalk.json rename to test/data/ua/os/zenwalk.json diff --git a/test/playwright-test-main.spec.mjs b/test/e2e/browser.spec.mjs similarity index 97% rename from test/playwright-test-main.spec.mjs rename to test/e2e/browser.spec.mjs index db6e149..97431b6 100644 --- a/test/playwright-test-main.spec.mjs +++ b/test/e2e/browser.spec.mjs @@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test'; import path from 'path'; import url from 'url'; -const localHtml = `file://${path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '../')}/dist/ua-parser.html`; +const localHtml = `file://${path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '../../')}/dist/ua-parser.html`; test.describe('Custom navigator.userAgent tests', () => { @@ -83,7 +83,7 @@ test.describe('withClientHints() tests', () => { test.describe('withFeatureCheck() tests', () => { - test('Detect Brave', async ({ page }) => { + test('Detect Brave', async ({ page, browserName }) => { await page.addInitScript(() => { Object.defineProperty(navigator, 'brave', { value: { @@ -94,7 +94,12 @@ test.describe('withFeatureCheck() tests', () => { await page.goto(localHtml); // @ts-ignore let uap = await page.evaluate(() => UAParser()); - expect(uap).toHaveProperty('browser.name', 'Chrome Headless'); + const browserMap = { + chromium: 'Chrome Headless', + firefox: 'Firefox', + webkit: 'Safari' + } + expect(uap).toHaveProperty('browser.name', browserMap[browserName]); // @ts-ignore uap = await page.evaluate(() => UAParser().withFeatureCheck()); expect(uap).toHaveProperty('browser.name', 'Brave'); diff --git a/test/jazzer-fuzz-test.js b/test/fuzz/redos.js similarity index 87% rename from test/jazzer-fuzz-test.js rename to test/fuzz/redos.js index 8d87049..b046862 100644 --- a/test/jazzer-fuzz-test.js +++ b/test/fuzz/redos.js @@ -1,6 +1,6 @@ const { FuzzedDataProvider } = require('@jazzer.js/core'); -const { UAParser } = require('../src/main/ua-parser'); -const UA_MAX_LENGTH = 350; +const { UAParser } = require('../../dist/main'); +const UA_MAX_LENGTH = 500; module.exports.fuzz = function (buffer) { const data = new FuzzedDataProvider(buffer); diff --git a/test/dts-test.ts b/test/static/dts-lint.ts similarity index 91% rename from test/dts-test.ts rename to test/static/dts-lint.ts index 39bb4a3..bcfc262 100644 --- a/test/dts-test.ts +++ b/test/static/dts-lint.ts @@ -1,6 +1,6 @@ import { expectType } from 'tsd'; -import { UAParser, IResult, IBrowser, ICPU, IEngine, IDevice, IOS } from "../src/main/ua-parser"; -import { isAppleSilicon, isChromeFamily } from "../src/helpers/ua-parser-helpers"; +import { UAParser, IResult, IBrowser, ICPU, IEngine, IDevice, IOS } from "../../src/main/ua-parser"; +import { isAppleSilicon, isChromeFamily } from "../../src/helpers/ua-parser-helpers"; const uastring = 'Mozilla/5.0 (X11; MyCustomOS; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0'; const extensions = { diff --git a/test/mocha-test-es6.mjs b/test/unit/es6.mjs similarity index 88% rename from test/mocha-test-es6.mjs rename to test/unit/es6.mjs index 69a334e..8e26908 100644 --- a/test/mocha-test-es6.mjs +++ b/test/unit/es6.mjs @@ -1,5 +1,5 @@ -import { UAParser } from '../src/main/ua-parser.mjs'; -import { CPU, Device, Engine } from '../src/enums/ua-parser-enums.mjs'; +import { UAParser } from '../../src/main/ua-parser.mjs'; +import { CPU, Device, Engine } from '../../src/enums/ua-parser-enums.mjs'; import * as assert from 'assert'; describe('Returns', () => { diff --git a/test/mocha-test-extension.js b/test/unit/extensions.js similarity index 91% rename from test/mocha-test-extension.js rename to test/unit/extensions.js index c32c1b8..6fd755b 100644 --- a/test/mocha-test-extension.js +++ b/test/unit/extensions.js @@ -3,13 +3,13 @@ const assert = require('assert'); const parseJS = require('@babel/parser').parse; const traverse = require('@babel/traverse').default; const safe = require('safe-regex'); -const { UAParser } = require('../src/main/ua-parser'); -const clis = require('./specs/extension/cli.json'); -const crawlers = require('./specs/extension/crawler.json'); -const emails = require('./specs/extension/email.json'); -const fetchers = require('./specs/extension/fetcher.json'); -const libraries = require('./specs/extension/library.json'); -const { Bots, CLIs, Crawlers, Emails, Fetchers, Libraries } = require('../src/extensions/ua-parser-extensions'); +const { UAParser } = require('../../src/main/ua-parser'); +const clis = require('../data/ua/extension/cli.json'); +const crawlers = require('../data/ua/extension/crawler.json'); +const emails = require('../data/ua/extension/email.json'); +const fetchers = require('../data/ua/extension/fetcher.json'); +const libraries = require('../data/ua/extension/library.json'); +const { Bots, CLIs, Crawlers, Emails, Fetchers, Libraries } = require('../../src/extensions/ua-parser-extensions'); describe('Extensions', () => { [ diff --git a/test/mocha-test-helpers.js b/test/unit/helpers.js similarity index 94% rename from test/mocha-test-helpers.js rename to test/unit/helpers.js index d6170bc..fcd6678 100644 --- a/test/mocha-test-helpers.js +++ b/test/unit/helpers.js @@ -1,7 +1,7 @@ const assert = require('assert'); -const { UAParser } = require('../src/main/ua-parser'); -const { getDeviceVendor, isAppleSilicon, isAIBot, isBot, isChromeFamily } = require('../src/helpers/ua-parser-helpers'); -const { Bots, Emails } = require('../src/extensions/ua-parser-extensions'); +const { UAParser } = require('../../src/main/ua-parser'); +const { getDeviceVendor, isAppleSilicon, isAIBot, isBot, isChromeFamily } = require('../../src/helpers/ua-parser-helpers'); +const { Bots, Emails } = require('../../src/extensions/ua-parser-extensions'); describe('getDeviceVendor', () => { it('Can guess the device vendor from a model name', () => { diff --git a/test/mocha-test.js b/test/unit/main.js similarity index 98% rename from test/mocha-test.js rename to test/unit/main.js index 9c50a82..0433882 100644 --- a/test/mocha-test.js +++ b/test/unit/main.js @@ -4,12 +4,12 @@ var assert = require('assert'); var requirejs = require('requirejs'); var parseJS = require('@babel/parser').parse; var traverse = require('@babel/traverse').default; -var {UAParser} = require('../src/main/ua-parser'); -var browsers = require('./specs/browser/browser-all.json'); -var cpus = require('./specs/cpu/cpu-all.json'); -var devices = readJsonFiles('test/specs/device'); -var engines = require('./specs/engine/engine-all.json'); -var os = readJsonFiles('test/specs/os'); +var {UAParser} = require('../../src/main/ua-parser'); +var browsers = require('../data/ua/browser/browser-all.json'); +var cpus = require('../data/ua/cpu/cpu-all.json'); +var devices = readJsonFiles('test/data/ua/device'); +var engines = require('../data/ua/engine/engine-all.json'); +var os = readJsonFiles('test/data/ua/os'); var { Headers } = require('node-fetch'); function readJsonFiles(dir) { From e013038643b5a2f7f249ed05bab089c249f707d5 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 29 Nov 2024 20:44:37 +0700 Subject: [PATCH 21/73] Improve cpu detection for x86 --- src/main/ua-parser.js | 2 +- test/data/ua/cpu/cpu-all.json | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 701375b..1f4a5ef 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -478,7 +478,7 @@ ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i, // IA32 (quicktime) - /((?:i[346]|x)86)[;\)]/i // IA32 (x86) + /\b((?:i[346]|x)86)\b/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 diff --git a/test/data/ua/cpu/cpu-all.json b/test/data/ua/cpu/cpu-all.json index 41df5d0..d43fbc0 100644 --- a/test/data/ua/cpu/cpu-all.json +++ b/test/data/ua/cpu/cpu-all.json @@ -7,6 +7,14 @@ "architecture" : "ia32" } }, + { + "desc" : "i686", + "ua" : "Mozilla/5.0 (X11; U; CrOS i686 9.10.0; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.253.0 Safari/532.5", + "expect" : + { + "architecture" : "ia32" + } + }, { "desc" : "i386", "ua" : "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7) Gecko/20040628 Epiphany/1.2.6", From b2fc76fe990888e80da9d5fdfe76632417acd553 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 30 Nov 2024 07:30:04 +0700 Subject: [PATCH 22/73] [test] remove the client hints check in firefox & safari --- test/e2e/browser.spec.mjs | 80 +++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/test/e2e/browser.spec.mjs b/test/e2e/browser.spec.mjs index 97431b6..848694c 100644 --- a/test/e2e/browser.spec.mjs +++ b/test/e2e/browser.spec.mjs @@ -3,6 +3,11 @@ import path from 'path'; import url from 'url'; const localHtml = `file://${path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '../../')}/dist/ua-parser.html`; +const browserMap = { + chromium: 'Chrome Headless', + firefox: 'Firefox', + webkit: 'Safari' +} test.describe('Custom navigator.userAgent tests', () => { @@ -42,42 +47,48 @@ test.describe('User-defined user-agent tests', () => { test.describe('withClientHints() tests', () => { - test('Detect custom Client Hints data', async ({ page }) => { - await page.addInitScript(() => { - Object.defineProperty(navigator, 'userAgentData', { - value: { - brands: [], - platform: '', - mobile: false, - getHighEntropyValues: () => { - return Promise.resolve({ - brands: [ - { - brand: 'Chromium', - version: '110' - }, - { - brand: 'Not(A:Brand', - version: '110' - }, - { - brand: 'New Browser', - version: '110' - } - ], - platform: 'New OS', - formFactors: 'New Form Factor' - }); + test('Detect custom Client Hints data', async ({ page, browserName }) => { + await page.addInitScript((browserName) => { + if (browserName == 'chromium') { + Object.defineProperty(navigator, 'userAgentData', { + value: { + brands: [], + platform: '', + mobile: false, + getHighEntropyValues: () => { + return Promise.resolve({ + brands: [ + { + brand: 'Chromium', + version: '110' + }, + { + brand: 'Not(A:Brand', + version: '110' + }, + { + brand: 'New Browser', + version: '110' + } + ], + platform: 'New OS', + formFactors: 'New Form Factor' + }); + } } - } - }); - }); + }); + } + }, browserName); await page.goto(localHtml); // @ts-ignore const uap = await page.evaluate(async () => await UAParser().withClientHints()); - expect(uap).toHaveProperty('browser.name', 'New Browser'); - expect(uap).toHaveProperty('os.name', 'New OS'); - expect(uap).toHaveProperty('device.type', undefined); + if (browserName == 'chromium') { + expect(uap).toHaveProperty('browser.name', 'New Browser'); + expect(uap).toHaveProperty('os.name', 'New OS'); + expect(uap).toHaveProperty('device.type', undefined); + } else { + expect(uap).toHaveProperty('browser.name', browserMap[browserName]); + } }); }); @@ -94,11 +105,6 @@ test.describe('withFeatureCheck() tests', () => { await page.goto(localHtml); // @ts-ignore let uap = await page.evaluate(() => UAParser()); - const browserMap = { - chromium: 'Chrome Headless', - firefox: 'Firefox', - webkit: 'Safari' - } expect(uap).toHaveProperty('browser.name', browserMap[browserName]); // @ts-ignore uap = await page.evaluate(() => UAParser().withFeatureCheck()); From fc851b40c5db6fe582f2bb017aec694b00b1f9f6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 30 Nov 2024 08:33:16 +0700 Subject: [PATCH 23/73] Improve device detection: recognize MIUI as Xiaomi --- src/extensions/ua-parser-extensions.js | 2 +- src/main/ua-parser.js | 3 ++- test/data/ua/device/xiaomi.json | 27 ++++++++++++++++++++++++++ test/data/ua/os/android.json | 9 +++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 79dd0b0..69ae56b 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -161,7 +161,7 @@ const ExtraDevices = Object.freeze({ /\b(zur\d{3}) b/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /\b((zeki)?tb.*\b) b/i // Zeki Tablets + /^((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ /\b([yr]\d{2}) b/i, diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 1f4a5ef..00884b1 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -553,7 +553,8 @@ /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models - /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i, // Xiaomi Mi + / ([\w ]+) miui\/v?\d/i ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ // OPPO diff --git a/test/data/ua/device/xiaomi.json b/test/data/ua/device/xiaomi.json index 688bd61..22fe005 100644 --- a/test/data/ua/device/xiaomi.json +++ b/test/data/ua/device/xiaomi.json @@ -1,4 +1,31 @@ [ + { + "desc": "MIUI Xiaomi Mi MIX 3 5G", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; Mi MIX 3 5G MIUI/V10.3.2.0.PEMEUVF)", + "expect": { + "vendor": "Xiaomi", + "model": "Mi MIX 3 5G", + "type": "mobile" + } + }, + { + "desc": "MIUI POCOPHONE F1", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; POCOPHONE F1 MIUI/9.6.27)", + "expect": { + "vendor": "Xiaomi", + "model": "POCOPHONE F1", + "type": "mobile" + } + }, + { + "desc": "MIUI Xiaomi M2006C3MT", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; M2006C3MT MIUI/V12.0.7.0.QCRMIXM)", + "expect": { + "vendor": "Xiaomi", + "model": "M2006C3MT", + "type": "mobile" + } + }, { "desc": "Xiaomi 2201117TG", "ua": "Mozilla/5.0 (Linux; Android 11; 2201117TG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.98 Mobile Safari/537.36", diff --git a/test/data/ua/os/android.json b/test/data/ua/os/android.json index 440fafe..7304e1e 100644 --- a/test/data/ua/os/android.json +++ b/test/data/ua/os/android.json @@ -8,6 +8,15 @@ "version" : "2.2.2" } }, + { + "desc" : "MIUI", + "ua" : "Dalvik/2.1.0 (Linux; U; Android 9; Mi MIX 3 5G MIUI/V10.3.2.0.PEMEUVF)", + "expect" : + { + "name" : "Android", + "version" : "9" + } + }, { "desc" : "KTB-Nexus 5", "ua" : "APP-My App/1.0 (Linux; Android 4.2.1; Nexus 5 Build/JOP40D)", From dbd24a579f85e02f000baa9a88953ed4e39086d2 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 30 Nov 2024 13:09:02 +0700 Subject: [PATCH 24/73] Browser naming adjustments for Client Hints: - `Google Chrome` => `Chrome` - `Microsoft Edge` => `Edge` - `Android WebView` => `Chrome WebView` - `HeadlessChrome` => `Chrome Headless` --- src/main/ua-parser.js | 8 +++++++- test/unit/ua-ch.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 test/unit/ua-ch.js diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 00884b1..468e456 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -1167,9 +1167,15 @@ var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; if (brands) { for (var i in brands) { - var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]), + var brandName = brands[i].brand || brands[i], brandVersion = brands[i].version; if (this.itemType == UA_BROWSER && !/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && brandName != CHROMIUM))) { + brandName = strMapper(brandName, { + 'Chrome' : 'Google Chrome', + 'Edge' : 'Microsoft Edge', + 'Chrome WebView' : 'Android WebView', + 'Chrome Headless' : 'HeadlessChrome' + }); this.set(NAME, brandName) .set(VERSION, brandVersion) .set(MAJOR, majorize(brandVersion)); diff --git a/test/unit/ua-ch.js b/test/unit/ua-ch.js new file mode 100644 index 0000000..83722de --- /dev/null +++ b/test/unit/ua-ch.js @@ -0,0 +1,37 @@ +const assert = require('assert'); +const { UAParser } = require('../../src/main/ua-parser'); + +describe('Browser naming adjustments', () => { + + it('Google Chrome => Chrome', () => { + const headers = { + 'sec-ch-ua' : '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + }; + const { browser } = UAParser(headers).withClientHints(); + assert.strictEqual(browser.name, 'Chrome'); + }); + + it('Microsoft Edge => Edge', () => { + const headers = { + 'sec-ch-ua' : '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"', + }; + const { browser } = UAParser(headers).withClientHints(); + assert.strictEqual(browser.name, 'Edge'); + }); + + it('Android WebView => Chrome WebView', () => { + const headers = { + 'sec-ch-ua' : '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"', + }; + const { browser } = UAParser(headers).withClientHints(); + assert.strictEqual(browser.name, 'Chrome WebView'); + }); + + it('HeadlessChrome => Chrome Headless', () => { + const headers = { + 'sec-ch-ua' : '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"', + }; + const { browser } = UAParser(headers).withClientHints(); + assert.strictEqual(browser.name, 'Chrome Headless'); + }); +}); \ No newline at end of file From 48c221b50b92eecb43069fe718fbf476dbc28164 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 30 Nov 2024 14:37:50 +0700 Subject: [PATCH 25/73] Update npm version of `@playwright/test` to fix failed test in GitHub Actions --- .github/workflows/test-ci.yml | 2 +- package-lock.json | 2523 +++++++++++++-------------------- package.json | 2 +- 3 files changed, 1008 insertions(+), 1519 deletions(-) diff --git a/.github/workflows/test-ci.yml b/.github/workflows/test-ci.yml index 5c02b3d..0c46a48 100644 --- a/.github/workflows/test-ci.yml +++ b/.github/workflows/test-ci.yml @@ -19,5 +19,5 @@ jobs: - name: Run the test run: | npm ci - npx playwright install + npx playwright install --with-deps npm test diff --git a/package-lock.json b/package-lock.json index 3e7e547..b602a64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "@babel/parser": "7.15.8", "@babel/traverse": "7.23.2", "@jazzer.js/core": "^1.4.0", - "@playwright/test": "~1.32.2", + "@playwright/test": "^1.49.0", "@types/node": "^22.9.1", "@types/node-fetch": "^2.6.12", "jshint": "~2.13.6", @@ -50,61 +50,62 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", - "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", - "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -115,10 +116,13 @@ } }, "node_modules/@babel/core/node_modules/@babel/parser": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", - "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.26.0" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -126,32 +130,163 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "node_modules/@babel/core/node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", - "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports/node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-module-imports/node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -160,145 +295,86 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "node_modules/@babel/helper-module-transforms/node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "node_modules/@babel/helper-module-transforms/node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.21.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2" + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" @@ -317,24 +393,27 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template/node_modules/@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.26.0" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -364,10 +443,13 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.26.0" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -376,14 +458,13 @@ } }, "node_modules/@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -398,19 +479,37 @@ "node": ">=8" } }, - "node_modules/@jazzer.js/core": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/core/-/core-1.4.0.tgz", - "integrity": "sha512-Wy2O6bWTOtYpfaSskYUq+iWtE6zIfp2Kang+2FvT+KT6lNMhoen/tCYZqUcMdDLgKpEqIZiDoAvMej8LgZZIxg==", + "node_modules/@jazzer.js/bug-detectors": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@jazzer.js/bug-detectors/-/bug-detectors-1.7.0.tgz", + "integrity": "sha512-ytGXkiH0G0XWXt1sm2KKdSWwEpOIN+SIe2wT6uvIO2mrUqQmLL2LnINeahL5T8L2b0+dafYDGZeVxElgsgH5eA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "dependencies": { - "@jazzer.js/hooking": "*", - "@jazzer.js/instrumentor": "*", + "@jazzer.js/core": "1.7.0", + "@jazzer.js/hooking": "1.7.0" + }, + "engines": { + "node": ">= 14.0.0", + "npm": ">= 7.0.0" + } + }, + "node_modules/@jazzer.js/core": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@jazzer.js/core/-/core-1.7.0.tgz", + "integrity": "sha512-HGSNb8HxPjK/z84I3CZUmXd/+TqTfjjGOgXKzHK9/fmwUltLLuUcbSTkc1RDHrgT4z2EF7Tlkeo51Vp648f8Ag==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "dependencies": { + "@jazzer.js/bug-detectors": "1.7.0", + "@jazzer.js/fuzzer": "1.7.0", + "@jazzer.js/hooking": "1.7.0", + "@jazzer.js/instrumentor": "1.7.0", "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-reports": "^3.1.5", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", "tmp": "^0.2.1", - "yargs": "^17.7.1" + "yargs": "^17.7.2" }, "bin": { "jazzer": "dist/cli.js" @@ -420,166 +519,17 @@ "npm": ">= 7.0.0" } }, - "node_modules/@jazzer.js/core/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jazzer.js/core/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jazzer.js/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jazzer.js/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jazzer.js/core/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/@jazzer.js/core/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@jazzer.js/core/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jazzer.js/core/node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jazzer.js/core/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/@jazzer.js/fuzzer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/fuzzer/-/fuzzer-1.4.0.tgz", - "integrity": "sha512-GSmoMZ1KCSOJoSoxrLQRELBzQcvmfJ6+CiFWbKiSFdYc6MGr3yIpROZu77vnGUSVr8hJnDA6vffbcM9dOk5r+g==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@jazzer.js/fuzzer/-/fuzzer-1.7.0.tgz", + "integrity": "sha512-FDTsHzUQva3G6ETowxAlBNY+aXc4J+XzKcTRtxQdIIW9wPli2qxUjlVCkPHfKCfOcdNseAygR/AIfrXfrB0iWw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "hasInstallScript": true, "dependencies": { "bindings": "^1.5.0", "cmake-js": "^7.2.1", - "node-addon-api": "^6.0.0", + "node-addon-api": "^7.0.0", "prebuild-install": "^7.1.1" }, "engines": { @@ -588,12 +538,13 @@ } }, "node_modules/@jazzer.js/hooking": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/hooking/-/hooking-1.4.0.tgz", - "integrity": "sha512-HubGSnLv8wfEoj81O0dxqyaLk69QGUvDGdRkZ4QydKmVvph70lLuH3DC4O7xHdneoA5Cv37qRHGvl5whkAEYnA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@jazzer.js/hooking/-/hooking-1.7.0.tgz", + "integrity": "sha512-1uGhdaRVAyNTnCuThcYFnjKKWIlVnobM+LUVoRHAFe+TVFyfnV2wCKCjoj+kjZtt4fD0lL9gjkKSafbiKNzsnA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "dependencies": { - "@babel/core": "^7.21.0" + "@babel/core": "^7.22.11" }, "engines": { "node": ">= 14.0.0", @@ -601,17 +552,18 @@ } }, "node_modules/@jazzer.js/instrumentor": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/instrumentor/-/instrumentor-1.4.0.tgz", - "integrity": "sha512-DkgalciiNIPzQaVsNM1FzzdKwnMcFDaJvB8AL+byKtdz3wEj4XoGSoMDk3tJmendP59FJHaOBxSxAjPBURv2ug==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@jazzer.js/instrumentor/-/instrumentor-1.7.0.tgz", + "integrity": "sha512-YPMzL0mH8+UKGwe0r/7vhq3DsxHOxhkeqTusYTajDycwz6/51y3JC20NhX3qs1Jyd7xpIo7ANhVN0dU4V1MwMw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "dependencies": { - "@babel/core": "^7.21.0", - "@babel/generator": "^7.21.1", - "@jazzer.js/fuzzer": "*", - "@jazzer.js/hooking": "*", + "@babel/core": "^7.22.11", + "@babel/generator": "^7.22.10", + "@jazzer.js/fuzzer": "1.7.0", + "@jazzer.js/hooking": "1.7.0", "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^5.2.1", + "istanbul-lib-instrument": "^6.0.0", "proper-lockfile": "^4.1.2", "source-map-support": "^0.5.21" }, @@ -633,59 +585,53 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -722,22 +668,18 @@ } }, "node_modules/@playwright/test": { - "version": "1.32.3", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.32.3.tgz", - "integrity": "sha512-BvWNvK0RfBriindxhLVabi8BRe3X0J9EVjKlcmhxjg4giWBD/xleLcg2dz7Tx0agu28rczjNIPQWznwzDwVsZQ==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz", + "integrity": "sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==", "dev": true, "dependencies": { - "@types/node": "*", - "playwright-core": "1.32.3" + "playwright": "1.49.0" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=14" - }, - "optionalDependencies": { - "fsevents": "2.3.2" + "node": ">=18" } }, "node_modules/@sinclair/typebox": { @@ -766,30 +708,30 @@ } }, "node_modules/@types/estree": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz", - "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/minimist": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.3.tgz", - "integrity": "sha512-ZYFzrvyWUNhaPomn80dsMNgMeXxNWZBdkuG/hWlUvXvbdUH8ZERNBGXnU87McuGcWDsyzX2aChCv/SVN348k3A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true }, "node_modules/@types/node": { - "version": "22.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz", - "integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dev": true, "dependencies": { - "undici-types": "~6.19.8" + "undici-types": "~6.20.0" } }, "node_modules/@types/node-fetch": { @@ -803,9 +745,9 @@ } }, "node_modules/@types/normalize-package-data": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz", - "integrity": "sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, "node_modules/@ungap/promise-all-settled": { @@ -838,37 +780,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { @@ -906,6 +839,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", "dev": true, "dependencies": { "delegates": "^1.0.0", @@ -972,12 +906,12 @@ "dev": true }, "node_modules/axios": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz", - "integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -1009,12 +943,15 @@ ] }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bindings": { @@ -1071,12 +1008,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1089,9 +1026,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -1101,13 +1038,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -1173,9 +1114,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001481", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz", - "integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==", + "version": "1.0.30001684", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz", + "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==", "dev": true, "funding": [ { @@ -1193,17 +1134,19 @@ ] }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chokidar": { @@ -1250,103 +1193,6 @@ } }, "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cmake-js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-7.2.1.tgz", - "integrity": "sha512-AdPSz9cSIJWdKvm0aJgVu3X8i0U3mNTswJkSHzZISqmYVjZk7Td4oDFg0mCBA383wO+9pG5Ix7pEP1CZH9x2BA==", - "dev": true, - "dependencies": { - "axios": "^1.3.2", - "debug": "^4", - "fs-extra": "^10.1.0", - "lodash.isplainobject": "^4.0.6", - "memory-stream": "^1.0.0", - "node-api-headers": "^0.0.2", - "npmlog": "^6.0.2", - "rc": "^1.2.7", - "semver": "^7.3.8", - "tar": "^6.1.11", - "url-join": "^4.0.1", - "which": "^2.0.2", - "yargs": "^17.6.0" - }, - "bin": { - "cmake-js": "bin/cmake-js" - }, - "engines": { - "node": ">= 14.15.0" - } - }, - "node_modules/cmake-js/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cmake-js/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cmake-js/node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", @@ -1360,7 +1206,46 @@ "node": ">=12" } }, - "node_modules/cmake-js/node_modules/color-convert": { + "node_modules/cmake-js": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-7.3.0.tgz", + "integrity": "sha512-dXs2zq9WxrV87bpJ+WbnGKv8WUBXDw8blNiwNHoRe/it+ptscxhQHKB1SJXa1w+kocLMeP28Tk4/eTCezg4o+w==", + "dev": true, + "dependencies": { + "axios": "^1.6.5", + "debug": "^4", + "fs-extra": "^11.2.0", + "lodash.isplainobject": "^4.0.6", + "memory-stream": "^1.0.0", + "node-api-headers": "^1.1.0", + "npmlog": "^6.0.2", + "rc": "^1.2.7", + "semver": "^7.5.4", + "tar": "^6.2.0", + "url-join": "^4.0.1", + "which": "^2.0.2", + "yargs": "^17.7.2" + }, + "bin": { + "cmake-js": "bin/cmake-js" + }, + "engines": { + "node": ">= 14.15.0" + } + }, + "node_modules/cmake-js/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -1372,154 +1257,12 @@ "node": ">=7.0.0" } }, - "node_modules/cmake-js/node_modules/color-name": { + "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/cmake-js/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cmake-js/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cmake-js/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cmake-js/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cmake-js/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cmake-js/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cmake-js/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/cmake-js/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/cmake-js/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/cmake-js/node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cmake-js/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -1563,9 +1306,9 @@ "dev": true }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "node_modules/core-util-is": { @@ -1581,12 +1324,12 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1705,9 +1448,9 @@ ] }, "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "dev": true, "engines": { "node": ">=8" @@ -1800,15 +1543,15 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.374", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.374.tgz", - "integrity": "sha512-dNP9tQNTrjgVlSXMqGaj0BdrCS+9pcUvy5/emB6x8kh0YwCoDZ0Z4ce1+7aod+KhybHUd5o5LgKrc5al4kVmzQ==", + "version": "1.5.67", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz", + "integrity": "sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==", "dev": true }, "node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/end-of-stream": { @@ -1836,21 +1579,24 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint-formatter-pretty": { @@ -1875,126 +1621,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-formatter-pretty/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint-formatter-pretty/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/eslint-formatter-pretty/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/eslint-rule-docs": { "version": "1.1.235", "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz", @@ -2033,9 +1659,9 @@ } }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -2049,9 +1675,9 @@ } }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -2064,9 +1690,9 @@ "dev": true }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -2101,9 +1727,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "dev": true, "funding": [ { @@ -2121,9 +1747,9 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dev": true, "dependencies": { "asynckit": "^0.4.0", @@ -2141,9 +1767,9 @@ "dev": true }, "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -2151,7 +1777,7 @@ "universalify": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.14" } }, "node_modules/fs-minipass": { @@ -2190,16 +1816,34 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gauge": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", "dev": true, "dependencies": { "aproba": "^1.0.3 || ^2.0.0", @@ -2215,56 +1859,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/gauge/node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -2302,6 +1896,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -2395,25 +1990,13 @@ "node": ">=6" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-unicode": { @@ -2422,6 +2005,18 @@ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -2501,9 +2096,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" @@ -2522,6 +2117,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "dependencies": { "once": "^1.3.0", @@ -2568,12 +2164,15 @@ } }, "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2589,12 +2188,12 @@ } }, "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/is-glob": { @@ -2619,12 +2218,12 @@ } }, "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/is-standalone-pwa": { @@ -2659,9 +2258,9 @@ "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "engines": { "node": ">=8" @@ -2680,60 +2279,66 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=8" + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -2758,76 +2363,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -2857,15 +2392,15 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/jshint": { @@ -2970,76 +2505,6 @@ "node": ">=10" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3050,20 +2515,32 @@ } }, "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -3165,12 +2642,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -3254,19 +2731,10 @@ "node": ">= 6" } }, - "node_modules/minimist-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, "engines": { "node": ">=8" @@ -3365,6 +2833,53 @@ "url": "https://opencollective.com/mochajs" } }, + "node_modules/mocha/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/mocha/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/mocha/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, "node_modules/mocha/node_modules/debug": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", @@ -3383,22 +2898,17 @@ } } }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/mocha/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "node_modules/mocha/node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -3415,13 +2925,26 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/mocha/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/mocha/node_modules/minimatch": { @@ -3436,16 +2959,72 @@ "node": "*" } }, - "node_modules/mocha/node_modules/nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "node_modules/mocha/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "p-try": "^2.0.0" }, "engines": { - "node": "^10 || ^12 || >=13.7" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/mocha/node_modules/strip-json-comments": { @@ -3460,24 +3039,74 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/mocha/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/mocha/node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || >=13.7" + } + }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -3485,9 +3114,9 @@ "dev": true }, "node_modules/node-abi": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.40.0.tgz", - "integrity": "sha512-zNy02qivjjRosswoYmPi8hIKJRr8MpQyeKT6qlcq/OnOgA3Rhoae+IYOqsM9V5+JnHWmxKnWOT2GxvtqdtOCXA==", + "version": "3.71.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", + "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", "dev": true, "dependencies": { "semver": "^7.3.5" @@ -3496,26 +3125,11 @@ "node": ">=10" } }, - "node_modules/node-abi/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-abi/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -3523,22 +3137,16 @@ "node": ">=10" } }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true }, "node_modules/node-api-headers": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/node-api-headers/-/node-api-headers-0.0.2.tgz", - "integrity": "sha512-YsjmaKGPDkmhoNKIpkChtCsPVaRE0a274IdERKnuc/E8K1UJdBZ4/mvI006OijlQZHCfpRNOH3dfHQs92se8gg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-api-headers/-/node-api-headers-1.4.0.tgz", + "integrity": "sha512-u83U3WnRbBpWlhc0sQbpF3slHRLV/a6/OXByc+QzHcLxiDiJUWLuKGZp4/ntZUchnXGOCnCq++JUEtwb1/tyow==", "dev": true }, "node_modules/node-fetch": { @@ -3562,9 +3170,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "node_modules/normalize-package-data": { @@ -3582,26 +3190,11 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -3609,12 +3202,6 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3628,6 +3215,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", "dev": true, "dependencies": { "are-we-there-yet": "^3.0.0", @@ -3739,9 +3327,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "node_modules/picomatch": { @@ -3756,16 +3344,48 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/playwright-core": { - "version": "1.32.3", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.32.3.tgz", - "integrity": "sha512-SB+cdrnu74ZIn5Ogh/8278ngEh9NEEV0vR4sJFmK04h2iZpybfbqBY0bX6+BLYWVdV12JLLI+JEFtSnYgR+mWg==", + "node_modules/playwright": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz", + "integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==", "dev": true, + "dependencies": { + "playwright-core": "1.49.0" + }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=14" + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz", + "integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/plur": { @@ -3784,9 +3404,9 @@ } }, "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", "dev": true, "dependencies": { "detect-libc": "^2.0.0", @@ -3853,9 +3473,9 @@ "dev": true }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, "dependencies": { "end-of-stream": "^1.1.0", @@ -3925,9 +3545,9 @@ } }, "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, "node_modules/read-pkg": { @@ -4097,9 +3717,9 @@ } }, "node_modules/regexp-tree": { - "version": "0.1.24", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", - "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", "dev": true, "bin": { "regexp-tree": "bin/regexp-tree" @@ -4134,9 +3754,9 @@ } }, "node_modules/resolve": { - "version": "1.22.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", - "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -4169,21 +3789,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4237,9 +3842,9 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -4350,9 +3955,9 @@ } }, "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, "node_modules/spdx-expression-parse": { @@ -4366,9 +3971,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.15.tgz", - "integrity": "sha512-lpT8hSQp9jAKp9mhtBU4Xjon8LPGBvLIuBiSVhMEtmLecTh2mO0tlqrAMp47tBXzMr13NJMQ2lf7RpQGLJ3HsQ==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "dev": true }, "node_modules/sprintf-js": { @@ -4384,28 +3989,29 @@ "dev": true }, "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-bom": { @@ -4442,15 +4048,15 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-hyperlinks": { @@ -4466,27 +4072,6 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -4500,14 +4085,14 @@ } }, "node_modules/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" @@ -4580,24 +4165,12 @@ "dev": true }, "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=14.14" } }, "node_modules/to-regex-range": { @@ -4660,6 +4233,18 @@ "node": "*" } }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ua-is-frozen": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ua-is-frozen/-/ua-is-frozen-0.1.2.tgz", @@ -4692,24 +4277,24 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -4726,8 +4311,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -4790,9 +4375,9 @@ } }, "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true }, "node_modules/wide-align": { @@ -4804,6 +4389,49 @@ "string-width": "^1.0.2 || 2" } }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/workerpool": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", @@ -4811,52 +4439,20 @@ "dev": true }, "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "node": ">=10" }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrappy": { @@ -4866,10 +4462,13 @@ "dev": true }, "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/yallist": { "version": "3.1.1", @@ -4878,21 +4477,21 @@ "dev": true }, "node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, "node_modules/yargs-parser": { @@ -4944,100 +4543,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" + "node": ">=12" } }, "node_modules/yocto-queue": { @@ -5051,38 +4572,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "src/client-hints-helpers": { - "name": "@ua-parser-js/client-hints-helpers", - "version": "0.0.1", - "extraneous": true, - "license": "MIT" - }, - "src/gpu-detect": { - "version": "0.0.1", - "extraneous": true, - "license": "MIT" - }, - "src/helpers": { - "name": "@ua-parser-js/helpers", - "version": "0.0.3", - "extraneous": true, - "license": "MIT" - }, - "src/ua-client-hints": { - "name": "@ua-parser-js/ua-client-hints", - "version": "0.0.1", - "extraneous": true, - "license": "MIT" - }, - "src/user-agent-helpers": { - "name": "@ua-parser-js/user-agent-helpers", - "version": "0.0.2", - "extraneous": true, - "license": "MIT", - "dependencies": { - "@ua-parser-js/client-hints-helpers": "*" - } } } } diff --git a/package.json b/package.json index b9d9581..76c9288 100755 --- a/package.json +++ b/package.json @@ -220,7 +220,7 @@ "@babel/parser": "7.15.8", "@babel/traverse": "7.23.2", "@jazzer.js/core": "^1.4.0", - "@playwright/test": "~1.32.2", + "@playwright/test": "^1.49.0", "@types/node": "^22.9.1", "@types/node-fetch": "^2.6.12", "jshint": "~2.13.6", From aed89f0b414fe75d843f983636d389bc1f94147e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 30 Nov 2024 18:55:27 +0700 Subject: [PATCH 26/73] Fix #660 - Infer device vendor & type from `sec-ch-ua-model` --- src/main/ua-parser.js | 15 ++-- test/unit/main.js | 4 +- test/unit/ua-ch.js | 185 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+), 7 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 468e456..7edc48d 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -1200,11 +1200,16 @@ } if (uaCH[MODEL]) { this.set(MODEL, uaCH[MODEL]); - } - // Xbox-Specific Detection - if (uaCH[MODEL] == 'Xbox') { - this.set(TYPE, CONSOLE) - .set(VENDOR, MICROSOFT); + if (!this.get(TYPE) || !this.get(VENDOR)) { + var reParse = {}; + rgxMapper.call(reParse, 'droid 9; ' + uaCH[MODEL] + ')', rgxMap); + if (!this.get(TYPE) && !!reParse.type) { + this.set(TYPE, reParse.type); + } + if (!this.get(VENDOR) && !!reParse.vendor) { + this.set(VENDOR, reParse.vendor); + } + } } if (uaCH[FORMFACTORS]) { var ff; diff --git a/test/unit/main.js b/test/unit/main.js index 0433882..ea337f9 100644 --- a/test/unit/main.js +++ b/test/unit/main.js @@ -390,10 +390,10 @@ describe('Map UA-CH headers', function () { assert.strictEqual(cpu.architecture, "arm64"); assert.strictEqual(uap.device.type, "mobile"); assert.strictEqual(uap.device.model, "Pixel 99"); - assert.strictEqual(uap.device.vendor, undefined); + assert.strictEqual(uap.device.vendor, "Google"); assert.strictEqual(device.type, "mobile"); assert.strictEqual(device.model, "Pixel 99"); - assert.strictEqual(device.vendor, undefined); + assert.strictEqual(device.vendor, "Google"); assert.strictEqual(uap.engine.name, 'Blink'); assert.strictEqual(uap.engine.version, '93.0.1.2'); assert.strictEqual(engine.name, 'Blink'); diff --git a/test/unit/ua-ch.js b/test/unit/ua-ch.js index 83722de..84dc1fd 100644 --- a/test/unit/ua-ch.js +++ b/test/unit/ua-ch.js @@ -34,4 +34,189 @@ describe('Browser naming adjustments', () => { const { browser } = UAParser(headers).withClientHints(); assert.strictEqual(browser.name, 'Chrome Headless'); }); +}); + +describe('Identify vendor & type of device from given model name', () => { + + [ + { + model: '220733SG', + expect: { + vendor : 'Xiaomi', + type : 'mobile' + } + }, + { + model: '5087Z', + expect: { + vendor : 'TCL', + type : 'mobile' + } + }, + { + model: '9137W', + expect: { + vendor : 'TCL', + type : 'tablet' + } + }, + { + model: 'BE2015', + expect: { + vendor : 'OnePlus', + type : 'mobile' + } + }, + { + model: 'CPH2389', + expect: { + vendor : 'OPPO', + type : 'mobile' + } + }, + { + model: 'Infinix X669C', + expect: { + vendor : 'Infinix', + type : 'mobile' + } + }, + { + model: 'itel L6502', + expect: { + vendor : 'itel', + type : 'mobile' + } + }, + { + model: 'Lenovo TB-X606F', + expect: { + vendor : 'Lenovo', + type : 'tablet' + } + }, + { + model: 'LM-Q720', + expect: { + vendor : 'LG', + type : 'mobile' + } + }, + { + model: 'M2003J15SC', + expect: { + vendor : 'Xiaomi', + type : 'mobile' + } + }, + { + model: 'MAR-LX1A', + expect: { + vendor : 'Huawei', + type : 'mobile' + } + }, + { + model: 'moto g(20)', + expect: { + vendor : 'Motorola', + type : 'mobile' + } + }, + { + model: 'Nokia C210', + expect: { + vendor : 'Nokia', + type : 'mobile' + } + }, + { + model: 'Pixel 8', + expect: { + vendor : 'Google', + type : 'mobile' + } + }, + { + model: 'Redmi Note 9S', + expect: { + vendor : 'Xiaomi', + type : 'mobile' + } + }, + { + model: 'RMX3830', + expect: { + vendor : 'Realme', + type : 'mobile' + } + }, + { + model: 'SM-S536DL', + expect: { + vendor : 'Samsung', + type : 'mobile' + } + }, + { + model: 'SM-S546VL', + expect: { + vendor : 'Samsung', + type : 'mobile' + } + }, + { + model: 'SM-T875', + expect: { + vendor : 'Samsung', + type : 'tablet' + } + }, + { + model: 'STK-L21', + expect: { + vendor : 'Huawei', + type : 'mobile' + } + }, + { + model: 'T430W', + expect: { + vendor : 'TCL', + type : 'mobile' + } + }, + { + model: 'TECNO KI5k', + expect: { + vendor : 'TECNO', + type : 'mobile' + } + }, + { + model: 'vivo 1820', + expect: { + vendor : 'Vivo', + type : 'mobile' + } + }, + { + model: 'Xbox', + expect: { + vendor : 'Microsoft', + type : 'console' + } + } + ] + .forEach((test) => { + it(`Solve "${test.model}"`, () => { + const headers = { + 'sec-ch-ua-model' : test.model, + }; + const { device } = UAParser(headers).withClientHints(); + assert.strictEqual(device.model, test.model); + assert.strictEqual(device.vendor, test.expect.vendor); + assert.strictEqual(device.type, test.expect.type); + }); + }); }); \ No newline at end of file From 259cd1422bc12f530b7f92fe40d1187dddd5ee7a Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 30 Nov 2024 19:31:53 +0700 Subject: [PATCH 27/73] [test] Move all client hints-related tests into a separate file --- test/unit/main.js | 220 ------------------------------------ test/unit/ua-ch.js | 269 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 247 insertions(+), 242 deletions(-) diff --git a/test/unit/main.js b/test/unit/main.js index ea337f9..3f01d19 100644 --- a/test/unit/main.js +++ b/test/unit/main.js @@ -353,224 +353,4 @@ describe('Read user-agent data from req.headers', function () { const { browser } = UAParser(reqHeaders); assert.strictEqual(browser.is('Midori'), true); }); -}); - -describe('Map UA-CH headers', function () { - - const headers = { - 'sec-ch-ua' : '"Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"', - 'sec-ch-ua-full-version-list' : '"Chromium";v="93.0.1.2", "Google Chrome";v="93.0.1.2", " Not;A Brand";v="99.0.1.2"', - 'sec-ch-ua-arch' : '"arm"', - 'sec-ch-ua-bitness' : '"64"', - 'sec-ch-ua-mobile' : '?1', - 'sec-ch-ua-model' : '"Pixel 99"', - 'sec-ch-ua-platform' : '"Windows"', - 'sec-ch-ua-platform-version' : '"13"', - 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' - }; - - let uap = UAParser(headers).withClientHints(); - let browser = new UAParser(headers).getBrowser().withClientHints(); - let cpu = new UAParser(headers).getCPU().withClientHints(); - let device = new UAParser(headers).getDevice().withClientHints(); - let engine = new UAParser(headers).getEngine().withClientHints(); - let os = new UAParser(headers).getOS().withClientHints(); - - it('Can read from client-hints headers using `withClientHints()`', function () { - - //assert.deepEqual(uap.ua_ch, ua_ch); - assert.strictEqual(uap.ua, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"); - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "93.0.1.2"); - assert.strictEqual(uap.browser.major, "93"); - assert.strictEqual(browser.name, "Chrome"); - assert.strictEqual(browser.version, "93.0.1.2"); - assert.strictEqual(browser.major, "93"); - assert.strictEqual(uap.cpu.architecture, "arm64"); - assert.strictEqual(cpu.architecture, "arm64"); - assert.strictEqual(uap.device.type, "mobile"); - assert.strictEqual(uap.device.model, "Pixel 99"); - assert.strictEqual(uap.device.vendor, "Google"); - assert.strictEqual(device.type, "mobile"); - assert.strictEqual(device.model, "Pixel 99"); - assert.strictEqual(device.vendor, "Google"); - assert.strictEqual(uap.engine.name, 'Blink'); - assert.strictEqual(uap.engine.version, '93.0.1.2'); - assert.strictEqual(engine.name, 'Blink'); - assert.strictEqual(engine.version, '93.0.1.2'); - assert.strictEqual(uap.os.name, "Windows"); - assert.strictEqual(uap.os.version, "11"); - assert.strictEqual(os.name, "Windows"); - assert.strictEqual(os.version, "11"); - }); - - it('Only read from user-agent header when called without `withClientHints()`', function () { - - uap = UAParser(headers); - browser = new UAParser(headers).getBrowser(); - cpu = new UAParser(headers).getCPU(); - device = new UAParser(headers).getDevice(); - engine = new UAParser(headers).getEngine(); - os = new UAParser(headers).getOS(); - - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "110.0.0.0"); - assert.strictEqual(uap.browser.major, "110"); - assert.strictEqual(uap.cpu.architecture, "amd64"); - assert.strictEqual(uap.device.type, undefined); - assert.strictEqual(uap.device.model, undefined); - assert.strictEqual(uap.device.vendor, undefined); - assert.strictEqual(uap.engine.name, 'Blink'); - assert.strictEqual(uap.engine.version, '110.0.0.0'); - assert.strictEqual(uap.os.name, "Linux"); - assert.strictEqual(uap.os.version, "x86_64"); - }); - - it('Fallback to user-agent header when using `withClientHints()` but found no client hints-related headers', function () { - - const headers2 = { - 'sec-ch-ua-mobile' : '?1', - 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' - }; - - uap = UAParser(headers2).withClientHints(); - - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "110.0.0.0"); - assert.strictEqual(uap.browser.major, "110"); - assert.strictEqual(uap.cpu.architecture, "amd64"); - assert.strictEqual(uap.device.type, "mobile"); - assert.strictEqual(uap.device.model, undefined); - assert.strictEqual(uap.device.vendor, undefined); - assert.strictEqual(uap.engine.name, 'Blink'); - assert.strictEqual(uap.engine.version, '110.0.0.0'); - assert.strictEqual(uap.os.name, "Linux"); - assert.strictEqual(uap.os.version, "x86_64"); - }); - - it('Can detect Apple silicon from client hints data', function () { - - // https://github.com/faisalman/ua-parser-js/issues/489#issuecomment-1479213579 - const httpHeadersFromAppleSilicon = { - 'sec-ch-ua-arch' : 'arm', - 'sec-ch-ua-platform' : 'macOS', - 'sec-ch-ua-mobile' : '?0', - 'sec-ch-ua' : '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', - 'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0' - }; - - UAParser(httpHeadersFromAppleSilicon).withClientHints().then(function (ua) { - - // Only works in Chrome - /* - if (ua.os.is("macOS") && - ua.cpu.is("arm") && - !ua.device.is("mobile") && - !ua.device.is("tablet")) { - // possibly an Apple silicon device - } - */ - - assert.strictEqual(ua.os.is("macOS"), true); - assert.strictEqual(ua.cpu.is("arm"), true); - assert.strictEqual(ua.device.is("mobile"), false); - assert.strictEqual(ua.device.is("tablet"), false); - }); - }); - - it('Can detect form-factors from client-hints', function () { - - const FFVR = { - 'sec-ch-ua-form-factors' : '"VR"' - }; - - const FFEInk = { - 'sec-ch-ua-form-factors' : '"Tablet", "EInk"' - }; - - const FFUnknown = { - 'sec-ch-ua-form-factors' : '"Unknown"' - }; - - UAParser(FFVR).withClientHints().then(function (ua) { - assert.strictEqual(ua.device.type, 'xr'); - }); - - UAParser(FFEInk).withClientHints().then(function (ua) { - assert.strictEqual(ua.device.type, 'tablet'); - }); - - - UAParser(FFUnknown).withClientHints().then(function (ua) { - assert.strictEqual(ua.device.type, undefined); - }); - }); - - it('Avoid error on headers variation', function () { - - const headers2 = { - 'sec-ch-ua' : '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', - 'sec-ch-ua-full-version-list' : '"Google Chrome", "Chromium", "Not?A_Brand";v="24.0.0.0"', - 'sec-ch-ua-full-version' : '""', - 'sec-ch-ua-mobile' : '?0', - 'sec-ch-ua-arch' : '""', - 'sec-ch-ua-bitness' : '""', - 'sec-ch-ua-model' : '""', - 'sec-ch-ua-platform' : '"Windows"', - 'sec-ch-ua-platform-version' : '""', - 'sec-ch-ua-wow64' : '?0', - }; - - uap = UAParser(headers2).withClientHints(); - - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, undefined); - assert.strictEqual(uap.browser.major, undefined); - }); - - it('Prioritize more specific brand name regardless the order', function () { - - const headers3a = { - 'sec-ch-ua-full-version-list' : '"Not_A Brand;v=8, Chromium;v=120.0.6099.131, Google Chrome;v=120.0.6099.132"' - }; - const headers3b = { - 'sec-ch-ua-full-version-list' : '"Chromium;v=120.0.6099.131, Not_A Brand;v=8, Google Chrome;v=120.0.6099.132"' - }; - const headers3c = { - 'sec-ch-ua-full-version-list' : '"Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131, Not_A Brand;v=8"' - }; - const headers3d = { - 'sec-ch-ua-full-version-list' : '"Microsoft Edge;v=120.0.6099.133, Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131, Not_A Brand;v=8"' - }; - const headers3e = { - 'sec-ch-ua-full-version-list' : '"Chromium;v=120.0.6099.131, Google Chrome;v=120.0.6099.132, Microsoft Edge;v=120.0.6099.133, Not_A Brand;v=8"' - }; - const headers3f = { - 'sec-ch-ua-full-version-list' : '"Not_A Brand;v=8, Microsoft Edge;v=120.0.6099.133, Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131"' - }; - - uap = UAParser(headers3a).withClientHints(); - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "120.0.6099.132"); - - uap = UAParser(headers3b).withClientHints(); - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "120.0.6099.132"); - - uap = UAParser(headers3c).withClientHints(); - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "120.0.6099.132"); - - uap = UAParser(headers3d).withClientHints(); - assert.strictEqual(uap.browser.name, "Edge"); - assert.strictEqual(uap.browser.version, "120.0.6099.133"); - - uap = UAParser(headers3e).withClientHints(); - assert.strictEqual(uap.browser.name, "Edge"); - assert.strictEqual(uap.browser.version, "120.0.6099.133"); - - uap = UAParser(headers3f).withClientHints(); - assert.strictEqual(uap.browser.name, "Edge"); - assert.strictEqual(uap.browser.version, "120.0.6099.133"); - }); }); \ No newline at end of file diff --git a/test/unit/ua-ch.js b/test/unit/ua-ch.js index 84dc1fd..1342a35 100644 --- a/test/unit/ua-ch.js +++ b/test/unit/ua-ch.js @@ -1,43 +1,268 @@ const assert = require('assert'); const { UAParser } = require('../../src/main/ua-parser'); -describe('Browser naming adjustments', () => { +describe('Map UA-CH headers', () => { - it('Google Chrome => Chrome', () => { - const headers = { + const headers = { + 'sec-ch-ua' : '"Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"', + 'sec-ch-ua-full-version-list' : '"Chromium";v="93.0.1.2", "Google Chrome";v="93.0.1.2", " Not;A Brand";v="99.0.1.2"', + 'sec-ch-ua-arch' : '"arm"', + 'sec-ch-ua-bitness' : '"64"', + 'sec-ch-ua-mobile' : '?1', + 'sec-ch-ua-model' : '"Pixel 99"', + 'sec-ch-ua-platform' : '"Windows"', + 'sec-ch-ua-platform-version' : '"13"', + 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' + }; + + let uap = UAParser(headers).withClientHints(); + let browser = new UAParser(headers).getBrowser().withClientHints(); + let cpu = new UAParser(headers).getCPU().withClientHints(); + let device = new UAParser(headers).getDevice().withClientHints(); + let engine = new UAParser(headers).getEngine().withClientHints(); + let os = new UAParser(headers).getOS().withClientHints(); + + it('Can read from client-hints headers using `withClientHints()`', () => { + + assert.strictEqual(uap.ua, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"); + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "93.0.1.2"); + assert.strictEqual(uap.browser.major, "93"); + assert.strictEqual(browser.name, "Chrome"); + assert.strictEqual(browser.version, "93.0.1.2"); + assert.strictEqual(browser.major, "93"); + assert.strictEqual(uap.cpu.architecture, "arm64"); + assert.strictEqual(cpu.architecture, "arm64"); + assert.strictEqual(uap.device.type, "mobile"); + assert.strictEqual(uap.device.model, "Pixel 99"); + assert.strictEqual(uap.device.vendor, "Google"); + assert.strictEqual(device.type, "mobile"); + assert.strictEqual(device.model, "Pixel 99"); + assert.strictEqual(device.vendor, "Google"); + assert.strictEqual(uap.engine.name, 'Blink'); + assert.strictEqual(uap.engine.version, '93.0.1.2'); + assert.strictEqual(engine.name, 'Blink'); + assert.strictEqual(engine.version, '93.0.1.2'); + assert.strictEqual(uap.os.name, "Windows"); + assert.strictEqual(uap.os.version, "11"); + assert.strictEqual(os.name, "Windows"); + assert.strictEqual(os.version, "11"); + }); + + it('Only read from user-agent header when called without `withClientHints()`', () => { + + uap = UAParser(headers); + browser = new UAParser(headers).getBrowser(); + cpu = new UAParser(headers).getCPU(); + device = new UAParser(headers).getDevice(); + engine = new UAParser(headers).getEngine(); + os = new UAParser(headers).getOS(); + + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "110.0.0.0"); + assert.strictEqual(uap.browser.major, "110"); + assert.strictEqual(uap.cpu.architecture, "amd64"); + assert.strictEqual(uap.device.type, undefined); + assert.strictEqual(uap.device.model, undefined); + assert.strictEqual(uap.device.vendor, undefined); + assert.strictEqual(uap.engine.name, 'Blink'); + assert.strictEqual(uap.engine.version, '110.0.0.0'); + assert.strictEqual(uap.os.name, "Linux"); + assert.strictEqual(uap.os.version, "x86_64"); + }); + + it('Fallback to user-agent header when using `withClientHints()` but found no client hints-related headers', () => { + + const headers2 = { + 'sec-ch-ua-mobile' : '?1', + 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' + }; + + uap = UAParser(headers2).withClientHints(); + + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "110.0.0.0"); + assert.strictEqual(uap.browser.major, "110"); + assert.strictEqual(uap.cpu.architecture, "amd64"); + assert.strictEqual(uap.device.type, "mobile"); + assert.strictEqual(uap.device.model, undefined); + assert.strictEqual(uap.device.vendor, undefined); + assert.strictEqual(uap.engine.name, 'Blink'); + assert.strictEqual(uap.engine.version, '110.0.0.0'); + assert.strictEqual(uap.os.name, "Linux"); + assert.strictEqual(uap.os.version, "x86_64"); + }); + + it('Can detect Apple silicon from client hints data', () => { + + // https://github.com/faisalman/ua-parser-js/issues/489#issuecomment-1479213579 + const httpHeadersFromAppleSilicon = { + 'sec-ch-ua-arch' : 'arm', + 'sec-ch-ua-platform' : 'macOS', + 'sec-ch-ua-mobile' : '?0', 'sec-ch-ua' : '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + 'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0' }; - const { browser } = UAParser(headers).withClientHints(); - assert.strictEqual(browser.name, 'Chrome'); + + UAParser(httpHeadersFromAppleSilicon).withClientHints().then(ua => { + + // Only works in Chrome + /* + if (ua.os.is("macOS") && + ua.cpu.is("arm") && + !ua.device.is("mobile") && + !ua.device.is("tablet")) { + // possibly an Apple silicon device + } + */ + + assert.strictEqual(ua.os.is("macOS"), true); + assert.strictEqual(ua.cpu.is("arm"), true); + assert.strictEqual(ua.device.is("mobile"), false); + assert.strictEqual(ua.device.is("tablet"), false); + }); }); - it('Microsoft Edge => Edge', () => { - const headers = { - 'sec-ch-ua' : '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"', + it('Can detect form-factors from client-hints', () => { + + const FFVR = { + 'sec-ch-ua-form-factors' : '"VR"' }; - const { browser } = UAParser(headers).withClientHints(); - assert.strictEqual(browser.name, 'Edge'); + + const FFEInk = { + 'sec-ch-ua-form-factors' : '"Tablet", "EInk"' + }; + + const FFUnknown = { + 'sec-ch-ua-form-factors' : '"Unknown"' + }; + + UAParser(FFVR).withClientHints().then(ua => { + assert.strictEqual(ua.device.type, 'xr'); + }); + + UAParser(FFEInk).withClientHints().then(ua => { + assert.strictEqual(ua.device.type, 'tablet'); + }); + + + UAParser(FFUnknown).withClientHints().then(ua => { + assert.strictEqual(ua.device.type, undefined); + }); }); - it('Android WebView => Chrome WebView', () => { - const headers = { - 'sec-ch-ua' : '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"', + it('Avoid error on headers variation', () => { + + const headers2 = { + 'sec-ch-ua' : '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', + 'sec-ch-ua-full-version-list' : '"Google Chrome", "Chromium", "Not?A_Brand";v="24.0.0.0"', + 'sec-ch-ua-full-version' : '""', + 'sec-ch-ua-mobile' : '?0', + 'sec-ch-ua-arch' : '""', + 'sec-ch-ua-bitness' : '""', + 'sec-ch-ua-model' : '""', + 'sec-ch-ua-platform' : '"Windows"', + 'sec-ch-ua-platform-version' : '""', + 'sec-ch-ua-wow64' : '?0', }; - const { browser } = UAParser(headers).withClientHints(); - assert.strictEqual(browser.name, 'Chrome WebView'); + + uap = UAParser(headers2).withClientHints(); + + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, undefined); + assert.strictEqual(uap.browser.major, undefined); }); - it('HeadlessChrome => Chrome Headless', () => { - const headers = { - 'sec-ch-ua' : '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"', + it('Prioritize more specific brand name regardless the order', () => { + + const headers3a = { + 'sec-ch-ua-full-version-list' : '"Not_A Brand;v=8, Chromium;v=120.0.6099.131, Google Chrome;v=120.0.6099.132"' }; - const { browser } = UAParser(headers).withClientHints(); - assert.strictEqual(browser.name, 'Chrome Headless'); + const headers3b = { + 'sec-ch-ua-full-version-list' : '"Chromium;v=120.0.6099.131, Not_A Brand;v=8, Google Chrome;v=120.0.6099.132"' + }; + const headers3c = { + 'sec-ch-ua-full-version-list' : '"Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131, Not_A Brand;v=8"' + }; + const headers3d = { + 'sec-ch-ua-full-version-list' : '"Microsoft Edge;v=120.0.6099.133, Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131, Not_A Brand;v=8"' + }; + const headers3e = { + 'sec-ch-ua-full-version-list' : '"Chromium;v=120.0.6099.131, Google Chrome;v=120.0.6099.132, Microsoft Edge;v=120.0.6099.133, Not_A Brand;v=8"' + }; + const headers3f = { + 'sec-ch-ua-full-version-list' : '"Not_A Brand;v=8, Microsoft Edge;v=120.0.6099.133, Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131"' + }; + + uap = UAParser(headers3a).withClientHints(); + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "120.0.6099.132"); + + uap = UAParser(headers3b).withClientHints(); + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "120.0.6099.132"); + + uap = UAParser(headers3c).withClientHints(); + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "120.0.6099.132"); + + uap = UAParser(headers3d).withClientHints(); + assert.strictEqual(uap.browser.name, "Edge"); + assert.strictEqual(uap.browser.version, "120.0.6099.133"); + + uap = UAParser(headers3e).withClientHints(); + assert.strictEqual(uap.browser.name, "Edge"); + assert.strictEqual(uap.browser.version, "120.0.6099.133"); + + uap = UAParser(headers3f).withClientHints(); + assert.strictEqual(uap.browser.name, "Edge"); + assert.strictEqual(uap.browser.version, "120.0.6099.133"); + }); +}); + +describe('Browser naming adjustments', () => { + [ + { + ua_ch: '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + expect: { + before: 'Google Chrome', + after: 'Chrome' + } + }, + { + ua_ch: '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"', + expect: { + before: "Microsoft Edge", + after: "Edge" + } + }, + { + ua_ch: '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"', + expect: { + before: "Android WebView", + after: "Chrome WebView" + } + }, + { + ua_ch: '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"', + expect: { + before: "HeadlessChrome", + after: "Chrome Headless" + } + }, + ] + .forEach(test => { + it(`"${test.expect.before}" => "${test.expect.after}"`, () => { + const headers = { + 'sec-ch-ua' : test.ua_ch, + }; + const { browser } = UAParser(headers).withClientHints(); + assert.strictEqual(browser.name, test.expect.after); + }); }); }); describe('Identify vendor & type of device from given model name', () => { - [ { model: '220733SG', @@ -208,7 +433,7 @@ describe('Identify vendor & type of device from given model name', () => { } } ] - .forEach((test) => { + .forEach(test => { it(`Solve "${test.model}"`, () => { const headers = { 'sec-ch-ua-model' : test.model, From fbadfd7aceaf1c416fc4a9147942a61f3ca67188 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 30 Nov 2024 22:51:29 +0700 Subject: [PATCH 28/73] Improve device detection for wearables --- src/main/ua-parser.js | 25 ++++++++++++++------- test/data/ua/device/asus.json | 9 ++++++++ test/data/ua/device/lg.json | 18 ++++++++++++++++ test/data/ua/device/motorola.json | 9 ++++++++ test/data/ua/device/oneplus.json | 9 ++++++++ test/data/ua/device/oppo.json | 36 +++++++++++++++++++++++++++++++ test/data/ua/device/samsung.json | 18 ++++++++++++++++ test/data/ua/device/sony.json | 9 ++++++++ 8 files changed, 125 insertions(+), 8 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 7edc48d..87fac2a 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -76,6 +76,7 @@ LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', + ONEPLUS = 'OnePlus', OPPO = 'OPPO', SAMSUNG = 'Samsung', SHARP = 'Sharp', @@ -576,7 +577,7 @@ // Motorola /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, /\bmot(?:orola)?[- ](\w*)/i, - /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i + /((?:moto(?! 360)[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ /\b(mz60\d|xoom[2 ]{0,2}) build\//i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ @@ -585,7 +586,7 @@ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, - /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, + /\blg[-e;\/ ]+((?!browser|netcast|android tv|watch)\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ @@ -617,7 +618,7 @@ // OnePlus / (kb2005|in20[12]5|be20[12][59])\b/i, /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i - ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [ // Amazon /(alexa)webm/i, @@ -697,14 +698,12 @@ /(infinix) (x1101b?)/i // Infinix XPad ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan /; (hmd|imo) ([\w ]+?)(?: bui|\))/i, // HMD/IMO /(hp) ([\w ]+\w)/i, // HP iPAQ - /(asus)-?(\w+)/i, // Asus /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i, // Lenovo - /(jolla)/i, // Jolla /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ @@ -784,13 +783,23 @@ // WEARABLES /////////////////// - /\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch + /\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i // Samsung Galaxy Watch ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [ /((pebble))app/i, // Pebble - /(google) (pixel watch[\w ]*)( bui|\))/i // Pixel Watch + /(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i // Asus ZenWatch / LG Watch / Pixel Watch ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ + /(ow(?:19|20)?we?[1-3]{1,3})/i // Oppo Watch + ], [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]], [ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [ + /(opwwe\d{3})/i // OnePlus Watch + ], [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]], [ + /(moto 360)/i // Motorola 360 + ], [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]], [ + /(smartwatch 3)/i // Sony SmartWatch + ], [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]], [ + /(g watch r)/i // LG G Watch R + ], [MODEL, [VENDOR, LG], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ diff --git a/test/data/ua/device/asus.json b/test/data/ua/device/asus.json index 4e3a0ef..e5fee47 100644 --- a/test/data/ua/device/asus.json +++ b/test/data/ua/device/asus.json @@ -151,5 +151,14 @@ "model": "Z00ED", "type": "mobile" } + }, + { + "desc": "ASUS ZenWatch", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; ASUS ZenWatch Build/LWX48S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/19.77.34.5 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZenWatch", + "type": "wearable" + } } ] \ No newline at end of file diff --git a/test/data/ua/device/lg.json b/test/data/ua/device/lg.json index f0312eb..b47e99f 100644 --- a/test/data/ua/device/lg.json +++ b/test/data/ua/device/lg.json @@ -160,5 +160,23 @@ "model": "LK430", "type": "tablet" } + }, + { + "desc": "LG Watch Urbane", + "ua": "Mozilla/5.0 Linux; Android 7.1.1; LG Watch Urbane Build/NWD1.180306.004 AppleWebKit/537.36 KHTML, like Gecko Chrome/19.77.34.5 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "Watch Urbane", + "type": "wearable" + } + }, + { + "desc": "LG G Watch R", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; G Watch R Build/LCA44B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Crosswalk/15.44.384.12 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "G Watch R", + "type": "wearable" + } } ] \ No newline at end of file diff --git a/test/data/ua/device/motorola.json b/test/data/ua/device/motorola.json index af6a4c8..b9227ba 100644 --- a/test/data/ua/device/motorola.json +++ b/test/data/ua/device/motorola.json @@ -79,5 +79,14 @@ "model": "Moto E (4)", "type": "mobile" } + }, + { + "desc": "Motorola Moto 360", + "ua": "Mozilla/5.0 (Linux; Android 4.4; Moto 360 Build/KNX01S) AppleWebKit/537.36 (KHTML, like Gecko) WIB/0.9.8 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Moto 360", + "type": "wearable" + } } ] \ No newline at end of file diff --git a/test/data/ua/device/oneplus.json b/test/data/ua/device/oneplus.json index 44407d4..74ddcf6 100644 --- a/test/data/ua/device/oneplus.json +++ b/test/data/ua/device/oneplus.json @@ -115,5 +115,14 @@ "model": "OPD2203", "type": "tablet" } + }, + { + "desc": "OnePlus Watch 2", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; OPWWE231 Build/TWR7.231113.001.OPWWE231_11_A.117.240703)", + "expect": { + "vendor": "OnePlus", + "model": "OPWWE231", + "type": "wearable" + } } ] \ No newline at end of file diff --git a/test/data/ua/device/oppo.json b/test/data/ua/device/oppo.json index 250909b..367039e 100644 --- a/test/data/ua/device/oppo.json +++ b/test/data/ua/device/oppo.json @@ -133,5 +133,41 @@ "model": "CPH1723", "type": "mobile" } + }, + { + "desc": "OPPO Watch 46mm", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; OW19W3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "OW19W3", + "type": "wearable" + } + }, + { + "desc": "OPPO Watch 41mm", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; OW19W2 Build/OPM1.171019.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "OW19W2", + "type": "wearable" + } + }, + { + "desc": "OPPO Watch 2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; OW20W1 Build/OPM1.171019.026.11_A.37.210713172937; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "OW20W1", + "type": "wearable" + } + }, + { + "desc": "OPPO Watch X", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; OWWE231 Build/TWR7.231113.001.OWWE231_11_A.117.240703)", + "expect": { + "vendor": "OPPO", + "model": "OWWE231", + "type": "wearable" + } } ] \ No newline at end of file diff --git a/test/data/ua/device/samsung.json b/test/data/ua/device/samsung.json index 0edb0f0..56e7b73 100644 --- a/test/data/ua/device/samsung.json +++ b/test/data/ua/device/samsung.json @@ -242,6 +242,15 @@ "type": "wearable" } }, + { + "desc": "Samsung Galaxy Watch7", + "ua": "Dalvik/2.1.0 (Linux; U; Android 14; SM-L300 Build/AW2E.240318.016)", + "expect": { + "vendor": "Samsung", + "model": "SM-L300", + "type": "wearable" + } + }, { "desc": "Samsung Note 10.1", "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-P605) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", @@ -367,5 +376,14 @@ "model": "SM-N920C", "type": "mobile" } + }, + { + "desc": "Samsung Galaxy Gear Live", + "ua": "Mozilla/5.0 (Linux; Android 4.4; Gear Live Build/KMV78X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/19.77.34.5 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "Gear Live", + "type": "wearable" + } } ] \ No newline at end of file diff --git a/test/data/ua/device/sony.json b/test/data/ua/device/sony.json index a4debe7..92151af 100644 --- a/test/data/ua/device/sony.json +++ b/test/data/ua/device/sony.json @@ -205,5 +205,14 @@ "model": "PlayStation Vita", "type": "console" } + }, + { + "desc": "Sony SmartWatch 3", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; SmartWatch 3 Build/LWX49K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/19.77.34.5 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SmartWatch 3", + "type": "wearable" + } } ] \ No newline at end of file From d4986af7c092ae0058a002209c70c1822cb5fecd Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 2 Dec 2024 10:42:09 +0700 Subject: [PATCH 29/73] Improve device detection for Xiaomi TVs --- src/main/ua-parser.js | 2 +- test/data/ua/device/xiaomi.json | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 87fac2a..0eefc30 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -755,7 +755,7 @@ ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[ /(bravia[\w ]+)( bui|\))/i // Sony ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ - /(mitv-\w{5}) bui/i // Xiaomi + /(mi(tv|box)-?\w+) bui/i // Xiaomi ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ /Hbbtv.*(technisat) (.*);/i // TechniSAT ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ diff --git a/test/data/ua/device/xiaomi.json b/test/data/ua/device/xiaomi.json index 22fe005..86593ef 100644 --- a/test/data/ua/device/xiaomi.json +++ b/test/data/ua/device/xiaomi.json @@ -547,5 +547,23 @@ "model": "MiTV-MOOQ0", "type": "smarttv" } + }, + { + "desc": "Xiaomi Mi TV", + "ua": "Mozilla/5.0 (Linux; Android 9; MiTV4I Build/PI; en-in) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36 Puffin/7.8.3.40913AP", + "expect": { + "vendor": "Xiaomi", + "model": "MiTV4I", + "type": "smarttv" + } + }, + { + "desc": "Xiaomi Mi Box", + "ua": "Mozilla/5.0 (Linux; Android 9; MIBOX3 Build/PI; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/119.0.6045.193 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MIBOX3", + "type": "smarttv" + } } ] \ No newline at end of file From d024fe20067fa09d8292d920ab0fd795be3b422a Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 3 Dec 2024 21:32:13 +0700 Subject: [PATCH 30/73] [extensions] Fix #770 - Add new fetcher bot: `Bluesky` --- src/extensions/ua-parser-extensions.js | 26 ++++++++++---------------- test/data/ua/extension/fetcher.json | 10 ++++++++++ test/unit/extensions.js | 9 +++++++++ 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 69ae56b..09b793c 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -218,31 +218,25 @@ const Fetchers = Object.freeze({ // ChatGPT-User - https://platform.openai.com/docs/plugins/bot // DuckAssistBot - https://duckduckgo.com/duckassistbot/ // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot - /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i, + // Google Site Verifier / Meta / Yahoo! Japan + // Yandex Bots - https://yandex.com/bots + /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, - // Google Site Verifier - /(google-site-verification)\/([\w\.]+)/i, - - // Meta - /(meta-externalfetcher)\/([\w\.]+)/i, + // Bluesky + /(bluesky) cardyb\/([\w\.]+)/i, // Slackbot - https://api.slack.com/robots /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i, // WhatsApp - /(whatsapp)\/([\w\.]+)[\/ ][ianw]/i, - - // Yahoo! Japan - /(y!?j-dlc)\/([\w\.]+)/i, - - // Yandex Bots - https://yandex.com/bots - /(yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, - /(yandex(?:sitelinks|userproxy))/i + /(whatsapp)\/([\w\.]+)[\/ ][ianw]/i ], [NAME, VERSION, [TYPE, FETCHER]], - // Google Bots / Cohere / Snapchat / Vercelbot - [/(cohere-ai|vercelbot|feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat)/i], + [ + // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots + /(cohere-ai|vercelbot|feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat|yandex(?:sitelinks|userproxy))/i + ], [NAME, [TYPE, FETCHER]], ] }); diff --git a/test/data/ua/extension/fetcher.json b/test/data/ua/extension/fetcher.json index dfd76f1..a04e4f6 100644 --- a/test/data/ua/extension/fetcher.json +++ b/test/data/ua/extension/fetcher.json @@ -19,6 +19,16 @@ "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", + "expect" : + { + "name" : "Bluesky", + "version" : "1.1", + "type" : "fetcher" + } + }, { "desc" : "ChatGPT-User", "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ChatGPT-User/1.0; +https://openai.com/bot", diff --git a/test/unit/extensions.js b/test/unit/extensions.js index 6fd755b..0f04732 100644 --- a/test/unit/extensions.js +++ b/test/unit/extensions.js @@ -48,6 +48,15 @@ describe('Extensions', () => { assert.deepEqual(libraryParser.setUA(axios).getBrowser(), {name: "axios", version: "1.3.5", major: "1", type: "library"}); assert.deepEqual(libraryParser.setUA(jsdom).getBrowser(), {name: "jsdom", version: "20.0.3", major: "20", type: "library"}); assert.deepEqual(libraryParser.setUA(scrapy).getBrowser(), {name: "Scrapy", version: "1.5.0", major: "1", type: "library"}); + + // Bluesky + const bluesky = 'Mozilla/5.0 (compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app)'; + assert.deepEqual(new UAParser(bluesky, Bots).getBrowser(), { + name: 'Bluesky', + version: '1.1', + major: '1', + type: 'fetcher' + }); }); describe('Merge', () => { From 592bfdd33c2c32a8b0a4786785863f2184287fe2 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 8 Dec 2024 21:52:05 +0700 Subject: [PATCH 31/73] Add new browser: `Ladybird` https://ladybird.org/ --- src/enums/ua-parser-enums.js | 1 + src/helpers/ua-parser-helpers.d.ts | 2 +- src/main/ua-parser.js | 53 +++++++++++++++++++-------- test/data/ua/browser/browser-all.json | 10 +++++ test/data/ua/engine/engine-all.json | 9 +++++ 5 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 42a1462..3cd5148 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -76,6 +76,7 @@ const Browser = Object.freeze({ KLARNA: 'Klarna', KINDLE: 'Kindle', LENOVO: 'Smart Lenovo Browser', + LADYBIRD: 'Ladybird', LIBREWOLF: 'LibreWolf', LIEBAO: 'LBBROWSER', LINE: 'Line', diff --git a/src/helpers/ua-parser-helpers.d.ts b/src/helpers/ua-parser-helpers.d.ts index 30a2c81..86bfad1 100644 --- a/src/helpers/ua-parser-helpers.d.ts +++ b/src/helpers/ua-parser-helpers.d.ts @@ -2,7 +2,7 @@ // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman -import { IResult } from "../main/ua-parser"; +import type { IResult } from "../main/ua-parser"; declare function getDeviceVendor(model: string): string | undefined; declare function isAppleSilicon(resultOrUA: IResult | string): boolean; diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 0eefc30..f7f2a64 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -19,20 +19,35 @@ // Constants ///////////// - var LIBVERSION = '2.0.0', + var LIBVERSION = '2.0.0', // UAParser.version + UA_MAX_LENGTH = 500, // UA string over this length will be trimmed + USER_AGENT = 'user-agent', EMPTY = '', UNKNOWN = '?', + + // typeof FUNC_TYPE = 'function', UNDEF_TYPE = 'undefined', OBJ_TYPE = 'object', STR_TYPE = 'string', - MAJOR = 'major', - MODEL = 'model', + + // properties + 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', + + // device types CONSOLE = 'console', MOBILE = 'mobile', TABLET = 'tablet', @@ -40,9 +55,11 @@ WEARABLE = 'wearable', XR = 'xr', EMBEDDED = 'embedded', + + // browser types INAPP = 'inapp', - USER_AGENT = 'user-agent', - UA_MAX_LENGTH = 500, + + // client hints BRANDS = 'brands', FORMFACTORS = 'formFactors', FULLVERLIST = 'fullVersionList', @@ -59,12 +76,8 @@ 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], - UA_BROWSER = 'browser', - UA_CPU = 'cpu', - UA_DEVICE = 'device', - UA_ENGINE = 'engine', - UA_OS = 'os', - UA_RESULT = 'result', + + // device vendors AMAZON = 'Amazon', APPLE = 'Apple', ASUS = 'ASUS', @@ -83,8 +96,8 @@ SONY = 'Sony', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', - PREFIX_MOBILE = 'Mobile ', - SUFFIX_BROWSER = ' Browser', + + // browsers CHROME = 'Chrome', CHROMIUM = 'Chromium', CHROMECAST = 'Chromecast', @@ -93,6 +106,11 @@ OPERA = 'Opera', FACEBOOK = 'Facebook', SOGOU = 'Sogou', + + PREFIX_MOBILE = 'Mobile ', + SUFFIX_BROWSER = ' Browser', + + // os WINDOWS = 'Windows'; var isWindow = typeof window !== UNDEF_TYPE, @@ -464,8 +482,8 @@ /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, - // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser + /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, + // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird /\b(links) \(([\w\.]+)/i // Links ], [NAME, [VERSION, /_/g, '.']], [ @@ -855,8 +873,11 @@ /ekioh(flow)\/([\w\.]+)/i, // Flow /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab - /\b(libweb)/i + + /\b(libweb)/i // LibWeb ], [NAME, VERSION], [ + /ladybird\//i + ], [[NAME, 'LibWeb']], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko ], [VERSION, NAME] diff --git a/test/data/ua/browser/browser-all.json b/test/data/ua/browser/browser-all.json index 8698597..45a8e07 100644 --- a/test/data/ua/browser/browser-all.json +++ b/test/data/ua/browser/browser-all.json @@ -1076,6 +1076,16 @@ "major" : "91" } }, + { + "desc" : "Ladybird", + "ua" : "Mozilla/5.0 (Linux; x86_64) Ladybird/1.0", + "expect" : + { + "name" : "Ladybird", + "version" : "1.0", + "major" : "1" + } + }, { "desc" : "LibreWolf", "ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0 LibreWolf/97.0.1", diff --git a/test/data/ua/engine/engine-all.json b/test/data/ua/engine/engine-all.json index 7523fc3..c686031 100644 --- a/test/data/ua/engine/engine-all.json +++ b/test/data/ua/engine/engine-all.json @@ -62,6 +62,15 @@ "version" : "4.5.4" } }, + { + "desc" : "LibWeb", + "ua" : "Mozilla/5.0 (Linux; x86_64) Ladybird/1.0", + "expect" : + { + "name" : "LibWeb", + "version" : "undefined" + } + }, { "desc" : "LibWeb", "ua" : "Mozilla/4.0 (SerenityOS; x86) LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb", From bb1daf4e132a3ffd73fbeae47aade5203bfcb3b3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 9 Dec 2024 09:49:58 +0700 Subject: [PATCH 32/73] Fix #771 - Provide alternative contribution channel for Alipay/WeChat users to support the open-source editions of UAParser.js --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cd77728..0ea5465 100644 --- a/README.md +++ b/README.md @@ -239,4 +239,13 @@ Made with [contributors-img](https://contrib.rocks). -Support the open-source editions of UAParser.js on [OpenCollective](https://opencollective.com/ua-parser-js) or [GitHub Sponsors](https://github.com/sponsors/faisalman). +You can support the open-source editions of UAParser.js through one of the following options: + +[![OpenCollective](https://img.shields.io/badge/OpenCollective-dddddd?style=for-the-badge&logo=opencollective&color=dddddd +)](https://opencollective.com/ua-parser-js) +[![GitHub Sponsors](https://img.shields.io/badge/GitHub_Sponsors-333333?style=for-the-badge&logo=githubsponsors&color=333333 +)](https://github.com/sponsors/faisalman) +[![PayPal](https://img.shields.io/badge/Paypal-003087?style=for-the-badge&logo=paypal&color=003087 +)](https://paypal.me/faisalman) +[![WeChat/Alipay](https://img.shields.io/badge/Other_Payment_Methods-Alipay_/_WeChat_Pay-09b83e?style=for-the-badge&logo=mastercard&color=09b83e +)](https://store.faisalman.com/buy/3d71f2f3-cf4d-473c-892a-9d4497c890be) \ No newline at end of file From f854f26cd6721029f3645b7b832c01b9de71405e Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 10 Dec 2024 03:23:01 -0800 Subject: [PATCH 33/73] feat: add TypeScript definitions for UAParser.js enums (#772) Introduce TypeScript type definitions for UAParser.js version 2.0.0. This enhances type safety and autocompletion for enums related to browsers, CPUs, devices, vendors, engines, and operating systems in the project. These changes are made to improve developer experience and ensure consistent usage of the enums throughout the codebase. --- src/enums/ua-parser-enums.d.ts | 363 +++++++++++++++++++++++++++++++++ src/enums/ua-parser-enums.mjs | 3 + 2 files changed, 366 insertions(+) create mode 100644 src/enums/ua-parser-enums.d.ts diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts new file mode 100644 index 0000000..efc7320 --- /dev/null +++ b/src/enums/ua-parser-enums.d.ts @@ -0,0 +1,363 @@ +// Type definitions for Enums submodule of UAParser.js v2.0.0 +// Project: https://github.com/faisalman/ua-parser-js +// Definitions by: Faisal Salman + +export const Browser: Readonly<{ + '115': "115"; + '2345': "2345"; + '360': "360"; + ALIPAY: "Alipay"; + AMAYA: "Amaya"; + ANDROID: "Android Browser"; + ARORA: "Arora"; + AVANT: "Avant"; + AVAST: "Avast Secure Browser"; + AVG: "AVG Secure Browser"; + BAIDU: "Baidu Browser"; + BASILISK: "Basilisk"; + BLAZER: "Blazer"; + BOLT: "Bolt"; + BOWSER: "Bowser"; + BRAVE: "Brave"; + CAMINO: "Camino"; + CHIMERA: "Chimera"; + CHROME: "Chrome"; + CHROME_HEADLESS: "Chrome Headless"; + CHROME_MOBILE: "Mobile Chrome"; + CHROME_WEBVIEW: "Chrome WebView"; + CHROMIUM: "Chromium"; + COBALT: "Cobalt"; + COC_COC: "Coc Coc"; + CONKEROR: "Conkeror"; + DILLO: "Dillo"; + DOLPHIN: "Dolphin"; + DORIS: "Doris"; + DRAGON: "Dragon"; + DUCKDUCKGO: "DuckDuckGo"; + EDGE: "Edge"; + EPIPHANY: "Epiphany"; + FACEBOOK: "Facebook"; + FALKON: "Falkon"; + FIREBIRD: "Firebird"; + FIREFOX: "Firefox"; + FIREFOX_FOCUS: "Firefox Focus"; + FIREFOX_MOBILE: "Mobile Firefox"; + FIREFOX_REALITY: "Firefox Reality"; + FENNEC: "Fennec"; + FLOCK: "Flock"; + FLOW: "Flow"; + GO: "GoBrowser"; + GOOGLE_SEARCH: "GSA"; + HELIO: "Helio"; + HEYTAP: "HeyTap"; + HONOR: "Honor"; + HUAWEI: "Huawei Browser"; + ICAB: "iCab"; + ICE: "ICE Browser"; + ICEAPE: "IceApe"; + ICECAT: "IceCat"; + ICEDRAGON: "IceDragon"; + ICEWEASEL: "IceWeasel"; + IE: "IE"; + INSTAGRAM: "Instagram"; + IRIDIUM: "Iridium"; + IRON: "Iron"; + JASMINE: "Jasmine"; + KONQUEROR: "Konqueror"; + KAKAO: "KakaoTalk"; + KHTML: "KHTML"; + K_MELEON: "K-Meleon"; + KLAR: "Klar"; + KLARNA: "Klarna"; + KINDLE: "Kindle"; + LENOVO: "Smart Lenovo Browser"; + LADYBIRD: "Ladybird"; + LIBREWOLF: "LibreWolf"; + LIEBAO: "LBBROWSER"; + LINE: "Line"; + LINKEDIN: "LinkedIn"; + LINKS: "Links"; + LUNASCAPE: "Lunascape"; + LYNX: "Lynx"; + MAEMO: "Maemo Browser"; + MAXTHON: "Maxthon"; + MIDORI: "Midori"; + MINIMO: "Minimo"; + MIUI: "MIUI Browser"; + MOZILLA: "Mozilla"; + MOSAIC: "Mosaic"; + NAVER: "Naver"; + NETFRONT: "NetFront"; + NETSCAPE: "Netscape"; + NETSURF: "Netsurf"; + NOKIA: "Nokia Browser"; + OBIGO: "Obigo"; + OCULUS: "Oculus Browser"; + OMNIWEB: "OmniWeb"; + OPERA: "Opera"; + OPERA_COAST: "Opera Coast"; + OPERA_MINI: "Opera Mini"; + OPERA_MOBI: "Opera Mobi"; + OPERA_TABLET: "Opera Tablet"; + OPERA_TOUCH: "Opera Touch"; + OVI: "OviBrowser"; + PALEMOON: "PaleMoon"; + PHANTOMJS: "PhantomJS"; + PHOENIX: "Phoenix"; + PICOBROWSER: "Pico Browser"; + POLARIS: "Polaris"; + PUFFIN: "Puffin"; + QQ: "QQBrowser"; + QQ_LITE: "QQBrowserLite"; + QUARK: "Quark"; + QUPZILLA: "QupZilla"; + REKONQ: "rekonq"; + ROCKMELT: "Rockmelt"; + SAFARI: "Safari"; + SAFARI_MOBILE: "Mobile Safari"; + SAILFISH: "Sailfish Browser"; + SAMSUNG: "Samsung Internet"; + SEAMONKEY: "SeaMonkey"; + SILK: "Silk"; + SKYFIRE: "Skyfire"; + SLEIPNIR: "Sleipnir"; + SLIMBOAT: "SlimBoat"; + SLIMBROWSER: "SlimBrowser"; + SLIMJET: "Slimjet"; + SNAPCHAT: "Snapchat"; + SOGOU_EXPLORER: "Sogou Explorer"; + SOGOU_MOBILE: "Sogou Mobile"; + SWIFTFOX: "Swiftfox"; + TESLA: "Tesla"; + TIKTOK: "TikTok"; + TIZEN: "Tizen Browser"; + TWITTER: "Twitter"; + UC: "UCBrowser"; + UP: "UP.Browser"; + VIVALDI: "Vivaldi"; + VIVO: "Vivo Browser"; + W3M: "w3m"; + WATERFOX: "Waterfox"; + WEBKIT: "WebKit"; + WECHAT: "WeChat"; + WEIBO: "Weibo"; + WHALE: "Whale"; + WOLVIC: "Wolvic"; + YANDEX: "Yandex"; +}>; +export const BrowserType: Readonly<{ + CRAWLER: "crawler"; + CLI: "cli"; + EMAIL: "email"; + FETCHER: "fetcher"; + INAPP: "inapp"; + MEDIAPLAYER: "mediaplayer"; + LIBRARY: "library"; +}>; +export const CPU: Readonly<{ + '68K': "68k"; + ARM: "arm"; + ARM_64: "arm64"; + ARM_HF: "armhf"; + AVR: "avr"; + AVR_32: "avr32"; + IA64: "ia64"; + IRIX: "irix"; + IRIX_64: "irix64"; + MIPS: "mips"; + MIPS_64: "mips64"; + PA_RISC: "pa-risc"; + PPC: "ppc"; + SPARC: "sparc"; + SPARC_64: "sparc64"; + X86: "ia32"; + X86_64: "amd64"; +}>; +export const Device: Readonly<{ + CONSOLE: "console"; + DESKTOP: "desktop"; + EMBEDDED: "embedded"; + MOBILE: "mobile"; + SMARTTV: "smarttv"; + TABLET: "tablet"; + WEARABLE: "wearable"; + XR: "xr"; +}>; +export const Vendor: Readonly<{ + ACER: "Acer"; + ADVAN: "Advan"; + ALCATEL: "Alcatel"; + APPLE: "Apple"; + AMAZON: "Amazon"; + ARCHOS: "Archos"; + ASUS: "ASUS"; + ATT: "AT&T"; + BENQ: "BenQ"; + BLACKBERRY: "BlackBerry"; + CAT: "Cat"; + DELL: "Dell"; + ENERGIZER: "Energizer"; + ESSENTIAL: "Essential"; + FACEBOOK: "Facebook"; + FAIRPHONE: "Fairphone"; + GEEKSPHONE: "GeeksPhone"; + GENERIC: "Generic"; + GOOGLE: "Google"; + HMD: "HMD"; + HP: "HP"; + HTC: "HTC"; + HUAWEI: "Huawei"; + IMO: "IMO"; + INFINIX: "Infinix"; + ITEL: "itel"; + JOLLA: "Jolla"; + KOBO: "Kobo"; + LENOVO: "Lenovo"; + LG: "LG"; + MEIZU: "Meizu"; + MICROMAX: "Micromax"; + MICROSOFT: "Microsoft"; + MOTOROLA: "Motorola"; + NEXIAN: "Nexian"; + NINTENDO: "Nintendo"; + NOKIA: "Nokia"; + NOTHING: "Nothing"; + NVIDIA: "Nvidia"; + ONEPLUS: "OnePlus"; + OPPO: "OPPO"; + OUYA: "Ouya"; + PALM: "Palm"; + PANASONIC: "Panasonic"; + PEBBLE: "Pebble"; + PICO: "Pico"; + POLYTRON: "Polytron"; + REALME: "Realme"; + RIM: "RIM"; + ROKU: "Roku"; + SAMSUNG: "Samsung"; + SHARP: "Sharp"; + SIEMENS: "Siemens"; + SMARTFREN: "Smartfren"; + SONY: "Sony"; + SPRINT: "Sprint"; + TCL: "TCL"; + TECHNISAT: "TechniSAT"; + TECNO: "Tecno"; + TESLA: "Tesla"; + ULEFONE: "Ulefone"; + VIVO: "Vivo"; + VODAFONE: "Vodafone"; + XBOX: "Xbox"; + XIAOMI: "Xiaomi"; + ZEBRA: "Zebra"; + ZTE: "ZTE"; +}>; +export const Engine: Readonly<{ + AMAYA: "Amaya"; + ARKWEB: "ArkWeb"; + BLINK: "Blink"; + EDGEHTML: "EdgeHTML"; + FLOW: "Flow"; + GECKO: "Gecko"; + GOANNA: "Goanna"; + ICAB: "iCab"; + KHTML: "KHTML"; + LIBWEB: "LibWeb"; + LINKS: "Links"; + LYNX: "Lynx"; + NETFRONT: "NetFront"; + NETSURF: "NetSurf"; + PRESTO: "Presto"; + SERVO: "Servo"; + TASMAN: "Tasman"; + TRIDENT: "Trident"; + W3M: "w3m"; + WEBKIT: "WebKit"; +}>; +export const OS: Readonly<{ + AIX: "AIX"; + AMIGA_OS: "Amiga OS"; + ANDROID: "Android"; + ANDROID_X86: "Android-x86"; + ARCH: "Arch"; + BADA: "Bada"; + BEOS: "BeOS"; + BLACKBERRY: "BlackBerry"; + CENTOS: "CentOS"; + CHROME_OS: "Chrome OS"; + CHROMECAST: "Chromecast"; + CHROMECAST_ANDROID: "Chromecast Android"; + CHROMECAST_FUCHSIA: "Chromecast Fuchsia"; + CHROMECAST_LINUX: "Chromecast Linux"; + CHROMECAST_SMARTSPEAKER: "Chromecast SmartSpeaker"; + CONTIKI: "Contiki"; + DEBIAN: "Debian"; + DEEPIN: "Deepin"; + DRAGONFLY: "DragonFly"; + ELEMENTARY_OS: "elementary OS"; + FEDORA: "Fedora"; + FIREFOX_OS: "Firefox OS"; + FREEBSD: "FreeBSD"; + FUCHSIA: "Fuchsia"; + GENTOO: "Gentoo"; + GHOSTBSD: "GhostBSD"; + GNU: "GNU"; + HAIKU: "Haiku"; + HARMONYOS: "HarmonyOS"; + HP_UX: "HP-UX"; + HURD: "Hurd"; + IOS: "iOS"; + JOLI: "Joli"; + KAIOS: "KaiOS"; + KUBUNTU: "Kubuntu"; + LINPUS: "Linpus"; + LINSPIRE: "Linspire"; + LINUX: "Linux"; + MACOS: "macOS"; + MAEMO: "Maemo"; + MAGEIA: "Mageia"; + MANDRIVA: "Mandriva"; + MANJARO: "Manjaro"; + MEEGO: "MeeGo"; + MINIX: "Minix"; + MINT: "Mint"; + MORPH_OS: "Morph OS"; + NETBSD: "NetBSD"; + NETRANGE: "NetRange"; + NETTV: "NetTV"; + NINTENDO: "Nintendo"; + OPENHARMONY: "OpenHarmony"; + OPENBSD: "OpenBSD"; + OPENVMS: "OpenVMS"; + OS2: "OS/2"; + PALM: "Palm"; + PC_BSD: "PC-BSD"; + PCLINUXOS: "PCLinuxOS"; + PICO: "Pico"; + PLAN9: "Plan9"; + PLAYSTATION: "PlayStation"; + QNX: "QNX"; + RASPBIAN: "Raspbian"; + REDHAT: "RedHat"; + RIM_TABLET_OS: "RIM Tablet OS"; + RISC_OS: "RISC OS"; + SABAYON: "Sabayon"; + SAILFISH: "Sailfish"; + SERENITYOS: "SerenityOS"; + SERIES40: "Series40"; + SLACKWARE: "Slackware"; + SOLARIS: "Solaris"; + SUSE: "SUSE"; + SYMBIAN: "Symbian"; + TIZEN: "Tizen"; + UBUNTU: "Ubuntu"; + UNIX: "Unix"; + VECTORLINUX: "VectorLinux"; + WATCHOS: "watchOS"; + WEBOS: "WebOS"; + WINDOWS: "Windows"; + WINDOWS_MOBILE: "Windows Mobile"; + WINDOWS_PHONE: "Windows Phone"; + XBOX: "Xbox"; + ZENWALK: "Zenwalk"; +}>; diff --git a/src/enums/ua-parser-enums.mjs b/src/enums/ua-parser-enums.mjs index c9a2f0f..276b8a2 100644 --- a/src/enums/ua-parser-enums.mjs +++ b/src/enums/ua-parser-enums.mjs @@ -80,6 +80,7 @@ const Browser = Object.freeze({ KLARNA: 'Klarna', KINDLE: 'Kindle', LENOVO: 'Smart Lenovo Browser', + LADYBIRD: 'Ladybird', LIBREWOLF: 'LibreWolf', LIEBAO: 'LBBROWSER', LINE: 'Line', @@ -217,6 +218,7 @@ const Vendor = Object.freeze({ GEEKSPHONE: 'GeeksPhone', GENERIC: 'Generic', GOOGLE: 'Google', + HMD: 'HMD', HP: 'HP', HTC: 'HTC', HUAWEI: 'Huawei', @@ -326,6 +328,7 @@ const OS = Object.freeze({ IOS: 'iOS', JOLI: 'Joli', KAIOS: 'KaiOS', + KUBUNTU: 'Kubuntu', LINPUS: 'Linpus', LINSPIRE: 'Linspire', LINUX: 'Linux', From 84b41f5be77334d46f76c55ec505acc5383c48c7 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 12 Dec 2024 06:29:35 +0700 Subject: [PATCH 34/73] Add new OS: `Windows IoT` --- src/enums/ua-parser-enums.d.ts | 1 + src/enums/ua-parser-enums.js | 1 + src/main/ua-parser.js | 8 +++++--- test/data/ua/device/_others.json | 9 +++++++++ test/data/ua/os/windows.json | 9 +++++++++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts index efc7320..5c406c3 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -356,6 +356,7 @@ export const OS: Readonly<{ WATCHOS: "watchOS"; WEBOS: "WebOS"; WINDOWS: "Windows"; + WINDOWS_IOT: "Windows IoT"; WINDOWS_MOBILE: "Windows Mobile"; WINDOWS_PHONE: "Windows Phone"; XBOX: "Xbox"; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 3cd5148..08a7afc 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -371,6 +371,7 @@ const OS = Object.freeze({ WATCHOS: 'watchOS', WEBOS: 'WebOS', WINDOWS: 'Windows', + WINDOWS_IOT: 'Windows IoT', WINDOWS_MOBILE: 'Windows Mobile', WINDOWS_PHONE: 'Windows Phone', XBOX: 'Xbox', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index f7f2a64..7dbe7dc 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -840,6 +840,8 @@ ], [VENDOR, [TYPE, EMBEDDED]], [ /(aeobc)\b/i // Echo Dot ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [ + /windows iot/i + ], [[TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) @@ -888,10 +890,10 @@ // Windows /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ - /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone + /(windows (?:phone(?: os)?|mobile|iot))[\/ ]?([\d\.\w ]*)/i // Windows Phone ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ - /windows nt 6\.2; (arm)/i, // Windows RT - /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i, + /windows nt 6\.2; (arm)/i, // Windows RT + /windows[\/ ]([ntce\d\. ]+\w)(?!.+xbox)/i, /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [ diff --git a/test/data/ua/device/_others.json b/test/data/ua/device/_others.json index 7ee9ec6..b830065 100644 --- a/test/data/ua/device/_others.json +++ b/test/data/ua/device/_others.json @@ -246,5 +246,14 @@ "model": "undefined", "type": "mobile" } + }, + { + "desc" : "Windows IoT", + "ua" : "Mozilla/5.0 (Windows IoT 10.0; Android 6.0.1; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Mobile Safari/537.36 Edge/18.17763", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "embedded" + } } ] \ No newline at end of file diff --git a/test/data/ua/os/windows.json b/test/data/ua/os/windows.json index 39e9541..7e12282 100644 --- a/test/data/ua/os/windows.json +++ b/test/data/ua/os/windows.json @@ -116,6 +116,15 @@ "version" : "CE" } }, + { + "desc" : "Windows IoT", + "ua" : "Mozilla/5.0 (Windows IoT 10.0; Android 6.0.1; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Mobile Safari/537.36 Edge/18.17763", + "expect" : + { + "name" : "Windows IoT", + "version" : "10.0" + } + }, { "desc" : "Windows NT on x86 or aarch64 CPU using Firefox", "ua" : "Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0", From 5d603dacd7fc065ee5e47471e180a164961c81fa Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 12 Dec 2024 07:29:56 +0700 Subject: [PATCH 35/73] Add new device: Apple HomePod --- src/main/ua-parser.js | 4 +++- test/data/ua/device/apple.json | 9 +++++++++ test/data/ua/os/ios.json | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 7dbe7dc..0fa08b9 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -840,6 +840,8 @@ ], [VENDOR, [TYPE, EMBEDDED]], [ /(aeobc)\b/i // Echo Dot ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [ + /(homepod).+mac os/i // Apple HomePod + ], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [ /windows iot/i ], [[TYPE, EMBEDDED]], [ @@ -898,7 +900,7 @@ ], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [ // iOS/macOS - /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS + /[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i, /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ diff --git a/test/data/ua/device/apple.json b/test/data/ua/device/apple.json index 4de5728..ea68e8a 100644 --- a/test/data/ua/device/apple.json +++ b/test/data/ua/device/apple.json @@ -116,6 +116,15 @@ "type": "mobile" } }, + { + "desc": "Apple HomePod", + "ua": "AppleCoreMedia/1.0.0.15D61 (HomePod; U; CPU OS 11_2_5 like Mac OS X; en_us)", + "expect": { + "vendor": "Apple", + "model": "HomePod", + "type": "embedded" + } + }, { "desc": "Issue #519", "ua": "ios/iPhone/14.2/SOME_CUSTOM_APP_VERSION", diff --git a/test/data/ua/os/ios.json b/test/data/ua/os/ios.json index 66cff1e..86ba8cb 100644 --- a/test/data/ua/os/ios.json +++ b/test/data/ua/os/ios.json @@ -52,5 +52,14 @@ "name" : "iOS", "version" : "7.0.2" } + }, + { + "desc": "Apple HomePod", + "ua": "AppleCoreMedia/1.0.0.15D61 (HomePod; U; CPU OS 11_2_5 like Mac OS X; en_us)", + "expect" : + { + "name" : "iOS", + "version" : "11.2.5" + } } ] \ No newline at end of file From 594b6b1399c307412ab3eeeb23dca4ac31464205 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 12 Dec 2024 14:43:19 +0700 Subject: [PATCH 36/73] Add new OS: `Ubuntu Touch` --- src/enums/ua-parser-enums.d.ts | 1 + src/enums/ua-parser-enums.js | 1 + src/main/ua-parser.js | 5 ++++- test/data/ua/os/ubuntu-touch.json | 11 +++++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 test/data/ua/os/ubuntu-touch.json diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts index 5c406c3..f8cca69 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -351,6 +351,7 @@ export const OS: Readonly<{ SYMBIAN: "Symbian"; TIZEN: "Tizen"; UBUNTU: "Ubuntu"; + UBUNTU_TOUCH: "Ubuntu Touch", UNIX: "Unix"; VECTORLINUX: "VectorLinux"; WATCHOS: "watchOS"; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 08a7afc..67a5447 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -366,6 +366,7 @@ const OS = Object.freeze({ SYMBIAN: 'Symbian', TIZEN: 'Tizen', UBUNTU: 'Ubuntu', + UBUNTU_TOUCH: 'Ubuntu Touch', UNIX: 'Unix', VECTORLINUX: 'VectorLinux', WATCHOS: 'watchOS', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 0fa08b9..620c4b0 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -922,7 +922,10 @@ // Mobile OSes /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS - ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony + ], [VERSION, NAME], [ + /(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch + ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [ + // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS diff --git a/test/data/ua/os/ubuntu-touch.json b/test/data/ua/os/ubuntu-touch.json new file mode 100644 index 0000000..e0aea5f --- /dev/null +++ b/test/data/ua/os/ubuntu-touch.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Ubuntu Touch", + "ua" : "Mozilla/5.0 (Linux; Ubuntu 16.04 like Android 4.4) AppleWebKit/537.36 Chromium/65.0.3325.151 Mobile Safari/537.36", + "expect" : + { + "name" : "Ubuntu Touch", + "version" : "16.04" + } + } +] \ No newline at end of file From 46019533264629ac7c945862f49887af1c4726d1 Mon Sep 17 00:00:00 2001 From: Hyewon Kang Date: Thu, 12 Dec 2024 21:22:28 +0900 Subject: [PATCH 37/73] Add Daum app user agent (#773) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Daum app user agent --------- Co-authored-by: helen.one(강혜원)/kakao --- src/enums/ua-parser-enums.d.ts | 1 + src/enums/ua-parser-enums.js | 1 + src/main/ua-parser.js | 1 + test/data/ua/browser/browser-all.json | 20 ++++++++++++++++++++ 4 files changed, 23 insertions(+) diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts index f8cca69..db4ffa6 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -29,6 +29,7 @@ export const Browser: Readonly<{ COBALT: "Cobalt"; COC_COC: "Coc Coc"; CONKEROR: "Conkeror"; + DAUM: "Daum"; DILLO: "Dillo"; DOLPHIN: "Dolphin"; DORIS: "Doris"; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 67a5447..9e8dbe0 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -34,6 +34,7 @@ const Browser = Object.freeze({ COBALT: 'Cobalt', COC_COC: 'Coc Coc', CONKEROR: 'Conkeror', + DAUM: 'Daum', DILLO: 'Dillo', DOLPHIN: 'Dolphin', DORIS: 'Doris', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 620c4b0..0fc6214 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -420,6 +420,7 @@ /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp + /(daum)apps[\/ ]([\w\.]+)/i, // Daum App /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(alipay)client\/([\w\.]+)/i, // Alipay diff --git a/test/data/ua/browser/browser-all.json b/test/data/ua/browser/browser-all.json index 45a8e07..05dfd4f 100644 --- a/test/data/ua/browser/browser-all.json +++ b/test/data/ua/browser/browser-all.json @@ -2503,6 +2503,26 @@ "type" : "inapp" } }, + { + "desc" : "Daum App Android", + "ua" : "Mozilla/5.0 (Linux; Android 11; SM-G970N Build/RP1A.200720.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36 DaumApps/7.5.0 DaumDevice/mobile", + "expect" : { + "name" : "Daum", + "version": "7.5.0", + "major" : "7", + "type" : "inapp" + } + }, + { + "desc" : "Daum App iOS", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Safari/605.1.15 Mobile/15E148 DaumApps/7.5.1 DaumDevice/mobile", + "expect" : { + "name" : "Daum", + "version": "7.5.1", + "major" : "7", + "type" : "inapp" + } + }, { "desc" : "TikTok", "ua" : "Mozilla/5.0 (Linux; Android 11; 21061119AG Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile Safari/537.36 trill_2022109040 JsSdk/1.0 NetType/MOBILE Channel/googleplay AppName/musical_ly app_version/21.9.4 ByteLocale/ru-RU ByteFullLocale/ru-RU Region/KG BytedanceWebview/d8a21c6", From de871b3d37f5022d20b688996c0b8c6051a46812 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 12 Dec 2024 19:04:03 +0700 Subject: [PATCH 38/73] [test] Move test file for Windows IoT --- test/data/ua/os/windows-iot.json | 11 +++++++++++ test/data/ua/os/windows.json | 9 --------- 2 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 test/data/ua/os/windows-iot.json diff --git a/test/data/ua/os/windows-iot.json b/test/data/ua/os/windows-iot.json new file mode 100644 index 0000000..ff1d02c --- /dev/null +++ b/test/data/ua/os/windows-iot.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Windows IoT", + "ua" : "Mozilla/5.0 (Windows IoT 10.0; Android 6.0.1; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Mobile Safari/537.36 Edge/18.17763", + "expect" : + { + "name" : "Windows IoT", + "version" : "10.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/windows.json b/test/data/ua/os/windows.json index 7e12282..39e9541 100644 --- a/test/data/ua/os/windows.json +++ b/test/data/ua/os/windows.json @@ -116,15 +116,6 @@ "version" : "CE" } }, - { - "desc" : "Windows IoT", - "ua" : "Mozilla/5.0 (Windows IoT 10.0; Android 6.0.1; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Mobile Safari/537.36 Edge/18.17763", - "expect" : - { - "name" : "Windows IoT", - "version" : "10.0" - } - }, { "desc" : "Windows NT on x86 or aarch64 CPU using Firefox", "ua" : "Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0", From 9cdf560e60c62ccd968b03bfe95b05b696a0a114 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 12 Dec 2024 20:01:58 +0700 Subject: [PATCH 39/73] Improve detection for Nvidia devices --- src/main/ua-parser.js | 11 ++++++---- test/data/ua/device/nvidia.json | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 0fc6214..5981dea 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -89,6 +89,7 @@ LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', + NVIDIA = 'Nvidia', ONEPLUS = 'OnePlus', OPPO = 'OPPO', SAMSUNG = 'Samsung', @@ -736,8 +737,8 @@ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ - /(shield[\w ]+) b/i // Nvidia Shield Tablets - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ + /((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i // Nvidia Tablets + ], [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]], [ /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin @@ -769,6 +770,8 @@ ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ /droid.+aft(\w+)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ + /(shield \w+ tv)/i // Nvidia Shield TV + ], [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i, /(aquos-tv[\w ]+)\)/i // Sharp ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[ @@ -791,8 +794,8 @@ /(ouya)/i, // Ouya /(nintendo) (\w+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ - /droid.+; (shield) bui/i // Nvidia - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ + /droid.+; (shield)( bui|\))/i // Nvidia Portable + ], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [ /(playstation \w+)/i // Playstation ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox diff --git a/test/data/ua/device/nvidia.json b/test/data/ua/device/nvidia.json index a78316e..96a2afc 100644 --- a/test/data/ua/device/nvidia.json +++ b/test/data/ua/device/nvidia.json @@ -1,4 +1,22 @@ [ + { + "desc": "Tegra Note 7", + "ua": "Mozilla/5.0 (Linux; Android 5.1; TegraNote-P1640 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "TegraNote-P1640", + "type": "tablet" + } + }, + { + "desc": "Nvidia Shield", + "ua": "Mozilla/5.0 (Linux; Android 5.1; SHIELD) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD", + "type": "console" + } + }, { "desc": "Nvidia Shield Tablet", "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SHIELD Tablet Build/LVY48E; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.19 Safari/537.36", @@ -7,5 +25,23 @@ "model": "SHIELD Tablet", "type": "tablet" } + }, + { + "desc": "Nvidia Shield Tablet K1", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SHIELD Tablet K1 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD Tablet K1", + "type": "tablet" + } + }, + { + "desc": "Nvidia Shield TV", + "ua": "Mozilla/5.0 (Linux; Android 11; SHIELD Android TV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36 ", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD Android TV", + "type": "smarttv" + } } ] \ No newline at end of file From 13d069f1c46ffb7edfeaa32d1e55b361350e9ed2 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 12 Dec 2024 22:12:43 +0700 Subject: [PATCH 40/73] Improve device detection for unidentified SmartTV vendors --- src/main/ua-parser.js | 5 ++++- test/data/ua/device/_others.json | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 5981dea..494dcbe 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -784,7 +784,10 @@ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors + // SmartTV from Unidentified Vendors + /droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i + ], [MODEL, [TYPE, SMARTTV]], [ + /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i ], [[TYPE, SMARTTV]], [ /////////////////// diff --git a/test/data/ua/device/_others.json b/test/data/ua/device/_others.json index b830065..b2bb7f1 100644 --- a/test/data/ua/device/_others.json +++ b/test/data/ua/device/_others.json @@ -34,6 +34,33 @@ "type": "mobile" } }, + { + "desc": "ChangHong Android TV", + "ua": "Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; ChangHong Android TV Build/LMY49J) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/10.8 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "ChangHong", + "type": "smarttv" + } + }, + { + "desc": "MStar Android TV", + "ua": "Mozilla/5.0 (Linux; Android 4.3.1; MStar Android TV Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.95 Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "MStar", + "type": "smarttv" + } + }, + { + "desc": "ONIDA Android TV", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ONIDA Android TV Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/48.0.2542.0 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "ONIDA", + "type": "smarttv" + } + }, { "desc": "JVC LT-43V55LFA Smart TV", "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB211 VSTVB MB200 HbbTV/1.2.1 (; JVC; MB211; 3.19.4.2; _TV_NT72563_2017 SmartTvA/3.0.0", From 93552e0172459487f24bb0307e0e64ec5ce58cd6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 14 Dec 2024 21:16:32 +0700 Subject: [PATCH 41/73] Improve CPU detection: ARM --- src/main/ua-parser.js | 16 ++++++++-------- test/data/ua/cpu/cpu-all.json | 8 ++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 494dcbe..0296329 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -495,30 +495,30 @@ cpu : [[ - /\b(?:(amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64) + /\b((amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64) ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i, // IA32 (quicktime) - /\b((?:i[346]|x)86)\b/i // IA32 (x86) + /\b((i[346]|x)86)\b/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ - /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 + /\b(aarch64|arm(v?[89]e?l?|_?64))\b/i // ARM64 ], [[ARCHITECTURE, 'arm64']], [ - /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF + /\b(arm(v[67])?ht?n?[fl]p?)\b/i // ARMHF ], [[ARCHITECTURE, 'armhf']], [ // PocketPC mistakenly identified as PowerPC - /windows (ce|mobile); ppc;/i + /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i ], [[ARCHITECTURE, 'arm']], [ - /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC + /((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ - /(sun4\w)[;\)]/i // SPARC + / sun4\w[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i + /\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]] ], diff --git a/test/data/ua/cpu/cpu-all.json b/test/data/ua/cpu/cpu-all.json index d43fbc0..5607eaf 100644 --- a/test/data/ua/cpu/cpu-all.json +++ b/test/data/ua/cpu/cpu-all.json @@ -175,6 +175,14 @@ "architecture" : "arm64" } }, + { + "desc" : "Google Search App", + "ua" : "Mozilla/5.0 (Linux; Android 9; JAT-LX1 Build/HONORJAT-LX1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.96 Mobile Safari/537.36 GoogleApp/11.11.10.21.arm", + "expect" : + { + "architecture" : "arm" + } + }, { "desc" : "Google Search App", "ua" : "Mozilla/5.0 (Linux; Android 6.0; M5s Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.147 Mobile Safari/537.36 GSA/12.40.17.23.arm64", From 6c6ff97e0cdff8930cdd09c51667855a4272c1d9 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 16 Dec 2024 11:05:24 +0700 Subject: [PATCH 42/73] Improve device detection for Generic device: capture its device model instead of its Android version --- src/main/ua-parser.js | 6 +++--- test/data/ua/device/_others.json | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 0296329..73778c4 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -19,8 +19,8 @@ // Constants ///////////// - var LIBVERSION = '2.0.0', // UAParser.version - UA_MAX_LENGTH = 500, // UA string over this length will be trimmed + var LIBVERSION = '2.0.0', + UA_MAX_LENGTH = 500, USER_AGENT = 'user-agent', EMPTY = '', UNKNOWN = '?', @@ -864,7 +864,7 @@ ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ - /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device + /droid .+?; ([\w\. -]+)( bui|\))/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] ], diff --git a/test/data/ua/device/_others.json b/test/data/ua/device/_others.json index b2bb7f1..53818da 100644 --- a/test/data/ua/device/_others.json +++ b/test/data/ua/device/_others.json @@ -1,10 +1,18 @@ [ + { + "desc": "Generic Android Device", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; X96mini_RP Build/X96mini_RP)", + "expect": { + "vendor": "Generic", + "model": "X96mini_RP" + } + }, { "desc": "Generic Android Device", "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)", "expect": { "vendor": "Generic", - "model": "Android 6.0.1" + "model": "i980" } }, { From 852520fafe12d5df84811f9936e70de2be5bad88 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 16 Dec 2024 23:41:19 +0700 Subject: [PATCH 43/73] Also provide minified .mjs files of main module in /dist --- dist/ua-parser.min.mjs | 4 ++++ dist/ua-parser.pack.mjs | 4 ++++ package-lock.json | 8 ++++---- package.json | 2 +- script/build-dist.sh | 12 +++++++++++- 5 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 dist/ua-parser.min.mjs create mode 100644 dist/ua-parser.pack.mjs diff --git a/dist/ua-parser.min.mjs b/dist/ua-parser.min.mjs new file mode 100644 index 0000000..8c8fd19 --- /dev/null +++ b/dist/ua-parser.min.mjs @@ -0,0 +1,4 @@ +/* UAParser.js v2.0.0 + Copyright © 2012-2024 Faisal Salman + AGPLv3 License */ +var LIBVERSION="2.0.0",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",SPACE=" ",HYPHEN="-",UNKNOWN="?",RGX_LOWDASH=/_/g,FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",BROWSER="browser",CPU="cpu",DEVICE="device",ENGINE="engine",OS="os",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=PLATFORM+"Version",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+HYPHEN+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+HYPHEN+MOBILE,CH_HEADER_MODEL=CH_HEADER+HYPHEN+MODEL,CH_HEADER_PLATFORM=CH_HEADER+HYPHEN+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=CHROME+"cast",EDGE="Edge",FIREFOX="Firefox",HEADLESS="Headless",OPERA="Opera",FACEBOOK="Facebook",SAFARI="Safari",SOGOU="Sogou",WEBVIEW="WebView",ARM="arm",ANDROID="Android",WINDOWS="Windows",Browser="Browser",Mobile="Mobile",Tablet="Tablet",SMART="Smart",PREFIX_MOBILE=Mobile+SPACE,SUFFIX_BROWSER=SPACE+Browser;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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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=stripQuotes(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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(BROWSER,detect(BROWSER)).set(CPU,detect(CPU)).set(DEVICE,detect(DEVICE)).set(ENGINE,detect(ENGINE)).set(OS,detect(OS))}}return this};this.parseUA=function(){if(this.itemType!=RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case BROWSER:case ENGINE:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:GOOGLE+SPACE+CHROME,Edge:MICROSOFT+SPACE+EDGE,"Chrome WebView":ANDROID+SPACE+WEBVIEW,"Chrome Headless":HEADLESS+CHROME});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,ANDROID+" 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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 RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(BROWSER,parse(BROWSER)).set(CPU,parse(CPU)).set(DEVICE,parse(DEVICE)).set(ENGINE,parse(ENGINE)).set(OS,parse(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==RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(BROWSER,this.getBrowser()).set(CPU,this.getCPU()).set(DEVICE,this.getDevice()).set(ENGINE,this.getEngine()).set(OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(BROWSER)],["getCPU",createItemFunc(CPU)],["getDevice",createItemFunc(DEVICE)],["getEngine",createItemFunc(ENGINE)],["getOS",createItemFunc(OS)],["getResult",createItemFunc(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.mjs b/dist/ua-parser.pack.mjs new file mode 100644 index 0000000..2891557 --- /dev/null +++ b/dist/ua-parser.pack.mjs @@ -0,0 +1,4 @@ +/* UAParser.js v2.0.0 + Copyright © 2012-2024 Faisal Salman + AGPLv3 License */ +function U(i){for(var e={},t=0;t{var t,o={},r=e;if(!Hi(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})(Vi,e):Vi,P.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Ni(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 Ni(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 ji(i)&&(r=i.length>M?Ui(i,M):i),this}]]).setUA(r),this):new E(i,e,t).getResult()}E.VERSION="2.0.0",E.BROWSER=U([v,y,B,k]),E.CPU=U([C]),E.DEVICE=U([S,x,k,G,_,t,r,o,D]),E.ENGINE=E.OS=U([v,y]);export{E as UAParser}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b602a64..118888a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "requirejs": "2.3.2", "safe-regex": "^2.1.1", "tsd": "^0.29.0", - "uglify-js": "~3.12.0" + "uglify-js": "~3.19.3" }, "engines": { "node": "*" @@ -4265,9 +4265,9 @@ ] }, "node_modules/uglify-js": { - "version": "3.12.8", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz", - "integrity": "sha512-fvBeuXOsvqjecUtF/l1dwsrrf5y2BCUk9AOJGzGcm6tE7vegku5u/YvqjyDaAGr422PLoLnrxg3EnRvTqsdC1w==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, "bin": { "uglifyjs": "bin/uglifyjs" diff --git a/package.json b/package.json index 76c9288..ca3208a 100755 --- a/package.json +++ b/package.json @@ -229,7 +229,7 @@ "requirejs": "2.3.2", "safe-regex": "^2.1.1", "tsd": "^0.29.0", - "uglify-js": "~3.12.0" + "uglify-js": "~3.19.3" }, "repository": { "type": "git", diff --git a/script/build-dist.sh b/script/build-dist.sh index 884f4b4..0648a12 100755 --- a/script/build-dist.sh +++ b/script/build-dist.sh @@ -4,10 +4,20 @@ SRC_PATH="src/main/ua-parser.js" MIN_PATH="dist/ua-parser.min.js" PACK_PATH="dist/ua-parser.pack.js" +SRC_PATH_MJS="src/main/ua-parser.mjs" +MIN_PATH_MJS="dist/ua-parser.min.mjs" +PACK_PATH_MJS="dist/ua-parser.pack.mjs" + # minified echo "Generate ${MIN_PATH}" uglifyjs $SRC_PATH -o $MIN_PATH --comments "/^ UA/" +echo "Generate ${MIN_PATH_MJS}" +uglifyjs $SRC_PATH_MJS -o $MIN_PATH_MJS --comments "/^ UA/" --module + # packed echo "Generate ${PACK_PATH}" -uglifyjs $SRC_PATH -o $PACK_PATH --comments "/^ UA/" --compress --mangle \ No newline at end of file +uglifyjs $SRC_PATH -o $PACK_PATH --comments "/^ UA/" --compress --mangle + +echo "Generate ${PACK_PATH_MJS}" +uglifyjs $SRC_PATH_MJS -o $PACK_PATH_MJS --comments "/^ UA/" --compress --mangle --module \ No newline at end of file From 20e874085b184779103f026ff107c4605398f2ed Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 18 Dec 2024 23:14:41 +0700 Subject: [PATCH 44/73] Improve device detection for unknown VR device --- src/main/ua-parser.js | 6 ++---- test/data/ua/device/_others.json | 8 ++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 73778c4..2938b07 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -856,10 +856,8 @@ // MIXED (GENERIC) /////////////////// - /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors - ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors - ], [MODEL, [TYPE, TABLET]], [ + /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 ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile diff --git a/test/data/ua/device/_others.json b/test/data/ua/device/_others.json index 53818da..c47da24 100644 --- a/test/data/ua/device/_others.json +++ b/test/data/ua/device/_others.json @@ -24,6 +24,14 @@ "type": "mobile" } }, + { + "desc": "Unknown VR Device", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; Unknown Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile VR Safari/537.36", + "expect": { + "model": "Unknown", + "type": "xr" + } + }, { "desc": "Desktop (IE11 with Tablet string)", "ua": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; GWX:MANAGED; rv:11.0) like Gecko", From e8a301265a0d2e903fce795a14fd1b61e8464a28 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 21 Dec 2024 12:53:06 +0700 Subject: [PATCH 45/73] [extensions] Create a new list for `Vehicles` user-agent: Volvo, Rivian, BYD --- src/extensions/ua-parser-extensions.d.ts | 3 ++- src/extensions/ua-parser-extensions.js | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/extensions/ua-parser-extensions.d.ts b/src/extensions/ua-parser-extensions.d.ts index d1d0a12..a90a443 100644 --- a/src/extensions/ua-parser-extensions.d.ts +++ b/src/extensions/ua-parser-extensions.d.ts @@ -12,4 +12,5 @@ export const Emails: UAParserExt; export const Fetchers: UAParserExt; export const InApps: UAParserExt; export const Libraries: UAParserExt; -export const MediaPlayers: UAParserExt; \ No newline at end of file +export const MediaPlayers: UAParserExt; +export const Vehicles: UAParserExt; \ No newline at end of file diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 09b793c..8f3043c 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -321,6 +321,24 @@ const Libraries = Object.freeze({ ] }); +///////////// +// VEHICLES +//////////// + +const Vehicles = Object.freeze({ + device : [ + [ + /dilink.+(byd) auto/i, // BYD + ], [VENDOR], [ + + /(rivian) (r1t)/i, // Rivian + ], [VENDOR, MODEL], [ + + /vcc.+netfront/i, // Volvo + ], [[VENDOR, 'Volvo']] + ] +}); + ////////// // BOTS ///////// @@ -343,5 +361,6 @@ module.exports = { Fetchers, InApps, Libraries, - MediaPlayers + MediaPlayers, + Vehicles }; \ No newline at end of file From 10ab810568db032035cd11822fd8ef58c74fbe18 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 23 Dec 2024 13:30:16 +0700 Subject: [PATCH 46/73] Improve detection for Nokia device & Symbian OS --- src/main/ua-parser.js | 13 ++++----- test/data/ua/device/nokia.json | 45 ++++++++++++++++++++++++++++++ test/data/ua/os/maemo.json | 18 ++++++++++++ test/data/ua/os/qnx.json | 2 +- test/data/ua/os/symbian.json | 51 ++++++++++++++++++++++++++++++++-- 5 files changed, 117 insertions(+), 12 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 2938b07..d7eedfa 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -618,8 +618,8 @@ // Nokia /(nokia) (t[12][01])/i ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /(?:maemo|nokia).*(n900|lumia \d+)/i, - /nokia[-_ ]?(([-\w\.]*))/i + /(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i, + /nokia[-_ ]?(([-\w\. ]*))/i ], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [ // Google @@ -930,15 +930,12 @@ ], [VERSION, NAME], [ /(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [ - // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony - /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i, - /(blackberry)\w*\/([\w\.]*)/i, // Blackberry - /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS - /\((series40);/i // Series 40 + // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen + /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/; ]?([\d\.]*)/i ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ - /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian + /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS ], [VERSION, [NAME, FIREFOX+' OS']], [ diff --git a/test/data/ua/device/nokia.json b/test/data/ua/device/nokia.json index c8cf6a9..375cfcc 100644 --- a/test/data/ua/device/nokia.json +++ b/test/data/ua/device/nokia.json @@ -17,6 +17,15 @@ "type": "mobile" } }, + { + "desc": "Nokia 5800 XpressMusic", + "ua": "Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Nokia5800d-1/10.4.016; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413", + "expect": { + "vendor": "Nokia", + "model": "5800d-1", + "type": "mobile" + } + }, { "desc": "Nokia 7", "ua": "Mozilla/5.0 (Linux; Android 11; Nokia 7.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", @@ -26,6 +35,33 @@ "type": "mobile" } }, + { + "desc": "Nokia 808 PureView", + "ua": "Mozilla/5.0 (Symbian; U; Nokia808 PureView; en-GB) AppleWebKit/534.3 (KHTML, like Gecko) Version/3.0 Mobile/1A543a Mobile Safari/534.3", + "expect": { + "vendor": "Nokia", + "model": "808 PureView", + "type": "mobile" + } + }, + { + "desc": "Nokia 808 PureView", + "ua": "Mozilla/5.0 (Symbian/3; Series60/5.5 Nokia808PureView/113.010.1508; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/535.1 (KHTML, like Gecko) NokiaBrowser/8.3.2.21 Mobile Safari/535.1 3gpp-gba", + "expect": { + "vendor": "Nokia", + "model": "808PureView", + "type": "mobile" + } + }, + { + "desc": "Nokia Lumia 630", + "ua": "UCWEB/2.0 (Windows; U; wds 8.10; en-IN; NOKIA; RM-978_1046) U2/1.0.0 UCBrowser/4.2.0.524 U2/1.0.0 Mobile", + "expect": { + "vendor": "Nokia", + "model": "RM-978", + "type": "mobile" + } + }, { "desc": "Nokia N9", "ua": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", @@ -35,6 +71,15 @@ "type": "mobile" } }, + { + "desc": "Nokia N900", + "ua": "Mozilla/5.0 (Linux; Maemo 5.0; Nokia N900; Build/4.0.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Mobile Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "N900", + "type": "mobile" + } + }, { "desc": "Nokia T20", "ua": "Mozilla/5.0 (Linux; Android 12; Nokia T20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", diff --git a/test/data/ua/os/maemo.json b/test/data/ua/os/maemo.json index 92dfe78..9d89849 100644 --- a/test/data/ua/os/maemo.json +++ b/test/data/ua/os/maemo.json @@ -7,5 +7,23 @@ "name" : "Maemo", "version" : "undefined" } + }, + { + "desc" : "Nokia N900 Linux mobile, on the Maemo browser", + "ua" : "Mozilla/5.0(X11; U; Linux armv7l; fr-FR; rv:1.9.2a1pre) Gecko/20091127 Firefox/3.5 Maemo Browser 1.5.6 RX-51 N900", + "expect" : + { + "name" : "Maemo", + "version" : "undefined" + } + }, + { + "desc" : "Nokia N900 Linux mobile, on the Maemo browser", + "ua" : "Mozilla/5.0 (Linux; Maemo 5.0; Nokia N900; Build/4.0.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Mobile Safari/537.36", + "expect" : + { + "name" : "Maemo", + "version" : "5.0" + } } ] \ No newline at end of file diff --git a/test/data/ua/os/qnx.json b/test/data/ua/os/qnx.json index fcb3ed1..2817e48 100644 --- a/test/data/ua/os/qnx.json +++ b/test/data/ua/os/qnx.json @@ -5,7 +5,7 @@ "expect" : { "name" : "QNX", - "version" : "x86pc" + "version" : "undefined" } } ] \ No newline at end of file diff --git a/test/data/ua/os/symbian.json b/test/data/ua/os/symbian.json index 24f509e..0e61d02 100644 --- a/test/data/ua/os/symbian.json +++ b/test/data/ua/os/symbian.json @@ -1,6 +1,6 @@ [ { - "desc" : "Symbian", + "desc" : "Nokia 5250", "ua" : "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba", "expect" : { @@ -9,12 +9,57 @@ } }, { - "desc" : "Symbian", + "desc" : "Nokia N79", + "ua" : "Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaN79-1/32.001; Profile/MIDP-2.1 Configuration/CLDC-1", + "expect" : + { + "name" : "Symbian", + "version" : "9.3" + } + }, + { + "desc" : "Nokia E71", + "ua" : "Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE71-1/110.07.127; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413", + "expect" : + { + "name" : "Symbian", + "version" : "9.2" + } + }, + { + "desc" : "Opera Mini on S60", + "ua" : "Opera/9.80 (Series 60; Opera Mini/7.1.32444/191.361; U; de) Presto/2.12.423 Version/12.16", + "expect" : + { + "name" : "Symbian", + "version" : "undefined" + } + }, + { + "desc" : "NokiaBrowser on Nokia C7", "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaC7-00/024.001; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba", "expect" : { "name" : "Symbian", - "version" : "5.2" + "version" : "3" + } + }, + { + "desc" : "Nokia 808 PureView", + "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.5 Nokia808PureView/113.010.1508; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/535.1 (KHTML, like Gecko) NokiaBrowser/8.3.2.21 Mobile Safari/535.1 3gpp-gba", + "expect" : + { + "name" : "Symbian", + "version" : "3" + } + }, + { + "desc" : "Nokia 808 PureView", + "ua" : "Mozilla/5.0 (Symbian; U; Nokia808 PureView; en-GB) AppleWebKit/534.3 (KHTML, like Gecko) Version/3.0 Mobile/1A543a Mobile Safari/534.3", + "expect" : + { + "name" : "Symbian", + "version" : "undefined" } } ] \ No newline at end of file From 9e64f34e726d79c8ad2aca4bf4ed3cf989680285 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 23 Dec 2024 15:19:35 +0700 Subject: [PATCH 47/73] Improve CPU detection: x86 --- src/main/ua-parser.js | 2 +- test/data/ua/cpu/cpu-all.json | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index d7eedfa..a5e8d63 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -499,7 +499,7 @@ ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i, // IA32 (quicktime) - /\b((i[346]|x)86)\b/i // IA32 (x86) + /\b((i[346]|x)86)(pc)?\b/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ /\b(aarch64|arm(v?[89]e?l?|_?64))\b/i // ARM64 diff --git a/test/data/ua/cpu/cpu-all.json b/test/data/ua/cpu/cpu-all.json index 5607eaf..a4f68b1 100644 --- a/test/data/ua/cpu/cpu-all.json +++ b/test/data/ua/cpu/cpu-all.json @@ -278,5 +278,13 @@ { "architecture" : "68k" } + }, + { + "desc" : "x86", + "ua" : "Mozilla/5.0 (Photon; U; QNX x86pc; en-US; rv:1.8.1.20) Gecko/20090127 BonEcho/2.0.0.20", + "expect" : + { + "architecture" : "ia32" + } } ] From 3ca23193ddc036261b41de75f2263596314641bf Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 23 Dec 2024 15:29:50 +0700 Subject: [PATCH 48/73] Improve OS detection: fix Linux arch mistakenly detected as version --- src/main/ua-parser.js | 2 +- test/data/ua/os/linux.json | 11 ++++++++++- test/unit/ua-ch.js | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index a5e8d63..a449ada 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -965,7 +965,7 @@ /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire - /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux + /(hurd|linux)(?: arm\w*| x86\w*| ?)([\w\.]*)/i, // Hurd/Linux /(gnu) ?([\w\.]*)/i, // GNU /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly /(haiku) (\w+)/i // Haiku diff --git a/test/data/ua/os/linux.json b/test/data/ua/os/linux.json index ad86c4e..af78593 100644 --- a/test/data/ua/os/linux.json +++ b/test/data/ua/os/linux.json @@ -5,7 +5,16 @@ "expect" : { "name" : "Linux", - "version" : "x86_64" + "version" : "undefined" + } + }, + { + "desc" : "Linux", + "ua" : "Mozilla/5.0 (X11; U; Linux armv61; en-US; rv:1.9.1b2pre) Gecko/20081015 Fennec/1.0a1", + "expect" : + { + "name" : "Linux", + "version" : "undefined" } } ] \ No newline at end of file diff --git a/test/unit/ua-ch.js b/test/unit/ua-ch.js index 1342a35..71bfdea 100644 --- a/test/unit/ua-ch.js +++ b/test/unit/ua-ch.js @@ -68,7 +68,7 @@ describe('Map UA-CH headers', () => { assert.strictEqual(uap.engine.name, 'Blink'); assert.strictEqual(uap.engine.version, '110.0.0.0'); assert.strictEqual(uap.os.name, "Linux"); - assert.strictEqual(uap.os.version, "x86_64"); + assert.strictEqual(uap.os.version, undefined); }); it('Fallback to user-agent header when using `withClientHints()` but found no client hints-related headers', () => { @@ -90,7 +90,7 @@ describe('Map UA-CH headers', () => { assert.strictEqual(uap.engine.name, 'Blink'); assert.strictEqual(uap.engine.version, '110.0.0.0'); assert.strictEqual(uap.os.name, "Linux"); - assert.strictEqual(uap.os.version, "x86_64"); + assert.strictEqual(uap.os.version, undefined); }); it('Can detect Apple silicon from client hints data', () => { From 51dce55e650eab110f403c2b5e6114b460e52fcd Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 4 Feb 2025 21:49:28 +0700 Subject: [PATCH 49/73] Bump version `2.0.1` --- CHANGELOG.md | 40 ++++ dist/ua-parser.min.js | 4 +- dist/ua-parser.min.mjs | 4 +- dist/ua-parser.pack.js | 4 +- dist/ua-parser.pack.mjs | 4 +- package-lock.json | 4 +- package.json | 2 +- src/enums/ua-parser-enums.d.ts | 2 +- src/enums/ua-parser-enums.js | 2 +- src/enums/ua-parser-enums.mjs | 5 +- src/extensions/ua-parser-extensions.d.ts | 2 +- src/extensions/ua-parser-extensions.js | 2 +- src/extensions/ua-parser-extensions.mjs | 173 +++++++---------- src/helpers/ua-parser-helpers.d.ts | 2 +- src/helpers/ua-parser-helpers.js | 2 +- src/helpers/ua-parser-helpers.mjs | 2 +- src/main/ua-parser.d.ts | 2 +- src/main/ua-parser.js | 4 +- src/main/ua-parser.mjs | 226 +++++++++++++++-------- 19 files changed, 276 insertions(+), 210 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5545baf..48b23eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,37 @@ --- +## Version 2.0.1 + +- Add new browser: Ladybird, Daum +- Add new device: Apple HomePod +- Add new device vendor: HMD +- Add new OS: Ubuntu Touch, Windows IoT +- Improve CPU detection: ARM, x86 +- Improve device detection: Lenovo, Nokia, Nvidia, Xiaomi + - Tablet: Google, Honor, Huawei, Infinix, Nokia, OnePlus, Xiaomi + - Wearable: Asus, Google, LG, Motorola, OnePlus, Oppo, Samsung, Sony + - Smart-TV: Xiaomi, unidentified vendors + - Improve detection for unknown VR devices + - Improve device model detection for Generic devices +- Improve OS detection: Linux, Symbian +- Improve TypeScript definitions for Headers +- Improve `withClientHints()`: + - `engine.version` also get updated + - Infer `device.vendor` & `device.type` by guessing from `device.model` + - Browser naming adjustments: + - `Google Chrome` => `Chrome` + - `Microsoft Edge` => `Edge` + - `Android WebView` => `Chrome WebView` + - `HeadlessChrome` => `Chrome Headless` +- `enums` submodule: + - Add TypeScript definitions +- `extensions` submodule: + - Add new list: + - `Vehicles`: BYD, Rivian, Volvo + - Add new Fetcher: Bluesky + - Add new Library: Apache-HttpClient, go-http-client, got, GuzzleHttp, Java-http-client, libwww-perl, lua-resty-http, Needle, OkHttp, node-fetch, PHP-SOAP, PostmanRuntime, superagent + ## Version 2.0.0 - `ua-parser-js/extensions` submodule: @@ -166,6 +197,15 @@ --- +## Version 0.7.40 / 1.0.40 +- Add new browser: 115, LibreWolf, Slimboat, Slimjet +- Add new device: Advan, Cat, Energizer, IMO, Micromax, Smartfren +- Add new engine: ArkWeb, Servo +- Add new os: OpenHarmony +- Improve browser detection: 2345, 360, Dragon, Iron, Maxthon +- Recognize Honor as a separate device vendor from Huawei +- Fix Python Request mistakenly identified as Meta Quest + ## Version 0.7.39 / 1.0.39 - Add new feature: executable command using `npx ua-parser-js "[INSERT-UA-HERE]"` - Add new browser: Helio, Pico Browser, Wolvic diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 54ff4b6..21e380c 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.0 +/* UAParser.js v2.0.1 Copyright © 2012-2024 Faisal Salman AGPLv3 License */ -(function(window,undefined){"use strict";var LIBVERSION="2.0.0",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",USER_AGENT="user-agent",UA_MAX_LENGTH=500,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],UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",CHROME="Chrome",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i in brands){var brandName=strip(/(Google|Microsoft) /,brands[i].brand||brands[i]),brandVersion=brands[i].version;if(!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&!/chromi/i.test(brandName))){this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL])}if(uaCH[MODEL]=="Xbox"){this.set(TYPE,CONSOLE).set(VENDOR,MICROSOFT)}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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.1",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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 diff --git a/dist/ua-parser.min.mjs b/dist/ua-parser.min.mjs index 8c8fd19..0d0cdbc 100644 --- a/dist/ua-parser.min.mjs +++ b/dist/ua-parser.min.mjs @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.0 +/* UAParser.js v2.0.1 Copyright © 2012-2024 Faisal Salman AGPLv3 License */ -var LIBVERSION="2.0.0",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",SPACE=" ",HYPHEN="-",UNKNOWN="?",RGX_LOWDASH=/_/g,FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",BROWSER="browser",CPU="cpu",DEVICE="device",ENGINE="engine",OS="os",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=PLATFORM+"Version",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+HYPHEN+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+HYPHEN+MOBILE,CH_HEADER_MODEL=CH_HEADER+HYPHEN+MODEL,CH_HEADER_PLATFORM=CH_HEADER+HYPHEN+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=CHROME+"cast",EDGE="Edge",FIREFOX="Firefox",HEADLESS="Headless",OPERA="Opera",FACEBOOK="Facebook",SAFARI="Safari",SOGOU="Sogou",WEBVIEW="WebView",ARM="arm",ANDROID="Android",WINDOWS="Windows",Browser="Browser",Mobile="Mobile",Tablet="Tablet",SMART="Smart",PREFIX_MOBILE=Mobile+SPACE,SUFFIX_BROWSER=SPACE+Browser;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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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=stripQuotes(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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(BROWSER,detect(BROWSER)).set(CPU,detect(CPU)).set(DEVICE,detect(DEVICE)).set(ENGINE,detect(ENGINE)).set(OS,detect(OS))}}return this};this.parseUA=function(){if(this.itemType!=RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case BROWSER:case ENGINE:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:GOOGLE+SPACE+CHROME,Edge:MICROSOFT+SPACE+EDGE,"Chrome WebView":ANDROID+SPACE+WEBVIEW,"Chrome Headless":HEADLESS+CHROME});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,ANDROID+" 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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 RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(BROWSER,parse(BROWSER)).set(CPU,parse(CPU)).set(DEVICE,parse(DEVICE)).set(ENGINE,parse(ENGINE)).set(OS,parse(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==RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(BROWSER,this.getBrowser()).set(CPU,this.getCPU()).set(DEVICE,this.getDevice()).set(ENGINE,this.getEngine()).set(OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(BROWSER)],["getCPU",createItemFunc(CPU)],["getDevice",createItemFunc(DEVICE)],["getEngine",createItemFunc(ENGINE)],["getOS",createItemFunc(OS)],["getResult",createItemFunc(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.1",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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 diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 6f7b1fb..0d56ca4 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.0 +/* UAParser.js v2.0.1 Copyright © 2012-2024 Faisal Salman AGPLv3 License */ -!function(i,d){"use strict";function e(i){for(var e={},t=0;tC?Ci(i,C):i),this}]]).setUA(r),this}Ui.VERSION="2.0.0",Ui.BROWSER=e([m,v,p,f]),Ui.CPU=e([k]),Ui.DEVICE=e([h,g,f,x,y,t,r,o,s]),Ui.ENGINE=Ui.OS=e([m,v]),typeof exports!==b?(typeof module!==b&&module.exports&&(exports=module.exports=Ui),exports.UAParser=Ui):typeof define===u&&define.amd?define(function(){return Ui}):li&&(i.UAParser=Ui);var ji,Ei=li&&(i.jQuery||i.Zepto);Ei&&!Ei.ua&&(ji=new Ui,Ei.ua=ji.getResult(),Ei.ua.get=function(){return ji.getUA()},Ei.ua.set=function(i){ji.setUA(i);var e,t=ji.getResult();for(e in t)Ei.ua[e]=t[e]})}("object"==typeof window?window:this); \ No newline at end of file +((i,l)=>{function I(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Pi,e):Pi,N.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Ri(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 Ri(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>M?Hi(i,M):i),this}]]).setUA(r),this):new P(i,e,t).getResult()}P.VERSION="2.0.1",P.BROWSER=I([v,y,B,k]),P.CPU=I([C]),P.DEVICE=I([T,x,k,G,S,e,r,t,D]),P.ENGINE=P.OS=I([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=P:exports).UAParser=P:typeof define===V&&define.amd?define(function(){return P}):Ti&&(i.UAParser=P);var Vi,Li=Ti&&(i.jQuery||i.Zepto);Li&&!Li.ua&&(Vi=new P,Li.ua=Vi.getResult(),Li.ua.get=function(){return Vi.getUA()},Li.ua.set=function(i){Vi.setUA(i);var e,t=Vi.getResult();for(e in t)Li.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 2891557..949ccc2 100644 --- a/dist/ua-parser.pack.mjs +++ b/dist/ua-parser.pack.mjs @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.0 +/* UAParser.js v2.0.1 Copyright © 2012-2024 Faisal Salman AGPLv3 License */ -function U(i){for(var e={},t=0;t{var t,o={},r=e;if(!Hi(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})(Vi,e):Vi,P.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Ni(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 Ni(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 ji(i)&&(r=i.length>M?Ui(i,M):i),this}]]).setUA(r),this):new E(i,e,t).getResult()}E.VERSION="2.0.0",E.BROWSER=U([v,y,B,k]),E.CPU=U([C]),E.DEVICE=U([S,x,k,G,_,t,r,o,D]),E.ENGINE=E.OS=U([v,y]);export{E as UAParser}; \ No newline at end of file +function M(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Ei,e):Ei,N.call(this,[["getBrowser",(n=function(i){return i==f?function(){return new Ri(i,r,s,a).set("ua",r).set(c,this.getBrowser()).set(u,this.getCPU()).set(h,this.getDevice()).set(p,this.getEngine()).set(m,this.getOS()).get()}:function(){return new Ri(i,r,s[i],a).parseUA().get()}})(c)],["getCPU",n(u)],["getDevice",n(h)],["getEngine",n(p)],["getOS",n(m)],["getResult",n(f)],["getUA",function(){return r}],["setUA",function(i){return A(i)&&(r=i.length>P?Ai(i,P):i),this}]]).setUA(r),this):new I(i,e,t).getResult()}I.VERSION="2.0.1",I.BROWSER=M([g,x,C,v]),I.CPU=M([y]),I.DEVICE=M([T,k,v,G,S,i,r,e,F]),I.ENGINE=I.OS=M([g,x]);export{I as UAParser}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 118888a..385c237 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ua-parser-js", - "version": "2.0.0", + "version": "2.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ua-parser-js", - "version": "2.0.0", + "version": "2.0.1", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index ca3208a..5fae021 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "2.0.0", + "version": "2.0.1", "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 db4ffa6..b1591bc 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Enums submodule of UAParser.js v2.0.0 +// Type definitions for Enums submodule of UAParser.js v2.0.1 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 9e8dbe0..cbc3383 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.0 +/* Enums for UAParser.js v2.0.1 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/enums/ua-parser-enums.mjs b/src/enums/ua-parser-enums.mjs index 276b8a2..1710477 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.0 +/* Enums for UAParser.js v2.0.1 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ @@ -38,6 +38,7 @@ const Browser = Object.freeze({ COBALT: 'Cobalt', COC_COC: 'Coc Coc', CONKEROR: 'Conkeror', + DAUM: 'Daum', DILLO: 'Dillo', DOLPHIN: 'Dolphin', DORIS: 'Doris', @@ -370,11 +371,13 @@ const OS = Object.freeze({ SYMBIAN: 'Symbian', TIZEN: 'Tizen', UBUNTU: 'Ubuntu', + UBUNTU_TOUCH: 'Ubuntu Touch', UNIX: 'Unix', VECTORLINUX: 'VectorLinux', WATCHOS: 'watchOS', WEBOS: 'WebOS', WINDOWS: 'Windows', + WINDOWS_IOT: 'Windows IoT', WINDOWS_MOBILE: 'Windows Mobile', WINDOWS_PHONE: 'Windows Phone', XBOX: 'Xbox', diff --git a/src/extensions/ua-parser-extensions.d.ts b/src/extensions/ua-parser-extensions.d.ts index a90a443..f6ac5d3 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.0 +// Type definitions for Helpers submodule of UAParser.js v2.0.1 // 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 8f3043c..a4fe347 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.0 +/* Extensions for UAParser.js v2.0.1 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/extensions/ua-parser-extensions.mjs b/src/extensions/ua-parser-extensions.mjs index 33f9b99..29a9e39 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.0 +/* Extensions for UAParser.js v2.0.1 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ @@ -165,7 +165,7 @@ const ExtraDevices = Object.freeze({ /\b(zur\d{3}) b/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /\b((zeki)?tb.*\b) b/i // Zeki Tablets + /^((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ /\b([yr]\d{2}) b/i, @@ -222,31 +222,25 @@ const Fetchers = Object.freeze({ // ChatGPT-User - https://platform.openai.com/docs/plugins/bot // DuckAssistBot - https://duckduckgo.com/duckassistbot/ // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot - /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i, + // Google Site Verifier / Meta / Yahoo! Japan + // Yandex Bots - https://yandex.com/bots + /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, - // Google Site Verifier - /(google-site-verification)\/([\w\.]+)/i, - - // Meta - /(meta-externalfetcher)\/([\w\.]+)/i, + // Bluesky + /(bluesky) cardyb\/([\w\.]+)/i, // Slackbot - https://api.slack.com/robots /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i, // WhatsApp - /(whatsapp)\/([\w\.]+)[\/ ][ianw]/i, - - // Yahoo! Japan - /(y!?j-dlc)\/([\w\.]+)/i, - - // Yandex Bots - https://yandex.com/bots - /(yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, - /(yandex(?:sitelinks|userproxy))/i + /(whatsapp)\/([\w\.]+)[\/ ][ianw]/i ], [NAME, VERSION, [TYPE, FETCHER]], - // Google Bots / Cohere / Snapchat / Vercelbot - [/(cohere-ai|vercelbot|feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat)/i], + [ + // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots + /(cohere-ai|vercelbot|feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat|yandex(?:sitelinks|userproxy))/i + ], [NAME, [TYPE, FETCHER]], ] }); @@ -271,104 +265,48 @@ const InApps = Object.freeze({ const MediaPlayers = Object.freeze({ browser : [[ - - /(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia - /(coremedia) v([\w\._]+)/i - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i, - // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC + /(apple(?:coremedia|tv))\/([\w\._]+)/i, // Generic Apple CoreMedia + /(coremedia) v([\w\._]+)/i, + // Ares/Nexplayer/OSSProxy + /(ares|clementine|music player daemon|nexplayer|ossproxy) ([\w\.-]+)/i, + // Aqualung/Lyssna/BSPlayer/Clementine/MPD + // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/GnomeMplayer/MoC // NSPlayer/PSP-InternetRadioPlayer/Videos - /(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD - /(lg player|nexplayer)\s([\d\.]+)/i, - /player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - /(nexplayer)\s([\w\.-]+)/i // Nexplayer + // Nero Home/Nero Scout/Nokia + // QuickTime/RealMedia/RadioApp/RadioClientApplication/ + // SoundTap/Totem/Stagefright/Streamium + // XBMC/gvfs/Xine/XMMS/irapp + /^(aqualung|audacious|audimusicstream|amarok|bass|bsplayer|core|gnomemplayer|gvfs|irapp|lyssna|music on console|nero (?:home|scout)|nokia\d+|nsplayer|psp-internetradioplayer|quicktime|rma|radioapp|radioclientapplication|soundtap|stagefright|streamium|totem|videos|xbmc|xine|xmms)\/([\w\.-]+)/i, + /(lg player|nexplayer) ([\d\.]+)/i, + /player\/(nexplayer|lg player) ([\w\.-]+)/i, // NexPlayer/LG Player + /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i, // Gstreamer + /(htc streaming player) [\w_]+ \/ ([\d\.]+)/i, // HTC Streaming Player + /(lavf)([\d\.]+)/i, // Lavf (FFMPEG) + // MPlayer SVN + /(mplayer)(?: |\/)(?:(?:sherpya-){0,1}svn)(?:-| )(r\d+(?:-\d+[\w\.-]+))/i, + / (songbird)\/([\w\.-]+)/i, // Songbird/Philips-Songbird + /(winamp)(?:3 version|mpeg| ) ([\w\.-]+)/i, // Winamp + /(vlc)(?:\/| media player - version )([\w\.-]+)/i, // VLC Videolan + /^(foobar2000|itunes|smp)\/([\d\.]+)/i, // Foobar2000/iTunes/SMP + /com\.(riseupradioalarm)\/([\d\.]*)/i, // RiseUP Radio Alarm + /(mplayer)(?:\s|\/| unknown-)([\w\.\-]+)/i, // MPlayer + // Windows Media Server + /(windows)\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ home media server/i ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ /(flrp)\/([\w\.-]+)/i // Flip Player ], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [ - - /(fstream|nativehost|queryseekspider)/i // FStream/NativeHost/QuerySeekSpider + // MPlayer (no other info)/Media Player Classic/Nero ShowTime + // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) + // inlight radio / YourMuze + /(fstream|media player classic|inlight radio|mplayer|nativehost|nero showtime|ocms-bot|queryseekspider|tapinradio|tunein radio|winamp|yourmuze)/i ], [NAME, [TYPE, MEDIAPLAYER]], [ - /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i - // Gstreamer - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ + /(htc_one_s|windows-media-player|wmplayer)\/([\w\.-]+)/i, // HTC One S / Windows Media Player + ], [[NAME, /[_-]/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - /(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player - /(lavf)([\d\.]+)/i // Lavf (FFMPEG) - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(htc_one_s)\/([\d\.]+)/i, // HTC One S - ], [[NAME, /_/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i, - // MPlayer SVN - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer - /(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)/i, // MPlayer (no other info) - /(yourmuze)/i, // YourMuze - /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime - ], [NAME, [TYPE, MEDIAPLAYER]], [ - - /(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(nokia\d+)\/([\w\.-]+)/i // Nokia - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(winamp)3 version ([\w\.-]+)/i, // Winamp - /(winamp)\s([\w\.-]+)/i, - /(winamp)mpeg\/([\w\.-]+)/i - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) - // inlight radio - ], [NAME, [TYPE, MEDIAPLAYER]], [ - - /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i - // QuickTime/RealMedia/RadioApp/RadioClientApplication/ - // SoundTap/Totem/Stagefright/Streamium - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(smp)([\d\.]+)/i // SMP - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(vlc) media player - version ([\w\.]+)/i, // VLC Videolan - /(vlc)\/([\w\.-]+)/i, - /(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp - /(foobar2000)\/([\d\.]+)/i, // Foobar2000 - /(itunes)\/([\d\.]+)/i // iTunes - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(wmplayer)\/([\w\.-]+)/i, // Windows Media Player - /(windows-media-player)\/([\w\.-]+)/i - ], [[NAME, /-/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - - /windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i, - // Windows Media Server - ], [VERSION, [NAME, 'Windows'], [TYPE, MEDIAPLAYER]], [ - - /(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(rad.io)\s([\d\.]+)/i, // Rad.io - /(radio.(?:de|at|fr))\s([\d\.]+)/i + /(rad.io|radio.(?:de|at|fr)) ([\d\.]+)/i // Rad.io ], [[NAME, 'rad.io'], VERSION, [TYPE, MEDIAPLAYER]] ] }); @@ -387,6 +325,24 @@ const Libraries = Object.freeze({ ] }); +///////////// +// VEHICLES +//////////// + +const Vehicles = Object.freeze({ + device : [ + [ + /dilink.+(byd) auto/i, // BYD + ], [VENDOR], [ + + /(rivian) (r1t)/i, // Rivian + ], [VENDOR, MODEL], [ + + /vcc.+netfront/i, // Volvo + ], [[VENDOR, 'Volvo']] + ] +}); + ////////// // BOTS ///////// @@ -409,5 +365,6 @@ export { Fetchers, InApps, Libraries, - MediaPlayers + MediaPlayers, + Vehicles }; \ No newline at end of file diff --git a/src/helpers/ua-parser-helpers.d.ts b/src/helpers/ua-parser-helpers.d.ts index 86bfad1..bfa8f37 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.0 +// Type definitions for Helpers submodule of UAParser.js v2.0.1 // 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 4af5175..66940d1 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.0 +/* Helpers for UAParser.js v2.0.1 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 c8d1669..e3fb9a1 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.0 +/* Helpers for UAParser.js v2.0.1 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/main/ua-parser.d.ts b/src/main/ua-parser.d.ts index 03be66e..17223f4 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.0 +// Type definitions for UAParser.js v2.0.1 // 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 a449ada..3b5e0a7 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v2.0.0 +/* UAParser.js v2.0.1 Copyright © 2012-2024 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.0', + var LIBVERSION = '2.0.1', UA_MAX_LENGTH = 500, USER_AGENT = 'user-agent', EMPTY = '', diff --git a/src/main/ua-parser.mjs b/src/main/ua-parser.mjs index 09dbce3..3027a55 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.0 +/* UAParser.js v2.0.1 Copyright © 2012-2024 Faisal Salman AGPLv3 License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -21,20 +21,35 @@ // Constants ///////////// - var LIBVERSION = '2.0.0', + var LIBVERSION = '2.0.1', + UA_MAX_LENGTH = 500, + USER_AGENT = 'user-agent', EMPTY = '', UNKNOWN = '?', + + // typeof FUNC_TYPE = 'function', UNDEF_TYPE = 'undefined', OBJ_TYPE = 'object', STR_TYPE = 'string', - MAJOR = 'major', - MODEL = 'model', + + // properties + 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', + + // device types CONSOLE = 'console', MOBILE = 'mobile', TABLET = 'tablet', @@ -42,9 +57,11 @@ WEARABLE = 'wearable', XR = 'xr', EMBEDDED = 'embedded', + + // browser types INAPP = 'inapp', - USER_AGENT = 'user-agent', - UA_MAX_LENGTH = 500, + + // client hints BRANDS = 'brands', FORMFACTORS = 'formFactors', FULLVERLIST = 'fullVersionList', @@ -61,12 +78,8 @@ 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], - UA_BROWSER = 'browser', - UA_CPU = 'cpu', - UA_DEVICE = 'device', - UA_ENGINE = 'engine', - UA_OS = 'os', - UA_RESULT = 'result', + + // device vendors AMAZON = 'Amazon', APPLE = 'Apple', ASUS = 'ASUS', @@ -78,20 +91,29 @@ LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', + NVIDIA = 'Nvidia', + ONEPLUS = 'OnePlus', + OPPO = 'OPPO', SAMSUNG = 'Samsung', SHARP = 'Sharp', SONY = 'Sony', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', - PREFIX_MOBILE = 'Mobile ', - SUFFIX_BROWSER = ' Browser', + + // browsers CHROME = 'Chrome', + CHROMIUM = 'Chromium', CHROMECAST = 'Chromecast', EDGE = 'Edge', FIREFOX = 'Firefox', OPERA = 'Opera', FACEBOOK = 'Facebook', SOGOU = 'Sogou', + + PREFIX_MOBILE = 'Mobile ', + SUFFIX_BROWSER = ' Browser', + + // os WINDOWS = 'Windows'; var isWindow = typeof window !== UNDEF_TYPE, @@ -401,6 +423,7 @@ /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp + /(daum)apps[\/ ]([\w\.]+)/i, // Daum App /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(alipay)client\/([\w\.]+)/i, // Alipay @@ -463,8 +486,8 @@ /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, - // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser + /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, + // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird /\b(links) \(([\w\.]+)/i // Links ], [NAME, [VERSION, /_/g, '.']], [ @@ -474,30 +497,30 @@ cpu : [[ - /\b(?:(amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64) + /\b((amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64) ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i, // IA32 (quicktime) - /((?:i[346]|x)86)[;\)]/i // IA32 (x86) + /\b((i[346]|x)86)(pc)?\b/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ - /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 + /\b(aarch64|arm(v?[89]e?l?|_?64))\b/i // ARM64 ], [[ARCHITECTURE, 'arm64']], [ - /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF + /\b(arm(v[67])?ht?n?[fl]p?)\b/i // ARMHF ], [[ARCHITECTURE, 'armhf']], [ // PocketPC mistakenly identified as PowerPC - /windows (ce|mobile); ppc;/i + /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i ], [[ARCHITECTURE, 'arm']], [ - /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC + /((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ - /(sun4\w)[;\)]/i // SPARC + / sun4\w[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i + /\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]] ], @@ -531,34 +554,38 @@ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ // Honor - /(?:honor)([-\w ]+)[;\)]/i + /\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i + ], [MODEL, [VENDOR, HONOR], [TYPE, TABLET]], [ + /honor([-\w ]+)[;\)]/i ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [ // Huawei - /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i + /\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei)([-\w ]+)[;\)]/i, /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi + /oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i, + /\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i // Mi Pad tablets + ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ + /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models - /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i, // Xiaomi Mi + / ([\w ]+) miui\/v?\d/i ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ - /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad - /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets - ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO /; (\w+) bui.+ oppo/i, /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i - ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ - /\b(opd2\d{3}a?) bui/i - ], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [ + ], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [ + /\b(opd2(\d{3}a?))(?: bui|\))/i + ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '203'], '*' : OPPO }], [TYPE, TABLET]], [ // Vivo /vivo (\w+)(?: bui|\))/i, @@ -572,7 +599,7 @@ // Motorola /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, /\bmot(?:orola)?[- ](\w*)/i, - /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i + /((?:moto(?! 360)[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ /\b(mz60\d|xoom[2 ]{0,2}) build\//i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ @@ -581,22 +608,24 @@ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, - /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, + /\blg[-e;\/ ]+((?!browser|netcast|android tv|watch)\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo - /(ideatab[-\w ]+)/i, - /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i + /(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i, + /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [ // Nokia - /(?:maemo|nokia).*(n900|lumia \d+)/i, - /nokia[-_ ]?([-\w\.]*)/i - ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ + /(nokia) (t[12][01])/i + ], [VENDOR, MODEL, [TYPE, TABLET]], [ + /(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i, + /nokia[-_ ]?(([-\w\. ]*))/i + ], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [ // Google - /(pixel c)\b/i // Google Pixel C + /(pixel (c|tablet))\b/i // Google Pixel C/Tablet ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ @@ -611,7 +640,7 @@ // OnePlus / (kb2005|in20[12]5|be20[12][59])\b/i, /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i - ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [ // Amazon /(alexa)webm/i, @@ -687,18 +716,19 @@ ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [ // MIXED - /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, + /(imo) (tab \w+)/i, // IMO + /(infinix) (x1101b?)/i // Infinix XPad + ], [VENDOR, MODEL, [TYPE, TABLET]], [ + + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan - /; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO + /; (hmd|imo) ([\w ]+?)(?: bui|\))/i, // HMD/IMO /(hp) ([\w ]+\w)/i, // HP iPAQ - /(asus)-?(\w+)/i, // Asus /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia - /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo - /(jolla)/i, // Jolla + /(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i, // Lenovo /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(imo) (tab \w+)/i, // IMO /(kobo)\s(ereader|touch)/i, // Kobo /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad @@ -709,8 +739,8 @@ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ - /(shield[\w ]+) b/i // Nvidia Shield Tablets - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ + /((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i // Nvidia Tablets + ], [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]], [ /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin @@ -742,19 +772,24 @@ ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ /droid.+aft(\w+)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ + /(shield \w+ tv)/i // Nvidia Shield TV + ], [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i, /(aquos-tv[\w ]+)\)/i // Sharp ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[ /(bravia[\w ]+)( bui|\))/i // Sony ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ - /(mitv-\w{5}) bui/i // Xiaomi + /(mi(tv|box)-?\w+) bui/i // Xiaomi ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ /Hbbtv.*(technisat) (.*);/i // TechniSAT ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors + // SmartTV from Unidentified Vendors + /droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i + ], [MODEL, [TYPE, SMARTTV]], [ + /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i ], [[TYPE, SMARTTV]], [ /////////////////// @@ -764,8 +799,8 @@ /(ouya)/i, // Ouya /(nintendo) (\w+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ - /droid.+; (shield) bui/i // Nvidia - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ + /droid.+; (shield)( bui|\))/i // Nvidia Portable + ], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [ /(playstation \w+)/i // Playstation ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox @@ -775,12 +810,23 @@ // WEARABLES /////////////////// - /\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch + /\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i // Samsung Galaxy Watch ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [ - /((pebble))app/i // Pebble + /((pebble))app/i, // Pebble + /(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i // Asus ZenWatch / LG Watch / Pixel Watch ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ + /(ow(?:19|20)?we?[1-3]{1,3})/i // Oppo Watch + ], [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]], [ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [ + /(opwwe\d{3})/i // OnePlus Watch + ], [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]], [ + /(moto 360)/i // Motorola 360 + ], [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]], [ + /(smartwatch 3)/i // Sony SmartWatch + ], [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]], [ + /(g watch r)/i // LG G Watch R + ], [MODEL, [VENDOR, LG], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ @@ -803,20 +849,22 @@ ], [VENDOR, [TYPE, EMBEDDED]], [ /(aeobc)\b/i // Echo Dot ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [ + /(homepod).+mac os/i // Apple HomePod + ], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [ + /windows iot/i + ], [[TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) /////////////////// - /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors - ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors - ], [MODEL, [TYPE, TABLET]], [ + /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 ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ - /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device + /droid .+?; ([\w\. -]+)( bui|\))/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] ], @@ -836,8 +884,11 @@ /ekioh(flow)\/([\w\.]+)/i, // Flow /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab - /\b(libweb)/i + + /\b(libweb)/i // LibWeb ], [NAME, VERSION], [ + /ladybird\//i + ], [[NAME, 'LibWeb']], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko ], [VERSION, NAME] @@ -848,15 +899,15 @@ // Windows /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ - /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone + /(windows (?:phone(?: os)?|mobile|iot))[\/ ]?([\d\.\w ]*)/i // Windows Phone ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ - /windows nt 6\.2; (arm)/i, // Windows RT - /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i, + /windows nt 6\.2; (arm)/i, // Windows RT + /windows[\/ ]([ntce\d\. ]+\w)(?!.+xbox)/i, /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [ // iOS/macOS - /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS + /[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i, /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ @@ -878,15 +929,15 @@ // Mobile OSes /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS - ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony - /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i, - /(blackberry)\w*\/([\w\.]*)/i, // Blackberry - /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS - /\((series40);/i // Series 40 + ], [VERSION, NAME], [ + /(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch + ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [ + // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen + /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/; ]?([\d\.]*)/i ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ - /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian + /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS ], [VERSION, [NAME, FIREFOX+' OS']], [ @@ -916,7 +967,7 @@ /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire - /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux + /(hurd|linux)(?: arm\w*| x86\w*| ?)([\w\.]*)/i, // Hurd/Linux /(gnu) ?([\w\.]*)/i, // GNU /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly /(haiku) (\w+)/i // Haiku @@ -1153,17 +1204,27 @@ switch (this.itemType) { case UA_BROWSER: + case UA_ENGINE: var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; if (brands) { for (var i in brands) { - var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]), + var brandName = brands[i].brand || brands[i], brandVersion = brands[i].version; - if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) { + if (this.itemType == UA_BROWSER && !/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && brandName != CHROMIUM))) { + brandName = strMapper(brandName, { + 'Chrome' : 'Google Chrome', + 'Edge' : 'Microsoft Edge', + 'Chrome WebView' : 'Android WebView', + 'Chrome Headless' : 'HeadlessChrome' + }); this.set(NAME, brandName) .set(VERSION, brandVersion) .set(MAJOR, majorize(brandVersion)); prevName = brandName; } + if (this.itemType == UA_ENGINE && brandName == CHROMIUM) { + this.set(VERSION, brandVersion); + } } } break; @@ -1180,11 +1241,16 @@ } if (uaCH[MODEL]) { this.set(MODEL, uaCH[MODEL]); - } - // Xbox-Specific Detection - if (uaCH[MODEL] == 'Xbox') { - this.set(TYPE, CONSOLE) - .set(VENDOR, MICROSOFT); + if (!this.get(TYPE) || !this.get(VENDOR)) { + var reParse = {}; + rgxMapper.call(reParse, 'droid 9; ' + uaCH[MODEL] + ')', rgxMap); + if (!this.get(TYPE) && !!reParse.type) { + this.set(TYPE, reParse.type); + } + if (!this.get(VENDOR) && !!reParse.vendor) { + this.set(VENDOR, reParse.vendor); + } + } } if (uaCH[FORMFACTORS]) { var ff; From 98e0708f2543fdce20f35e5b9c34a43b09e1ed29 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 6 Feb 2025 11:42:18 +0700 Subject: [PATCH 50/73] Fix issue #776 - Missing type def for node-fetch --- package-lock.json | 22 ++++++---------------- package.json | 5 ++--- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 385c237..dffa977 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ ], "license": "AGPL-3.0-or-later", "dependencies": { + "@types/node-fetch": "^2.6.12", "detect-europe-js": "^0.1.2", "is-standalone-pwa": "^0.1.1", "ua-is-frozen": "^0.1.2" @@ -35,8 +36,6 @@ "@babel/traverse": "7.23.2", "@jazzer.js/core": "^1.4.0", "@playwright/test": "^1.49.0", - "@types/node": "^22.9.1", - "@types/node-fetch": "^2.6.12", "jshint": "~2.13.6", "mocha": "~8.2.0", "node-fetch": "^2.7.0", @@ -726,10 +725,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", - "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", - "dev": true, + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", + "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", "dependencies": { "undici-types": "~6.20.0" } @@ -738,7 +736,6 @@ "version": "2.6.12", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", - "dev": true, "dependencies": { "@types/node": "*", "form-data": "^4.0.0" @@ -902,8 +899,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { "version": "1.7.8", @@ -1276,7 +1272,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1417,7 +1412,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -1750,7 +1744,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -2658,7 +2651,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -2667,7 +2659,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -4279,8 +4270,7 @@ "node_modules/undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" }, "node_modules/universalify": { "version": "2.0.1", diff --git a/package.json b/package.json index 5fae021..d0258e8 100755 --- a/package.json +++ b/package.json @@ -214,15 +214,14 @@ "dependencies": { "detect-europe-js": "^0.1.2", "is-standalone-pwa": "^0.1.1", - "ua-is-frozen": "^0.1.2" + "ua-is-frozen": "^0.1.2", + "@types/node-fetch": "^2.6.12" }, "devDependencies": { "@babel/parser": "7.15.8", "@babel/traverse": "7.23.2", "@jazzer.js/core": "^1.4.0", "@playwright/test": "^1.49.0", - "@types/node": "^22.9.1", - "@types/node-fetch": "^2.6.12", "jshint": "~2.13.6", "mocha": "~8.2.0", "node-fetch": "^2.7.0", From 4ea03a587d65d0c8386054a75f10935a31371a05 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 9 Feb 2025 07:34:43 +0700 Subject: [PATCH 51/73] Bump version `2.0.2` --- CHANGELOG.md | 4 ++++ dist/ua-parser.min.js | 4 ++-- dist/ua-parser.min.mjs | 4 ++-- dist/ua-parser.pack.js | 4 ++-- dist/ua-parser.pack.mjs | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- src/enums/ua-parser-enums.d.ts | 2 +- src/enums/ua-parser-enums.js | 2 +- src/enums/ua-parser-enums.mjs | 2 +- src/extensions/ua-parser-extensions.d.ts | 2 +- src/extensions/ua-parser-extensions.js | 2 +- src/extensions/ua-parser-extensions.mjs | 2 +- src/helpers/ua-parser-helpers.d.ts | 2 +- src/helpers/ua-parser-helpers.js | 2 +- src/helpers/ua-parser-helpers.mjs | 2 +- src/main/ua-parser.d.ts | 2 +- src/main/ua-parser.js | 4 ++-- src/main/ua-parser.mjs | 4 ++-- 19 files changed, 29 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48b23eb..f62d6ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,10 @@ --- +## Version 2.0.2 + +- Fix TypeScript dependency issue + ## Version 2.0.1 - Add new browser: Ladybird, Daum diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 21e380c..02d8a82 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.1 +/* UAParser.js v2.0.2 Copyright © 2012-2024 Faisal Salman AGPLv3 License */ -(function(window,undefined){"use strict";var LIBVERSION="2.0.1",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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.2",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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 diff --git a/dist/ua-parser.min.mjs b/dist/ua-parser.min.mjs index 0d0cdbc..6def7c8 100644 --- a/dist/ua-parser.min.mjs +++ b/dist/ua-parser.min.mjs @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.1 +/* UAParser.js v2.0.2 Copyright © 2012-2024 Faisal Salman AGPLv3 License */ -var LIBVERSION="2.0.1",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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.2",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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 diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 0d56ca4..6807b0e 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.1 +/* UAParser.js v2.0.2 Copyright © 2012-2024 Faisal Salman AGPLv3 License */ -((i,l)=>{function I(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Pi,e):Pi,N.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Ri(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 Ri(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>M?Hi(i,M):i),this}]]).setUA(r),this):new P(i,e,t).getResult()}P.VERSION="2.0.1",P.BROWSER=I([v,y,B,k]),P.CPU=I([C]),P.DEVICE=I([T,x,k,G,S,e,r,t,D]),P.ENGINE=P.OS=I([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=P:exports).UAParser=P:typeof define===V&&define.amd?define(function(){return P}):Ti&&(i.UAParser=P);var Vi,Li=Ti&&(i.jQuery||i.Zepto);Li&&!Li.ua&&(Vi=new P,Li.ua=Vi.getResult(),Li.ua.get=function(){return Vi.getUA()},Li.ua.set=function(i){Vi.setUA(i);var e,t=Vi.getResult();for(e in t)Li.ua[e]=t[e]})})("object"==typeof window?window:this); \ No newline at end of file +((i,l)=>{function I(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Pi,e):Pi,N.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Ri(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 Ri(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>M?Hi(i,M):i),this}]]).setUA(r),this):new P(i,e,t).getResult()}P.VERSION="2.0.2",P.BROWSER=I([v,y,B,k]),P.CPU=I([C]),P.DEVICE=I([T,x,k,G,S,e,r,t,D]),P.ENGINE=P.OS=I([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=P:exports).UAParser=P:typeof define===V&&define.amd?define(function(){return P}):Ti&&(i.UAParser=P);var Vi,Li=Ti&&(i.jQuery||i.Zepto);Li&&!Li.ua&&(Vi=new P,Li.ua=Vi.getResult(),Li.ua.get=function(){return Vi.getUA()},Li.ua.set=function(i){Vi.setUA(i);var e,t=Vi.getResult();for(e in t)Li.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 949ccc2..5cc94b7 100644 --- a/dist/ua-parser.pack.mjs +++ b/dist/ua-parser.pack.mjs @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.1 +/* UAParser.js v2.0.2 Copyright © 2012-2024 Faisal Salman AGPLv3 License */ -function M(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Ei,e):Ei,N.call(this,[["getBrowser",(n=function(i){return i==f?function(){return new Ri(i,r,s,a).set("ua",r).set(c,this.getBrowser()).set(u,this.getCPU()).set(h,this.getDevice()).set(p,this.getEngine()).set(m,this.getOS()).get()}:function(){return new Ri(i,r,s[i],a).parseUA().get()}})(c)],["getCPU",n(u)],["getDevice",n(h)],["getEngine",n(p)],["getOS",n(m)],["getResult",n(f)],["getUA",function(){return r}],["setUA",function(i){return A(i)&&(r=i.length>P?Ai(i,P):i),this}]]).setUA(r),this):new I(i,e,t).getResult()}I.VERSION="2.0.1",I.BROWSER=M([g,x,C,v]),I.CPU=M([y]),I.DEVICE=M([T,k,v,G,S,i,r,e,F]),I.ENGINE=I.OS=M([g,x]);export{I as UAParser}; \ No newline at end of file +function M(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Ei,e):Ei,N.call(this,[["getBrowser",(n=function(i){return i==f?function(){return new Ri(i,r,s,a).set("ua",r).set(c,this.getBrowser()).set(u,this.getCPU()).set(h,this.getDevice()).set(p,this.getEngine()).set(m,this.getOS()).get()}:function(){return new Ri(i,r,s[i],a).parseUA().get()}})(c)],["getCPU",n(u)],["getDevice",n(h)],["getEngine",n(p)],["getOS",n(m)],["getResult",n(f)],["getUA",function(){return r}],["setUA",function(i){return A(i)&&(r=i.length>P?Ai(i,P):i),this}]]).setUA(r),this):new I(i,e,t).getResult()}I.VERSION="2.0.2",I.BROWSER=M([g,x,C,v]),I.CPU=M([y]),I.DEVICE=M([T,k,v,G,S,i,r,e,F]),I.ENGINE=I.OS=M([g,x]);export{I as UAParser}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index dffa977..e577985 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ua-parser-js", - "version": "2.0.1", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ua-parser-js", - "version": "2.0.1", + "version": "2.0.2", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index d0258e8..d7399cf 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "2.0.1", + "version": "2.0.2", "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 b1591bc..a6b1e59 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Enums submodule of UAParser.js v2.0.1 +// Type definitions for Enums submodule of UAParser.js v2.0.2 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index cbc3383..61a857b 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.1 +/* Enums for UAParser.js v2.0.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/enums/ua-parser-enums.mjs b/src/enums/ua-parser-enums.mjs index 1710477..6e8257a 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.1 +/* Enums for UAParser.js v2.0.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/extensions/ua-parser-extensions.d.ts b/src/extensions/ua-parser-extensions.d.ts index f6ac5d3..500a0a2 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.1 +// Type definitions for Helpers submodule of UAParser.js v2.0.2 // 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 a4fe347..9cd884c 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.1 +/* Extensions for UAParser.js v2.0.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/extensions/ua-parser-extensions.mjs b/src/extensions/ua-parser-extensions.mjs index 29a9e39..8e7bc88 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.1 +/* Extensions for UAParser.js v2.0.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/helpers/ua-parser-helpers.d.ts b/src/helpers/ua-parser-helpers.d.ts index bfa8f37..389e8c6 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.1 +// Type definitions for Helpers submodule of UAParser.js v2.0.2 // 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 66940d1..3cd3aac 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.1 +/* Helpers for UAParser.js v2.0.2 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 e3fb9a1..622e27a 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.1 +/* Helpers for UAParser.js v2.0.2 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/main/ua-parser.d.ts b/src/main/ua-parser.d.ts index 17223f4..c22a3de 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.1 +// Type definitions for UAParser.js v2.0.2 // 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 3b5e0a7..3e266eb 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v2.0.1 +/* UAParser.js v2.0.2 Copyright © 2012-2024 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.1', + var LIBVERSION = '2.0.2', UA_MAX_LENGTH = 500, USER_AGENT = 'user-agent', EMPTY = '', diff --git a/src/main/ua-parser.mjs b/src/main/ua-parser.mjs index 3027a55..0dfa143 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.1 +/* UAParser.js v2.0.2 Copyright © 2012-2024 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.1', + var LIBVERSION = '2.0.2', UA_MAX_LENGTH = 500, USER_AGENT = 'user-agent', EMPTY = '', From 5413a9888d504ef7071b08d3fded6ac161cc73a4 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 10 Feb 2025 00:55:32 +0700 Subject: [PATCH 52/73] Move node-fetch to dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d7399cf..d6b0e83 100755 --- a/package.json +++ b/package.json @@ -215,6 +215,7 @@ "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": { @@ -224,7 +225,6 @@ "@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 6f0191c11b6ac5accd0499c977137b49b55d56cd Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 15 Feb 2025 13:37:56 +0700 Subject: [PATCH 53/73] [test] Move playwright installation inside `test:playwright` script --- .github/workflows/test-ci.yml | 1 - package.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test-ci.yml b/.github/workflows/test-ci.yml index 0c46a48..feb5206 100644 --- a/.github/workflows/test-ci.yml +++ b/.github/workflows/test-ci.yml @@ -19,5 +19,4 @@ jobs: - name: Run the test run: | npm ci - npx playwright install --with-deps npm test diff --git a/package.json b/package.json index d6b0e83..3ec2617 100755 --- a/package.json +++ b/package.json @@ -209,7 +209,7 @@ "test:jshint": "jshint src/main", "test:lockfile-lint": "npx lockfile-lint -p package-lock.json", "test:mocha": "mocha test/unit", - "test:playwright": "playwright test test/e2e --browser all" + "test:playwright": "npx playwright install && playwright test test/e2e --browser all" }, "dependencies": { "detect-europe-js": "^0.1.2", From 837d31963033d937f72708e07e3e34673e7be884 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 20 Feb 2025 20:34:45 +0700 Subject: [PATCH 54/73] [extensions][helpers] Update Semrush bot variants --- package-lock.json | 10 +++------- src/extensions/ua-parser-extensions.js | 8 +++++--- src/helpers/ua-parser-helpers.js | 3 +++ test/data/ua/extension/crawler.json | 10 ++++++++++ test/data/ua/extension/fetcher.json | 10 ++++++++++ test/unit/helpers.js | 2 ++ 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index e577985..187bf02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "@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,7 +39,6 @@ "@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", @@ -3144,7 +3144,6 @@ "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" }, @@ -4179,8 +4178,7 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/trim-newlines": { "version": "3.0.1", @@ -4336,14 +4334,12 @@ "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 + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "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/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 9cd884c..1d528c9 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -52,7 +52,6 @@ const Crawlers = Object.freeze({ // MojeekBot - https://www.mojeek.com/bot.html // OpenAI's SearchGPT - https://platform.openai.com/docs/bots // PerplexityBot - https://perplexity.ai/perplexitybot - // SemrushBot - http://www.semrush.com/bot.html // SeznamBot - http://napoveda.seznam.cz/seznambot-intro /((?:ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, @@ -78,6 +77,9 @@ const Crawlers = Object.freeze({ // Internet Archive (archive.org) /(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i, + // SemrushBot - http://www.semrush.com/bot.html + /((?:semrush|splitsignal)bot[-abcfimostw]*)\/([\w\.-]+)/i, + // Sogou Spider /(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i, @@ -217,10 +219,10 @@ const Fetchers = Object.freeze({ // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // ChatGPT-User - https://platform.openai.com/docs/plugins/bot // DuckAssistBot - https://duckduckgo.com/duckassistbot/ - // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot + // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot // Google Site Verifier / Meta / Yahoo! Japan // Yandex Bots - https://yandex.com/bots - /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, + /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|telegram|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, // Bluesky /(bluesky) cardyb\/([\w\.]+)/i, diff --git a/src/helpers/ua-parser-helpers.js b/src/helpers/ua-parser-helpers.js index 3cd3aac..daaa897 100644 --- a/src/helpers/ua-parser-helpers.js +++ b/src/helpers/ua-parser-helpers.js @@ -93,6 +93,9 @@ const isAIBot = (resultOrUA) => [ // Perplexity 'perplexitybot', + // Semrush + 'semrushbot-ocob', + // Timpi 'timpibot', diff --git a/test/data/ua/extension/crawler.json b/test/data/ua/extension/crawler.json index 04a1a35..48c5865 100644 --- a/test/data/ua/extension/crawler.json +++ b/test/data/ua/extension/crawler.json @@ -480,6 +480,16 @@ "type" : "crawler" } }, + { + "desc" : "SemrushBot for ContentShake AI tool", + "ua" : "Mozilla/5.0 (compatible; SemrushBot-OCOB/1; +https://www.semrush.com/bot/)", + "expect" : + { + "name" : "SemrushBot-OCOB", + "version" : "1", + "type" : "crawler" + } + }, { "desc" : "SeznamBot", "ua" : "Mozilla/5.0 (compatible; SeznamBot/4.0-RC1; +http://napoveda.seznam.cz/seznambot-intro/)", diff --git a/test/data/ua/extension/fetcher.json b/test/data/ua/extension/fetcher.json index a04e4f6..075281e 100644 --- a/test/data/ua/extension/fetcher.json +++ b/test/data/ua/extension/fetcher.json @@ -119,6 +119,16 @@ "type" : "fetcher" } }, + { + "desc" : "SiteAuditBot", + "ua" : "Mozilla/5.0 (compatible; SiteAuditBot/0.97; +http://www.semrush.com/bot.html)", + "expect" : + { + "name" : "SiteAuditBot", + "version" : "0.97", + "type" : "fetcher" + } + }, { "desc" : "UptimeRobot", "ua" : "Mozilla/5.0 (compatible; UptimeRobot/2.0; http://www.uptimerobot.com/)", diff --git a/test/unit/helpers.js b/test/unit/helpers.js index fcd6678..95ce871 100644 --- a/test/unit/helpers.js +++ b/test/unit/helpers.js @@ -40,11 +40,13 @@ describe('isAIBot', () => { const claudeBot = 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)'; const firefox = 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0'; const searchGPT = 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; OAI-SearchBot/1.0; +https://openai.com/searchbot'; + const semrushAI = 'Mozilla/5.0 (compatible; SemrushBot-OCOB/1; +https://www.semrush.com/bot/)'; assert.equal(isAIBot(UAParser(claudeBot, Bots)), true); assert.equal(isAIBot(claudeBot), true); assert.equal(isAIBot(firefox), false); assert.equal(isAIBot(searchGPT), true); + assert.equal(isAIBot(semrushAI), true); }); }); From d8057bcd8a037eb7521a91c9eaa20dc40875b88e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 21 Feb 2025 21:14:54 +0700 Subject: [PATCH 55/73] Browser naming adjustments for Client Hints: - `HuaweiBrowser` => `Huawei Browser`, - `Miui Browser` => `MIUI Browser`, - `OperaMobile` => `Opera Mobi`, - `YaBrowser` => `Yandex` --- src/enums/ua-parser-enums.d.ts | 1 + src/enums/ua-parser-enums.js | 1 + src/main/ua-parser.js | 6 +- test/unit/ua-ch.js | 215 ++++++++++++++++++++++++++++++--- 4 files changed, 202 insertions(+), 21 deletions(-) diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts index a6b1e59..c279436 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -97,6 +97,7 @@ export const Browser: Readonly<{ OMNIWEB: "OmniWeb"; OPERA: "Opera"; OPERA_COAST: "Opera Coast"; + OPERA_GX: "Opera GX", OPERA_MINI: "Opera Mini"; OPERA_MOBI: "Opera Mobi"; OPERA_TABLET: "Opera Tablet"; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 61a857b..25b8de5 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -102,6 +102,7 @@ const Browser = Object.freeze({ OMNIWEB: 'OmniWeb', OPERA: 'Opera', OPERA_COAST: 'Opera Coast', + OPERA_GX: 'Opera GX', OPERA_MINI: 'Opera Mini', OPERA_MOBI: 'Opera Mobi', OPERA_TABLET: 'Opera Tablet', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 3e266eb..31c1c33 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -1213,7 +1213,11 @@ 'Chrome' : 'Google Chrome', 'Edge' : 'Microsoft Edge', 'Chrome WebView' : 'Android WebView', - 'Chrome Headless' : 'HeadlessChrome' + 'Chrome Headless' : 'HeadlessChrome', + 'Huawei Browser' : 'HuaweiBrowser', + 'MIUI Browser' : 'Miui Browser', + 'Opera Mobi' : 'OperaMobile', + 'Yandex' : 'YaBrowser' }); this.set(NAME, brandName) .set(VERSION, brandVersion) diff --git a/test/unit/ua-ch.js b/test/unit/ua-ch.js index 71bfdea..54e2f9a 100644 --- a/test/unit/ua-ch.js +++ b/test/unit/ua-ch.js @@ -220,45 +220,220 @@ describe('Map UA-CH headers', () => { }); }); -describe('Browser naming adjustments', () => { +describe('UA-CH Headers tests', () => { [ { - ua_ch: '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + headers : { + 'sec-ch-ua': '"Avast Secure Browser";v="131", "Chromium";v="131", "Not_A Brand";v="24"' + }, expect: { - before: 'Google Chrome', - after: 'Chrome' + browser : { + name : 'Avast Secure Browser', + version : '131', + major : '131', + type : undefined + } } }, { - ua_ch: '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"', + headers : { + 'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"' + }, expect: { - before: "Microsoft Edge", - after: "Edge" + browser : { + name : 'Brave', + version : '132', + major : '132', + type : undefined + } } }, { - ua_ch: '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"', + headers : { + 'sec-ch-ua': '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"' + }, expect: { - before: "Android WebView", - after: "Chrome WebView" + browser : { + name : 'Chrome', + version : '111', + major : '111', + type : undefined + } } }, { - ua_ch: '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"', + headers : { + 'sec-ch-ua': '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"' + }, expect: { - before: "HeadlessChrome", - after: "Chrome Headless" + browser : { + name : 'Chrome Headless', + version : '124', + major : '124', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"' + }, + expect: { + browser : { + name : 'Chrome WebView', + version : '123', + major : '123', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"DuckDuckGo";v="131", "Chromium";v="131", "Not_A Brand";v="24"' + }, + expect : { + browser : { + name : 'DuckDuckGo', + version : '131', + major : '131', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"' + }, + expect: { + browser : { + name : 'Edge', + version : '120', + major : '120', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "HuaweiBrowser";v="114"' + }, + expect: { + browser : { + name : 'Huawei Browser', + version : '114', + major : '114', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Miui Browser";v="123", "Not:A-Brand";v="8", "Chromium";v="123"' + }, + expect: { + browser : { + name : 'MIUI Browser', + version : '123', + major : '123', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="130", "Oculus Browser";v="36", "Not?A_Brand";v="99"' + }, + expect: { + browser : { + name : 'Oculus Browser', + version : '36', + major : '36', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Opera";v="116", "Chromium";v="131", "Not_A Brand";v="24"' + }, + expect: { + browser : { + name : 'Opera', + version : '116', + major : '116', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Opera GX";v="114"' + }, + expect: { + browser : { + name : 'Opera GX', + version : '114', + major : '114', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"OperaMobile";v="86", ";Not A Brand";v="99", "Opera";v="115", "Chromium";v="130"' + }, + expect: { + browser : { + name : 'Opera Mobi', + version : '86', + major : '86', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="132", "OperaMobile";v="87", "Opera";v="117", " Not A;Brand";v="99"' + }, + expect: { + browser : { + name : 'Opera Mobi', + version : '87', + major : '87', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="125", "Not.A/Brand";v="24", "Samsung Internet";v="27.0"' + }, + expect: { + browser : { + name : 'Samsung Internet', + version : '27.0', + major : '27', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="130", "YaBrowser";v="24.12", "Not?A_Brand";v="99", "Yowser";v="2.5"' + }, + expect: { + browser : { + name : 'Yandex', + version : '24.12', + major : '24', + type : undefined + } } }, ] .forEach(test => { - it(`"${test.expect.before}" => "${test.expect.after}"`, () => { - const headers = { - 'sec-ch-ua' : test.ua_ch, - }; - const { browser } = UAParser(headers).withClientHints(); - assert.strictEqual(browser.name, test.expect.after); - }); + const { browser } = UAParser(test.headers).withClientHints(); + assert.deepEqual(browser, test.expect.browser); }); }); From 056e66f6a0caf79aedad55adb133eda49b0fd4eb Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 1 Mar 2025 06:50:16 +0700 Subject: [PATCH 56/73] Update contributors in package.json --- package.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/package.json b/package.json index 3ec2617..00cbf2e 100755 --- a/package.json +++ b/package.json @@ -25,14 +25,17 @@ "contributors": [ "Aamir Poonawalla ", "Admas ", + "Aiyush ", "algenon ", "Alvin Portillo ", "Amumu ", + "Andreas Kogler ", "Andrea Vaghi ", "Anton Zhiyanov ", "Arturo Mejia ", "Arun Rama Reddy ", "Austin Pray ", + "Beat YT <66485277+Beat-YT@users.noreply.github.com>", "Bendeguz ", "Benjamin Bertrand ", "Benjamin Urban ", @@ -44,6 +47,8 @@ "chenyuan-new <53860479+chenyuan-new@users.noreply.github.com>", "Christopher De Cairos ", "Cyrille David ", + "Dai Jie ", + "Danila Rodichkin ", "Dante ", "Dario Vladovic ", "David Annez ", @@ -73,11 +78,15 @@ "Grigory Dmitrenko ", "gulpin ", "Hans Ott ", + "Harald Reingruber <74898239+haraldreingruber-dedalus@users.noreply.github.com>", "Hendrik Helwich ", "Hermann Ebert ", "hr6r ", + "Hyewon Kang ", + "Hyunbin <47051820+hyunbinseo@users.noreply.github.com>", "Igor Topal ", "Ildar Kamalov ", + "Ilya Daraseliya ", "insanehong ", "jackpoll ", "Jacky Choo ", @@ -98,6 +107,7 @@ "Liam Quinn ", "Lithin ", "liujunlve ", + "lj0812 ", "ll-syber <670159357@qq.com>", "Loris Guignard ", "Lukas Drgon ", @@ -111,6 +121,7 @@ "Max Maurer ", "Max Nordlund ", "Michael Hess ", + "Mike ", "MimyyK ", "Mok ", "nabetama ", @@ -124,6 +135,7 @@ "o.drapeza ", "Oscar Becerra ", "otakuSiD ", + "Pablo Osés ", "Paris Morgan ", "patrick-nurt ", "Pavel Studeny ", From 178e678b15a9662956b64b9e998f328ede970e19 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 1 Mar 2025 08:08:44 +0700 Subject: [PATCH 57/73] [extensions] Update some fetcher bots #780 - `Google-PageRenderer`, `GoogleImageProxy`, `Snap URL Preview`, `SkypeUriPreview`, `TelegramBot` --- src/extensions/ua-parser-extensions.js | 9 ++-- test/data/ua/extension/fetcher.json | 60 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 1d528c9..46991cc 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -222,22 +222,25 @@ const Fetchers = Object.freeze({ // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot // Google Site Verifier / Meta / Yahoo! Japan // Yandex Bots - https://yandex.com/bots - /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|telegram|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, + /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, // Bluesky /(bluesky) cardyb\/([\w\.]+)/i, + // Skype + /(skypeuripreview) preview\/([\w\.]+)/i, + // Slackbot - https://api.slack.com/robots /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i, // WhatsApp - /(whatsapp)\/([\w\.]+)[\/ ][ianw]/i + /(whatsapp)\/([\w\.]+)/i ], [NAME, VERSION, [TYPE, FETCHER]], [ // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots - /(cohere-ai|vercelbot|feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat|yandex(?:sitelinks|userproxy))/i + /(cohere-ai|vercelbot|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|telegrambot|yandex(?:sitelinks|userproxy))/i ], [NAME, [TYPE, FETCHER]], ] diff --git a/test/data/ua/extension/fetcher.json b/test/data/ua/extension/fetcher.json index 075281e..41d819e 100644 --- a/test/data/ua/extension/fetcher.json +++ b/test/data/ua/extension/fetcher.json @@ -59,6 +59,16 @@ "type" : "fetcher" } }, + { + "desc" : "Google Image Proxy", + "ua" : "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)", + "expect" : + { + "name" : "GoogleImageProxy", + "version" : "undefined", + "type" : "fetcher" + } + }, { "desc" : "Google Read Aloud - Mobile agent", "ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36 (compatible; Google-Read-Aloud; +https://support.google.com/webmasters/answer/1061943)", @@ -79,6 +89,16 @@ "type" : "fetcher" } }, + { + "desc" : "Google Page Renderer", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 Google-PageRenderer Google (+https://developers.google.com/+/web/snippet/) ", + "expect" : + { + "name" : "Google-PageRenderer", + "version" : "undefined", + "type" : "fetcher" + } + }, { "desc" : "Google Publisher Center", "ua" : "GoogleProducer; (+https://developers.google.com/search/docs/crawling-indexing/google-producer)", @@ -129,6 +149,36 @@ "type" : "fetcher" } }, + { + "desc" : "Snap URL Preview", + "ua" : "Snap URL Preview Service; bot; snapchat; https://developers.snap.com/robots ", + "expect" : + { + "name" : "Snap URL Preview", + "version" : "undefined", + "type" : "fetcher" + } + }, + { + "desc" : "SkypeUriPreview", + "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5 skype-url-preview@microsoft.com", + "expect" : + { + "name" : "SkypeUriPreview", + "version" : "0.5", + "type" : "fetcher" + } + }, + { + "desc" : "TelegramBot", + "ua" : "TelegramBot (like TwitterBot)", + "expect" : + { + "name" : "TelegramBot", + "version" : "undefined", + "type" : "fetcher" + } + }, { "desc" : "UptimeRobot", "ua" : "Mozilla/5.0 (compatible; UptimeRobot/2.0; http://www.uptimerobot.com/)", @@ -148,5 +198,15 @@ "version" : "undefined", "type" : "fetcher" } + }, + { + "desc" : "WhatsApp", + "ua" : "WhatsApp/2.23.20.0", + "expect" : + { + "name" : "WhatsApp", + "version" : "2.23.20.0", + "type" : "fetcher" + } } ] \ No newline at end of file From 3fccce26d06aae4e5c91a36dd15f1a838d75ce89 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 1 Mar 2025 09:18:18 +0700 Subject: [PATCH 58/73] GitHub Actions: test in various node versions --- .github/workflows/test-ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-ci.yml b/.github/workflows/test-ci.yml index feb5206..fee2ed4 100644 --- a/.github/workflows/test-ci.yml +++ b/.github/workflows/test-ci.yml @@ -11,12 +11,14 @@ jobs: strategy: matrix: arch: [amd64, ppc64le] + node-version: ['10.x', 'lts/*', 'node'] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: 'lts/*' + node-version: ${{ matrix.node-version }} - name: Run the test run: | npm ci + npx playwright install --with-deps npm test From d1105ce4b35c072a6e9e447a380b4d1cb8eb2bf4 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 1 Mar 2025 09:33:32 +0700 Subject: [PATCH 59/73] GitHub Actions: update node versions to be tested --- .github/workflows/test-ci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-ci.yml b/.github/workflows/test-ci.yml index fee2ed4..f1e262b 100644 --- a/.github/workflows/test-ci.yml +++ b/.github/workflows/test-ci.yml @@ -10,8 +10,11 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - arch: [amd64, ppc64le] - node-version: ['10.x', 'lts/*', 'node'] + arch: [amd64] + node-version: ['22.13', 'lts/*'] + include: + - arch: ppc64le + node-version: 20 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -19,6 +22,7 @@ jobs: node-version: ${{ matrix.node-version }} - name: Run the test run: | + echo "Running on ubuntu-latest-${{ matrix.arch }} with node version set as ${{ matrix.node-version }}" npm ci npx playwright install --with-deps npm test From 3d41647a55a71bc8755978b4a6a6c15302930f89 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 4 Mar 2025 11:14:31 +0700 Subject: [PATCH 60/73] [extensions] Update some more bots #780: `Better Uptime Bot`, `SemrushBot`, `Yahoo! Slurp` --- src/extensions/ua-parser-extensions.js | 8 +++---- test/data/ua/extension/crawler.json | 30 ++++++++++++++++++++++++++ test/data/ua/extension/fetcher.json | 10 +++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 46991cc..09feadf 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -78,7 +78,7 @@ const Crawlers = Object.freeze({ /(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i, // SemrushBot - http://www.semrush.com/bot.html - /((?:semrush|splitsignal)bot[-abcfimostw]*)\/([\w\.-]+)/i, + /((?:semrush|splitsignal)bot[-abcfimostw]*)\/?([\w\.-]*)/i, // Sogou Spider /(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i, @@ -110,7 +110,7 @@ const Crawlers = Object.freeze({ // Qihoo 360Spider // TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html // 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 + /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i ], [NAME, [TYPE, CRAWLER]] ] @@ -219,7 +219,7 @@ const Fetchers = Object.freeze({ // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // ChatGPT-User - https://platform.openai.com/docs/plugins/bot // DuckAssistBot - https://duckduckgo.com/duckassistbot/ - // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot + // Better Uptime / BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot // Google Site Verifier / Meta / Yahoo! Japan // Yandex Bots - https://yandex.com/bots /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, @@ -240,7 +240,7 @@ const Fetchers = Object.freeze({ [ // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots - /(cohere-ai|vercelbot|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|telegrambot|yandex(?:sitelinks|userproxy))/i + /((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i ], [NAME, [TYPE, FETCHER]], ] diff --git a/test/data/ua/extension/crawler.json b/test/data/ua/extension/crawler.json index 48c5865..2a4d096 100644 --- a/test/data/ua/extension/crawler.json +++ b/test/data/ua/extension/crawler.json @@ -480,6 +480,26 @@ "type" : "crawler" } }, + { + "desc" : "SemrushBot for Backlink Audit tool", + "ua" : "Mozilla/5.0 (compatible; SemrushBot-BA; +http://www.semrush.com/bot.html)", + "expect" : + { + "name" : "SemrushBot-BA", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "SemrushBot for On Page SEO Checker tool", + "ua" : "Mozilla/5.0 (compatible; SemrushBot-SI/0.97; +http://www.semrush.com/bot.html)", + "expect" : + { + "name" : "SemrushBot-SI", + "version" : "0.97", + "type" : "crawler" + } + }, { "desc" : "SemrushBot for ContentShake AI tool", "ua" : "Mozilla/5.0 (compatible; SemrushBot-OCOB/1; +https://www.semrush.com/bot/)", @@ -550,6 +570,16 @@ "type" : "crawler" } }, + { + "desc" : "Yahoo! Slurp", + "ua" : "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp) ", + "expect" : + { + "name" : "Yahoo! Slurp", + "version" : "undefined", + "type" : "crawler" + } + }, { "desc" : "YandexBot", "ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)", diff --git a/test/data/ua/extension/fetcher.json b/test/data/ua/extension/fetcher.json index 41d819e..b385428 100644 --- a/test/data/ua/extension/fetcher.json +++ b/test/data/ua/extension/fetcher.json @@ -9,6 +9,16 @@ "type" : "fetcher" } }, + { + "desc" : "Better Uptime Bot", + "ua" : "Better Uptime Bot Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36", + "expect" : + { + "name" : "Better Uptime Bot", + "version" : "undefined", + "type" : "fetcher" + } + }, { "desc" : "BingPreview", "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b", From baeac63ebeda9830834292ba2e013738bad78f1c Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 6 Mar 2025 19:17:12 +0700 Subject: [PATCH 61/73] Remover Jazzer.js fuzz testing, since the package is no longer supported & leads to failing build --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 00cbf2e..d6a3dc1 100755 --- a/package.json +++ b/package.json @@ -233,7 +233,6 @@ "devDependencies": { "@babel/parser": "7.15.8", "@babel/traverse": "7.23.2", - "@jazzer.js/core": "^1.4.0", "@playwright/test": "^1.49.0", "jshint": "~2.13.6", "mocha": "~8.2.0", From 8a05328ce09dcda4d5d0cadec77e3aa638cba7ab Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 6 Mar 2025 21:03:29 +0700 Subject: [PATCH 62/73] [extensions] Improve inapp browser detection: Slack, Yahoo! Japan --- src/extensions/ua-parser-extensions.js | 6 +++-- test/data/ua/extension/inapp.json | 32 ++++++++++++++++++++++++++ test/unit/extensions.js | 4 +++- 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/data/ua/extension/inapp.json diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 09feadf..f1da2ac 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -253,10 +253,12 @@ const Fetchers = Object.freeze({ const InApps = Object.freeze({ browser : [ // Slack - [/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]], + [/(?:slack(?=.+electron|.+ios)|chatlyio)\/([\d\.]+)/i], + [VERSION, [NAME, 'Slack'], [TYPE, INAPP]], // Yahoo! Japan - [/jp\.co\.yahoo\.android\.yjtop\/([\d\.]+)/i], [VERSION, 'Yahoo! Japan', [TYPE, INAPP]] + [/jp\.co\.yahoo\.(?:android\.yjtop|ipn\.appli)\/([\d\.]+)/i], + [VERSION, [NAME, 'Yahoo! Japan'], [TYPE, INAPP]] ] }); diff --git a/test/data/ua/extension/inapp.json b/test/data/ua/extension/inapp.json new file mode 100644 index 0000000..5512465 --- /dev/null +++ b/test/data/ua/extension/inapp.json @@ -0,0 +1,32 @@ +[ + { + "desc" : "Slack on mac", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Slack/4.39.90 Chrome/127.0.6533.72 Electron/13.1.9 Safari/537.36", + "expect" : + { + "name" : "Slack", + "version" : "4.39.90", + "type" : "inapp" + } + }, + { + "desc" : "Yahoo! Japan on Android", + "ua" : "Mozilla/5.0 (Linux; Android 13; SH-M20 Build/TKQ1.220915.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.163 Mobile Safari/537.36 YJApp-ANDROID jp.co.yahoo.android.yjtop/3.187.0", + "expect" : + { + "name" : "Yahoo! Japan", + "version" : "3.187.0", + "type" : "inapp" + } + }, + { + "desc" : "Yahoo! Japan on iOS", + "ua" : "Mozilla/5.0 (iPad; CPU OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 YJApp-IOS jp.co.yahoo.ipn.appli/4.131.0", + "expect" : + { + "name" : "Yahoo! Japan", + "version" : "4.131.0", + "type" : "inapp" + } + } +] diff --git a/test/unit/extensions.js b/test/unit/extensions.js index 0f04732..f4548f3 100644 --- a/test/unit/extensions.js +++ b/test/unit/extensions.js @@ -8,8 +8,9 @@ const clis = require('../data/ua/extension/cli.json'); const crawlers = require('../data/ua/extension/crawler.json'); const emails = require('../data/ua/extension/email.json'); const fetchers = require('../data/ua/extension/fetcher.json'); +const inapps = require('../data/ua/extension/inapp.json'); const libraries = require('../data/ua/extension/library.json'); -const { Bots, CLIs, Crawlers, Emails, Fetchers, Libraries } = require('../../src/extensions/ua-parser-extensions'); +const { Bots, CLIs, Crawlers, Emails, Fetchers, InApps, Libraries } = require('../../src/extensions/ua-parser-extensions'); describe('Extensions', () => { [ @@ -17,6 +18,7 @@ describe('Extensions', () => { ['Crawlers', crawlers, Crawlers], ['Emails', emails, Emails], ['Fetchers', fetchers, Fetchers], + ['InApps', inapps, InApps], ['Libraries', libraries, Libraries] ] .forEach((list) => { From a9b31c0f7b7e092d9afadfaf381809e6201c8d0c Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 7 Mar 2025 00:13:37 +0700 Subject: [PATCH 63/73] [extensions] Add bots: AdIdxBot, Linespider, LinkedInBot, MicrosoftPreview, OpenAI Image Downloader --- src/extensions/ua-parser-extensions.js | 17 ++- test/data/ua/extension/crawler.json | 202 ++++++++++++++++++++++--- test/data/ua/extension/fetcher.json | 20 +++ 3 files changed, 210 insertions(+), 29 deletions(-) diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index f1da2ac..761b3c8 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -42,24 +42,25 @@ const Crawlers = Object.freeze({ [ // AhrefsBot - https://ahrefs.com/robot // Amazonbot - https://developer.amazon.com/amazonbot - // Bingbot - http://www.bing.com/bingbot.htm + // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0 // CCBot - https://commoncrawl.org/faq // 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 + // LinkedInBot - http://www.linkedin.com // MJ12bot - https://mj12bot.com/ // MojeekBot - https://www.mojeek.com/bot.html // OpenAI's SearchGPT - https://platform.openai.com/docs/bots // PerplexityBot - https://perplexity.ai/perplexitybot // SeznamBot - http://napoveda.seznam.cz/seznambot-intro - /((?:ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, + /((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|linkedin|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, // Applebot - http://apple.com/go/applebot - /(applebot(?:-extended)?)\/([\w\.]+)/i, + /(applebot(?:-extended)?)\/?([\w\.]*)/i, // Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001 - /(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i, + /(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i, // ClaudeBot (Anthropic) /(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i, @@ -92,8 +93,8 @@ const Crawlers = Object.freeze({ // Yeti (Naver) /(yeti)\/([\w\.]+)/i, - // aiHitBot / Diffbot / Magpie-Crawler / Omgilibot / Webzio-Extended / Screaming Frog SEO Spider / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot - /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|(?:magpie-|velenpublicweb)crawler|webzio-extended|(?:screaming frog seo |yisou)spider)\/?([\w\.]*)/i + // aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot + /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|webzio-extended|(?:screaming frog seo |line|yisou)spider)\/?([\w\.]*)/i ], [NAME, VERSION, [TYPE, CRAWLER]], @@ -219,10 +220,10 @@ const Fetchers = Object.freeze({ // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // ChatGPT-User - https://platform.openai.com/docs/plugins/bot // DuckAssistBot - https://duckduckgo.com/duckassistbot/ - // Better Uptime / BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot + // Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot // Google Site Verifier / Meta / Yahoo! Japan // Yandex Bots - https://yandex.com/bots - /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, + /(ahrefssiteaudit|(?:bing|microsoft)preview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, // Bluesky /(bluesky) cardyb\/([\w\.]+)/i, diff --git a/test/data/ua/extension/crawler.json b/test/data/ua/extension/crawler.json index 2a4d096..8ed2d00 100644 --- a/test/data/ua/extension/crawler.json +++ b/test/data/ua/extension/crawler.json @@ -9,6 +9,16 @@ "type" : "crawler" } }, + { + "desc" : "AdIdxBot", + "ua" : "Mozilla/5.0 (compatible; adidxbot/2.0; +http://www.bing.com/bingbot.htm)", + "expect" : + { + "name" : "adidxbot", + "version" : "2.0", + "type" : "crawler" + } + }, { "desc" : "AdsBot Mobile Web", "ua" : "AdsBot-Google (+http://www.google.com/adsbot.html)", @@ -79,6 +89,16 @@ "type" : "crawler" } }, + { + "desc" : "Applebot-Extended", + "ua" : "Applebot-Extended", + "expect" : + { + "name" : "Applebot-Extended", + "version" : "undefined", + "type" : "crawler" + } + }, { "desc" : "Amazonbot", "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Amazonbot/0.1; +https://developer.amazon.com/support/amazonbot)", @@ -89,6 +109,126 @@ "type" : "crawler" } }, + { + "desc" : "Anthropic AI", + "ua" : "anthropic-ai", + "expect" : + { + "name" : "anthropic-ai", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Archive.org Bot", + "ua" : "ia_archiver/8.1 (Windows 2000 1.9; en-US;)", + "expect" : + { + "name" : "ia_archiver", + "version" : "8.1", + "type" : "crawler" + } + }, + { + "desc" : "Archive.org Bot", + "ua" : "Mozilla/5.0 (compatible; archive.org_bot/3.3.0 +https://archive.org/details/archive.org_bot)", + "expect" : + { + "name" : "archive.org_bot", + "version" : "3.3.0", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider", + "ua" : "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)", + "expect" : + { + "name" : "Baiduspider", + "version" : "2.0", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-ads", + "ua" : "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0; Baiduspider-ads) Gecko/17.0 Firefox/17.0", + "expect" : + { + "name" : "Baiduspider-ads", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-cpro", + "ua" : "Mozilla/5.0 (compatible; Baiduspider-cpro; +http://www.baidu.com/search/spider.html)", + "expect" : + { + "name" : "Baiduspider-cpro", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-favo", + "ua" : "Baiduspider-favo", + "expect" : + { + "name" : "Baiduspider-favo", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-image", + "ua" : "Baiduspider-image+(+http://www.baidu.com/search/spider.htm)", + "expect" : + { + "name" : "Baiduspider-image", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-news", + "ua" : "Baiduspider-news", + "expect" : + { + "name" : "Baiduspider-news", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-render", + "ua" : "Mozilla/5.0 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html)", + "expect" : + { + "name" : "Baiduspider-render", + "version" : "2.0", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-video", + "ua" : "Baiduspider-video", + "expect" : + { + "name" : "Baiduspider-video", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Bingbot", + "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/", + "expect" : + { + "name" : "bingbot", + "version" : "2.0", + "type" : "crawler" + } + }, { "desc" : "Bytespider", "ua" : "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.1511.1269 Mobile Safari/537.36; Bytespider", @@ -179,6 +319,16 @@ "type" : "crawler" } }, + { + "desc" : "DuckDuckBot", + "ua" : "DuckDuckBot/1.1; ( http://duckduckgo.com/duckduckbot.html)", + "expect" : + { + "name" : "DuckDuckBot", + "version" : "1.1", + "type" : "crawler" + } + }, { "desc" : "Exabot", "ua" : "Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)", @@ -339,26 +489,6 @@ "type" : "crawler" } }, - { - "desc" : "Archive.org Bot", - "ua" : "ia_archiver/8.1 (Windows 2000 1.9; en-US;)", - "expect" : - { - "name" : "ia_archiver", - "version" : "8.1", - "type" : "crawler" - } - }, - { - "desc" : "Archive.org Bot", - "ua" : "Mozilla/5.0 (compatible; archive.org_bot/3.3.0 +https://archive.org/details/archive.org_bot)", - "expect" : - { - "name" : "archive.org_bot", - "version" : "3.3.0", - "type" : "crawler" - } - }, { "desc" : "ImagesiftBot", "ua" : "Mozilla/5.0 (compatible; ImagesiftBot; +imagesift.com)", @@ -369,6 +499,26 @@ "type" : "crawler" } }, + { + "desc" : "Linespider", + "ua" : "Mozilla/5.0 (compatible; Linespider/1.1; +https://lin.ee/4dwXkTH)", + "expect" : + { + "name" : "Linespider", + "version" : "1.1", + "type" : "crawler" + } + }, + { + "desc" : "LinkedInBot", + "ua" : "LinkedInBot/1.0 (compatible; Mozilla/5.0; Apache-HttpClient +http://www.linkedin.com)", + "expect" : + { + "name" : "LinkedInBot", + "version" : "1.0", + "type" : "crawler" + } + }, { "desc" : "magpie-crawler", "ua" : "magpie-crawler/1.1 (robots-txt-checker; +http://www.brandwatch.net)", @@ -462,7 +612,7 @@ }, { "desc" : "PetalBot", - "ua" : "Mozilla/5.0 (Linux; Android 7.0;) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; PetalBot;+https://webmaster.petalsearch.com/site/petalbot) ", + "ua" : "Mozilla/5.0 (Linux; Android 7.0;) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; PetalBot;+https://webmaster.petalsearch.com/site/petalbot)", "expect" : { "name" : "PetalBot", @@ -520,6 +670,16 @@ "type" : "crawler" } }, + { + "desc" : "Sogou", + "ua" : "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", + "expect" : + { + "name" : "Sogou web spider", + "version" : "4.0", + "type" : "crawler" + } + }, { "desc" : "Teoma", "ua" : "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://sp.ask.com/docs/about/tech_crawling.html)", diff --git a/test/data/ua/extension/fetcher.json b/test/data/ua/extension/fetcher.json index b385428..fed25bc 100644 --- a/test/data/ua/extension/fetcher.json +++ b/test/data/ua/extension/fetcher.json @@ -139,6 +139,26 @@ "type" : "fetcher" } }, + { + "desc" : "MicrosoftPreview", + "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; MicrosoftPreview/2.0; +https://aka.ms/MicrosoftPreview) Chrome/W.X.Y.Z Safari/537.36", + "expect" : + { + "name" : "MicrosoftPreview", + "version" : "2.0", + "type" : "fetcher" + } + }, + { + "desc" : "Pinterestbot", + "ua" : "Mozilla/5.0 (compatible; Pinterestbot/1.0; +http://www.pinterest.com/bot.html)", + "expect" : + { + "name" : "Pinterestbot", + "version" : "1.0", + "type" : "fetcher" + } + }, { "desc" : "Rogerbot", "ua" : "Mozilla/5.0 (compatible; rogerBot/1.0; UrlCrawler; http://www.seomoz.org/dp/rogerbot)", From 367eae4c85e7b5bd70b26a73a49e79edb95db314 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 7 Mar 2025 10:14:37 +0700 Subject: [PATCH 64/73] [extensions] Add new Vehicles: `BMW`, `Jeep Wagooner` --- src/extensions/ua-parser-extensions.js | 19 +++++--- test/data/ua/extension/vehicle.json | 62 ++++++++++++++++++++++++++ test/unit/extensions.js | 44 +++++++++--------- 3 files changed, 97 insertions(+), 28 deletions(-) create mode 100644 test/data/ua/extension/vehicle.json diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 761b3c8..7c24624 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -335,15 +335,20 @@ const Libraries = Object.freeze({ const Vehicles = Object.freeze({ device : [ - [ - /dilink.+(byd) auto/i, // BYD - ], [VENDOR], [ + [/aftlbt962e2/i], // BMW + [[VENDOR, 'BMW']], - /(rivian) (r1t)/i, // Rivian - ], [VENDOR, MODEL], [ + [/dilink.+(byd) auto/i], // BYD + [VENDOR], - /vcc.+netfront/i, // Volvo - ], [[VENDOR, 'Volvo']] + [/aftlft962x3/i], // Jeep + [[VENDOR, 'Jeep'], [MODEL, 'Wagooner']], + + [/(rivian) (r1t)/i], // Rivian + [VENDOR, MODEL], + + [/vcc.+netfront/i], // Volvo + [[VENDOR, 'Volvo']] ] }); diff --git a/test/data/ua/extension/vehicle.json b/test/data/ua/extension/vehicle.json new file mode 100644 index 0000000..7800051 --- /dev/null +++ b/test/data/ua/extension/vehicle.json @@ -0,0 +1,62 @@ +[ + { + "desc" : "BMW", + "ua" : "Mozilla/5.0 (Linux; Android 9; AFTLBT962E2) AppleWebKit/537.36 (KHTML, like Gecko) Silk/118.3.1 like Chrome/118.0.5993.155 Safari/537.36", + "expect" : + { + "vendor" : "BMW", + "model" : "undefined", + "type" : "undefined" + } + }, + { + "desc" : "BYD", + "ua" : "Mozilla/5.0 (Linux; Android 10; DiLink3.0 For BYD AUTO Build/QKQ1.200816.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.186 Safari/537.36", + "expect" : + { + "vendor" : "BYD", + "model" : "undefined", + "type" : "undefined" + } + }, + { + "desc" : "Jeep", + "ua" : "Mozilla/5.0 (Linux; Android 9; AFTLFT962X3) AppleWebKit/537.36 (KHTML, like Gecko) Silk/124.5.2 like Chrome/124.0.6367.248 Safari/537.36", + "expect" : + { + "vendor" : "Jeep", + "model" : "Wagooner", + "type" : "undefined" + } + }, + { + "desc" : "Rivian", + "ua" : "Dalvik/2.1.0 (Linux; U; Android 10; Rivian R1T Build/QQ3A.200605.002)", + "expect" : + { + "vendor" : "Rivian", + "model" : "R1T", + "type" : "undefined" + } + }, + { + "desc" : "Tesla", + "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/79.0.3945.130 Chrome/79.0.3945.130 Safari/537.36 Tesla/2020.36.16-3e9e4e8dd287", + "expect" : + { + "vendor" : "Tesla", + "model" : "undefined", + "type" : "embedded" + } + }, + { + "desc" : "Volvo", + "ua" : "Mozilla/5.0 (VCC; 1.0; like Gecko) NetFront/4.2", + "expect" : + { + "vendor" : "Volvo", + "model" : "undefined", + "type" : "undefined" + } + } +] diff --git a/test/unit/extensions.js b/test/unit/extensions.js index f4548f3..417ed8a 100644 --- a/test/unit/extensions.js +++ b/test/unit/extensions.js @@ -4,31 +4,33 @@ const parseJS = require('@babel/parser').parse; const traverse = require('@babel/traverse').default; const safe = require('safe-regex'); const { UAParser } = require('../../src/main/ua-parser'); -const clis = require('../data/ua/extension/cli.json'); -const crawlers = require('../data/ua/extension/crawler.json'); -const emails = require('../data/ua/extension/email.json'); -const fetchers = require('../data/ua/extension/fetcher.json'); -const inapps = require('../data/ua/extension/inapp.json'); -const libraries = require('../data/ua/extension/library.json'); -const { Bots, CLIs, Crawlers, Emails, Fetchers, InApps, Libraries } = require('../../src/extensions/ua-parser-extensions'); +const { Bots, CLIs, Crawlers, Emails, Fetchers, InApps, Libraries, Vehicles } = require('../../src/extensions/ua-parser-extensions'); describe('Extensions', () => { [ - ['CLIs', clis, CLIs], - ['Crawlers', crawlers, Crawlers], - ['Emails', emails, Emails], - ['Fetchers', fetchers, Fetchers], - ['InApps', inapps, InApps], - ['Libraries', libraries, Libraries] + ['CLIs', 'cli', CLIs], + ['Crawlers', 'crawler', Crawlers], + ['Emails', 'email', Emails], + ['Fetchers', 'fetcher', Fetchers], + ['InApps', 'inapp', InApps], + ['Libraries', 'library', Libraries], + ['Vehicles', 'vehicle', Vehicles] ] - .forEach((list) => { - describe(list[0], () => { - list[1].forEach((agent) => { - it(`Can detect ${agent.desc}: "${agent.ua}"`, () => { - let browser = UAParser(agent.ua, list[2]).browser; - assert.strictEqual(String(browser.name), agent.expect.name); - assert.strictEqual(String(browser.version), agent.expect.version); - assert.strictEqual(String(browser.type), agent.expect.type); + .forEach(([desc, path, ext]) => { + const tests = require(`../data/ua/extension/${path}.json`); + describe(desc, () => { + tests.forEach((test) => { + it(`Can detect ${test.desc}: "${test.ua}"`, () => { + const { browser, device } = UAParser(test.ua, ext); + if ('browser' in ext) { + assert.strictEqual(String(browser.name), test.expect.name); + assert.strictEqual(String(browser.version), test.expect.version); + assert.strictEqual(String(browser.type), test.expect.type); + } else if ('device' in ext) { + assert.strictEqual(String(device.vendor), test.expect.vendor); + assert.strictEqual(String(device.model), test.expect.model); + assert.strictEqual(String(device.type), test.expect.type); + } }); }); }); From 0cf44773b144b120fb72be5d565658225962e344 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 8 Mar 2025 11:37:54 +0700 Subject: [PATCH 65/73] Improve device detection: Archos --- src/main/ua-parser.js | 9 +- test/data/ua/device/archos.json | 227 ++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 test/data/ua/device/archos.json diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 31c1c33..85cbec5 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -713,6 +713,14 @@ /droid.+; (a(?:015|06[35]|142p?))/i ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [ + // Archos + /; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i, + /archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i + ], [MODEL, [VENDOR, 'Archos'], [TYPE, TABLET]], [ + /archos ([\w ]+)( b|\))/i, + /; (ac[3-6]\d\w{2,8})( b|\))/i + ], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [ + // MIXED /(imo) (tab \w+)/i, // IMO /(infinix) (x1101b?)/i // Infinix XPad @@ -728,7 +736,6 @@ ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kobo)\s(ereader|touch)/i, // Kobo - /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i // Kindle ], [VENDOR, MODEL, [TYPE, TABLET]], [ diff --git a/test/data/ua/device/archos.json b/test/data/ua/device/archos.json new file mode 100644 index 0000000..53628c5 --- /dev/null +++ b/test/data/ua/device/archos.json @@ -0,0 +1,227 @@ +[ + { + "desc": "Archos 5", + "ua": "Mozilla/5.0 (Linux; U; Android 1.6; fr-fr; Archos5 Build/Donut) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1", + "expect": { + "vendor": "Archos", + "model": "5", + "type": "tablet" + } + }, + { + "desc": "Archos 40b Titanium Surround", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Archos 40b Titanium Surround Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "40b Titanium Surround", + "type": "mobile" + } + }, + { + "desc": "Archos 40c Titanium v2", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ARCHOS 40C TIv2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "40C TIv2", + "type": "mobile" + } + }, + { + "desc": "Archos 45 Neon", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Archos 45 Neon Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "45 Neon", + "type": "mobile" + } + }, + { + "desc": "Archos 45 Neon", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; AC45NE Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 YaBrowser/15.6.2311.6088.00 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC45NE", + "type": "mobile" + } + }, + { + "desc": "Archos 45B Helium", + "ua": "Mozilla/5.0 (Linux; Android 7.0; AC45BHE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.109 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC45BHE", + "type": "mobile" + } + }, + { + "desc": "Archos 45B Titanium", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Archos 45B Titanium) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "45B Titanium", + "type": "mobile" + } + }, + { + "desc": "Archos 50 Cesium", + "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; ARCHOS; AC50CE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", + "expect": { + "vendor": "Archos", + "model": "AC50CE", + "type": "mobile" + } + }, + { + "desc": "Archos 50B Helium 4G", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; AC50BHE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC50BHE", + "type": "mobile" + } + }, + { + "desc": "Archos 55 diamond Selfie", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Archos 55 diamond Selfie Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.91 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "55 diamond Selfie", + "type": "mobile" + } + }, + { + "desc": "Archos 80 G9", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; zh-tw; ARCHOS 80G9 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "Archos", + "model": "80G9", + "type": "tablet" + } + }, + { + "desc": "Archos 80 Xenon", + "ua": "Mozilla/5.0 (Linux; Android 4.1.2; Archos 80 Xenon Build/JZO54K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Safari/537.36 OPR/50.6.2426.201126", + "expect": { + "vendor": "Archos", + "model": "80 Xenon", + "type": "tablet" + } + }, + { + "desc": "Archos 97c Platinum", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Archos 97c Platinum Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "97c Platinum", + "type": "tablet" + } + }, + { + "desc": "Archos 101 Access 3G V2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Archos Access 101 3G V2 Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.130 Safari/537.36[FBAN/EMA;FBLC/pt_PT;FBAV/360.0.0.7.53;]", + "expect": { + "vendor": "Archos", + "model": "Access 101 3G V2", + "type": "tablet" + } + }, + { + "desc": "Archos 101 Oxygen 4G", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Archos 101 Oxygen 4G Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.71 Safari/537.36 [FB_IAB/FB4A;FBAV/374.0.0.20.109;]", + "expect": { + "vendor": "Archos", + "model": "101 Oxygen 4G", + "type": "tablet" + } + }, + { + "desc": "Archos 101 Platinum 3G V2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; AC101PL3GV2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC101PL3GV2", + "type": "tablet" + } + }, + { + "desc": "Archos 101B Helium 4G", + "ua": "Mozilla/5.0 (Linux; Android 6.0; AC101BHE Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC101BHE", + "type": "tablet" + } + }, + { + "desc": "Archos 101s Oxygen Ardoiz", + "ua": "Mozilla/5.0 (Linux; Android 9; Archos Oxygen 101S ARDOIZ Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.102 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "Oxygen 101S ARDOIZ", + "type": "tablet" + } + }, + { + "desc": "Archos GAMEPAD2", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; ARCHOS GAMEPAD2 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.94 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "GAMEPAD2", + "type": "tablet" + } + }, + { + "desc": "Archos Hello 7", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Archos Hello 7 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.53 Safari/537.36 GoogleApp/13.24.9.26.arm64", + "expect": { + "vendor": "Archos", + "model": "Hello 7", + "type": "tablet" + } + }, + { + "desc": "Archos Sense 101 X", + "ua": "Mozilla/5.0 (Linux; arm; Android 7.0; Archos Sense 101 X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 YaBrowser/20.2.0.215.01 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "Sense 101 X", + "type": "tablet" + } + }, + { + "desc": "Archos T101 FHD WiFi", + "ua": "Mozilla/5.0 (Linux; Android 13; ARCHOS T101 FHD WiFi Build/T00624; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.159 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "T101 FHD WiFi", + "type": "tablet" + } + }, + { + "desc": "Archos Tikeasy 10d", + "ua": "Mozilla/5.0 (Linux; Android 13; Tikeasy 10d Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.260 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "Tikeasy 10d", + "type": "tablet" + } + }, + { + "desc": "Archos T96 WIFI", + "ua": "Mozilla/5.0 (Linux; Android 11; ARCHOS T96 WIFI_EEA Build/RP1A.201005.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.78 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "T96 WIFI_EEA", + "type": "tablet" + } + }, + { + "desc": "Archos X67 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; X67 5G Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.58 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "X67 5G", + "type": "tablet" + } + } +] \ No newline at end of file From 30c0b20c207405359a0fabe0ab9b78df78dae298 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 8 Mar 2025 12:42:20 +0700 Subject: [PATCH 66/73] Improve device detection: LG --- src/main/ua-parser.js | 8 +++++--- test/data/ua/device/lg.json | 9 +++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 85cbec5..f2a1536 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -606,7 +606,7 @@ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, - /\blg[-e;\/ ]+((?!browser|netcast|android tv|watch)\w+)/i, + /\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch))(\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ @@ -763,7 +763,9 @@ ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ - /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV + /tcast.+(lg)e?. ([-\w]+)/i // LG SmartTV + ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ + /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ @@ -938,7 +940,7 @@ /(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [ // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen - /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/; ]?([\d\.]*)/i + /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/\.; ]?([\d\.]*)/i ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ diff --git a/test/data/ua/device/lg.json b/test/data/ua/device/lg.json index b47e99f..9d63ac1 100644 --- a/test/data/ua/device/lg.json +++ b/test/data/ua/device/lg.json @@ -134,6 +134,15 @@ "type": "smarttv" } }, + { + "desc": "LG Smart TV", + "ua": "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.41 (KHTML, like Gecko) Large Screen Safari/537.41 LG Browser/7.00.00(LGE; 42LB670V-ZA; 05.05.90; 1); webOS.TV-2014; LG NetCast.TV-2013 Compatible (LGE, 42LB670V-ZA, wireless)", + "expect": { + "vendor": "LG", + "model": "42LB670V-ZA", + "type": "smarttv" + } + }, { "desc": "LG Android TV", "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; LG Android TV Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", From 2d26eada9adf31c2af34b85e98c105dbbfc5de6c Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 8 Mar 2025 12:49:29 +0700 Subject: [PATCH 67/73] Add new browser: LG Browser --- src/enums/ua-parser-enums.d.ts | 1 + src/enums/ua-parser-enums.js | 1 + src/main/ua-parser.js | 4 ++-- test/data/ua/browser/browser-all.json | 10 +++++----- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts index c279436..5f7a734 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -73,6 +73,7 @@ export const Browser: Readonly<{ KINDLE: "Kindle"; LENOVO: "Smart Lenovo Browser"; LADYBIRD: "Ladybird"; + LG: "LG Browser"; LIBREWOLF: "LibreWolf"; LIEBAO: "LBBROWSER"; LINE: "Line"; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 25b8de5..d5cdc42 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -78,6 +78,7 @@ const Browser = Object.freeze({ KINDLE: 'Kindle', LENOVO: 'Smart Lenovo Browser', LADYBIRD: 'Ladybird', + LG: 'LG Browser', LIBREWOLF: 'LibreWolf', LIEBAO: 'LBBROWSER', LINE: 'Line', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index f2a1536..1b22b7e 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -353,8 +353,8 @@ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer - // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon - /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon)\/([-\w\.]+)/i, + // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|lg browser)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115 /(weibo)__([\d\.]+)/i // Weibo diff --git a/test/data/ua/browser/browser-all.json b/test/data/ua/browser/browser-all.json index 05dfd4f..9d0344b 100644 --- a/test/data/ua/browser/browser-all.json +++ b/test/data/ua/browser/browser-all.json @@ -1067,13 +1067,13 @@ } }, { - "desc" : "LibreWolf", - "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 LibreWolf/91.0", + "desc" : "LG Browser", + "ua" : "Mozilla/5.0 (Unknown; Linux armv7l) AppleWebKit/537.1+ (KHTML, like Gecko) Safari/537.1+ LG Browser/6.00.00(+mouse+3D+SCREEN+TUNER; LGE; 47LA621V-ZD; 04.28.17; 0x00000001;); LG NetCast.TV-2013 /04.28.17 (LG, 47LA621V-ZD, wired)", "expect" : { - "name" : "LibreWolf", - "version" : "91.0", - "major" : "91" + "name" : "LG Browser", + "version" : "6.00.00", + "major" : "6" } }, { From 8f545f9e3fd99ca2890bc1f7d6b92260eca35c0f Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 8 Mar 2025 16:18:31 +0700 Subject: [PATCH 68/73] Add new browser: Dooble, Ecosia, Otter, qutebrowser, Surf --- src/enums/ua-parser-enums.d.ts | 5 +++ src/enums/ua-parser-enums.js | 5 +++ src/main/ua-parser.js | 8 ++-- test/data/ua/browser/browser-all.json | 60 +++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts index 5f7a734..9ea1ffe 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -32,9 +32,11 @@ export const Browser: Readonly<{ DAUM: "Daum"; DILLO: "Dillo"; DOLPHIN: "Dolphin"; + DOOBLE: 'Dooble', DORIS: "Doris"; DRAGON: "Dragon"; DUCKDUCKGO: "DuckDuckGo"; + ECOSIA: "Ecosia"; EDGE: "Edge"; EPIPHANY: "Epiphany"; FACEBOOK: "Facebook"; @@ -103,6 +105,7 @@ export const Browser: Readonly<{ OPERA_MOBI: "Opera Mobi"; OPERA_TABLET: "Opera Tablet"; OPERA_TOUCH: "Opera Touch"; + OTTER: "Otter"; OVI: "OviBrowser"; PALEMOON: "PaleMoon"; PHANTOMJS: "PhantomJS"; @@ -114,6 +117,7 @@ export const Browser: Readonly<{ QQ_LITE: "QQBrowserLite"; QUARK: "Quark"; QUPZILLA: "QupZilla"; + QUTEBROWSER: "qutebrowser"; REKONQ: "rekonq"; ROCKMELT: "Rockmelt"; SAFARI: "Safari"; @@ -130,6 +134,7 @@ export const Browser: Readonly<{ SNAPCHAT: "Snapchat"; SOGOU_EXPLORER: "Sogou Explorer"; SOGOU_MOBILE: "Sogou Mobile"; + SURF: "Surf"; SWIFTFOX: "Swiftfox"; TESLA: "Tesla"; TIKTOK: "TikTok"; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index d5cdc42..0900357 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -37,9 +37,11 @@ const Browser = Object.freeze({ DAUM: 'Daum', DILLO: 'Dillo', DOLPHIN: 'Dolphin', + DOOBLE: 'Dooble', DORIS: 'Doris', DRAGON: 'Dragon', DUCKDUCKGO: 'DuckDuckGo', + ECOSIA: 'Ecosia', EDGE: 'Edge', EPIPHANY: 'Epiphany', FACEBOOK: 'Facebook', @@ -108,6 +110,7 @@ const Browser = Object.freeze({ OPERA_MOBI: 'Opera Mobi', OPERA_TABLET: 'Opera Tablet', OPERA_TOUCH: 'Opera Touch', + OTTER: 'Otter', OVI: 'OviBrowser', PALEMOON: 'PaleMoon', PHANTOMJS: 'PhantomJS', @@ -119,6 +122,7 @@ const Browser = Object.freeze({ QQ_LITE: 'QQBrowserLite', QUARK: 'Quark', QUPZILLA: 'QupZilla', + QUTEBROWSER: 'qutebrowser', REKONQ: 'rekonq', ROCKMELT: 'Rockmelt', SAFARI: 'Safari', @@ -135,6 +139,7 @@ const Browser = Object.freeze({ SNAPCHAT: 'Snapchat', SOGOU_EXPLORER: 'Sogou Explorer', SOGOU_MOBILE: 'Sogou Mobile', + SURF: 'Surf', SWIFTFOX: 'Swiftfox', TESLA: 'Tesla', TIKTOK: 'TikTok', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 1b22b7e..4966699 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -353,11 +353,11 @@ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer - // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser - /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|lg browser)\/([-\w\.]+)/i, + // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon - /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115 - /(weibo)__([\d\.]+)/i // Weibo + /(heytap|ovi|115|surf)browser\/([\d\.]+)/i, // HeyTap/Ovi/115/Surf + /(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i // Ecosia/Weibo ], [NAME, VERSION], [ /quark(?:pc)?\/([-\w\.]+)/i // Quark ], [VERSION, [NAME, 'Quark']], [ diff --git a/test/data/ua/browser/browser-all.json b/test/data/ua/browser/browser-all.json index 9d0344b..3fc0e5e 100644 --- a/test/data/ua/browser/browser-all.json +++ b/test/data/ua/browser/browser-all.json @@ -511,6 +511,16 @@ "major" : "2" } }, + { + "desc" : "Dooble", + "ua" : "Mozilla/5.0 (X11; Haiku BePC) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.15.17 Chrome/87.0.4280.144 Safari/537.36 Dooble/2023.12.25 Dooble/2023.12.25", + "expect" : + { + "name" : "Dooble", + "version" : "2023.12.25", + "major" : "2023" + } + }, { "desc" : "Doris", "ua" : "Doris/1.15 [en] (Symbian)", @@ -541,6 +551,26 @@ "major" : "5" } }, + { + "desc" : "Ecosia on Android", + "ua" : "Mozilla/5.0 (Linux; Android 10; SM-G975U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36 (Ecosia android@85.0.4183.127)", + "expect" : + { + "name" : "Ecosia", + "version" : "85.0.4183.127", + "major" : "85" + } + }, + { + "desc" : "Ecosia on iOS", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 (Ecosia ios@3.0.1.533)", + "expect" : + { + "name" : "Ecosia", + "version" : "3.0.1.533", + "major" : "3" + } + }, { "desc" : "Epiphany", "ua" : "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7) Gecko/20040628 Epiphany/1.2.6", @@ -1006,6 +1036,16 @@ "major" : "5" } }, + { + "desc" : "Otter", + "ua" : "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/602.1 (KHTML, like Gecko) Otter/1.0.81", + "expect" : + { + "name" : "Otter", + "version" : "1.0.81", + "major" : "1" + } + }, { "desc" : "PicoBrowser", "ua" : "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", @@ -1066,6 +1106,16 @@ "major" : "9" } }, + { + "desc" : "Surf Browser", + "ua" : "Mozilla/5.0 (Android 6.0; HUAWEI ALE-L21) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36 SurfBrowser/3.0", + "expect" : + { + "name" : "Surf", + "version" : "3.0", + "major" : "3" + } + }, { "desc" : "LG Browser", "ua" : "Mozilla/5.0 (Unknown; Linux armv7l) AppleWebKit/537.1+ (KHTML, like Gecko) Safari/537.1+ LG Browser/6.00.00(+mouse+3D+SCREEN+TUNER; LGE; 47LA621V-ZD; 04.28.17; 0x00000001;); LG NetCast.TV-2013 /04.28.17 (LG, 47LA621V-ZD, wired)", @@ -1628,6 +1678,16 @@ "major" : "1" } }, + { + "desc" : "qutebrowser", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) qutebrowser/2.4.0 QtWebEngine/5.15.6 Chrome/95.0.4628.2 Safari/537.36", + "expect" : + { + "name" : "qutebrowser", + "version" : "2.4.0", + "major" : "2" + } + }, { "desc" : "Rekonq 2", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.21 (KHTML, like Gecko) rekonq/2.2.1 Safari/537.21", From f7f64a31eae0ca20d9cfa28bd2732e1a110ca16a Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 11 Mar 2025 17:50:36 +0700 Subject: [PATCH 69/73] [extensions] Detect OS from WhatsApp user agent --- src/extensions/ua-parser-extensions.js | 8 ++++++++ test/unit/extensions.js | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 7c24624..e8e3f6e 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -244,6 +244,11 @@ const Fetchers = Object.freeze({ /((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i ], [NAME, [TYPE, FETCHER]], + ], + + os : [ + [/whatsapp\/[\d\.]+ (a|i)/i], + [[NAME, os => os == 'A' ? 'Android' : 'iOS' ]] ] }); @@ -362,6 +367,9 @@ const Bots = Object.freeze({ ...Crawlers.browser, ...Fetchers.browser, ...Libraries.browser + ], + os : [ + ...Fetchers.os ] }); diff --git a/test/unit/extensions.js b/test/unit/extensions.js index 417ed8a..9f1fa96 100644 --- a/test/unit/extensions.js +++ b/test/unit/extensions.js @@ -61,6 +61,12 @@ describe('Extensions', () => { major: '1', type: 'fetcher' }); + + const whatsapp = "WhatsApp/2.0 A"; + assert.deepEqual(new UAParser(whatsapp, Fetchers).getOS(), { + name : 'Android', + version : undefined + }); }); describe('Merge', () => { From c6f8ba3788e4348e56063642d62ef7d809888524 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 11 Mar 2025 17:57:47 +0700 Subject: [PATCH 70/73] Add new device: Facebook Portal TV --- src/main/ua-parser.js | 2 ++ test/data/ua/device/facebook.json | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 4966699..13bb4cc 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -777,6 +777,8 @@ ], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast, Linux-based or unknown ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ + /(portaltv)/i // Facebook Portal TV + ], [MODEL, [VENDOR, FACEBOOK], [TYPE, SMARTTV]], [ /droid.+aft(\w+)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /(shield \w+ tv)/i // Nvidia Shield TV diff --git a/test/data/ua/device/facebook.json b/test/data/ua/device/facebook.json index 01e1c97..f08f81f 100644 --- a/test/data/ua/device/facebook.json +++ b/test/data/ua/device/facebook.json @@ -34,5 +34,14 @@ "model": "Quest Pro", "type": "xr" } + }, + { + "desc": "Portal TV", + "ua": "Mozilla/5.0 (Linux; Android 9; PortalTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.120 Mobile Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "PortalTV", + "type": "smarttv" + } } ] \ No newline at end of file From f93cb043f589b15e375458633549e079b2c5ac12 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 11 Mar 2025 18:07:46 +0700 Subject: [PATCH 71/73] Improve device detection for Meta Quest --- src/main/ua-parser.js | 2 +- test/unit/helpers.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 13bb4cc..5172007 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -847,7 +847,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [ /(pico) (4|neo3(?: link|pro)?)/i // Pico ], [VENDOR, MODEL, [TYPE, XR]], [ - /; (quest( \d| pro)?)/i // Oculus Quest + /(quest( \d| pro)?s?).+vr/i // Meta Quest ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [ /////////////////// diff --git a/test/unit/helpers.js b/test/unit/helpers.js index 95ce871..127133b 100644 --- a/test/unit/helpers.js +++ b/test/unit/helpers.js @@ -9,13 +9,11 @@ describe('getDeviceVendor', () => { const modelSM = 'SM-A605G'; const modelRedmi = 'Redmi Note 8'; const modelNexus = 'Nexus 6P'; - const modelQuest = 'Quest 3'; const modelAquos = 'AQUOS-TVX19B'; assert.equal(getDeviceVendor(modelSM), 'Samsung'); assert.equal(getDeviceVendor(modelRedmi), 'Xiaomi'); assert.equal(getDeviceVendor(modelNexus), 'Huawei'); - assert.equal(getDeviceVendor(modelQuest), 'Facebook'); assert.equal(getDeviceVendor(modelAquos), 'Sharp'); }); }); From 6a41513df4f92359a2917b1349372c372da6d1c7 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 11 Mar 2025 22:39:21 +0700 Subject: [PATCH 72/73] Add new device vendor: BLU --- src/enums/ua-parser-enums.d.ts | 1 + src/enums/ua-parser-enums.js | 1 + src/main/ua-parser.js | 7 ++- test/data/ua/device/alcatel.json | 11 +++- test/data/ua/device/blu.json | 101 +++++++++++++++++++++++++++++++ test/data/ua/device/hmd.json | 9 +++ test/data/ua/device/tcl.json | 9 +++ 7 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 test/data/ua/device/blu.json diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts index 9ea1ffe..907f469 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -16,6 +16,7 @@ export const Browser: Readonly<{ BAIDU: "Baidu Browser"; BASILISK: "Basilisk"; BLAZER: "Blazer"; + BLU: "BLU"; BOLT: "Bolt"; BOWSER: "Bowser"; BRAVE: "Brave"; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 0900357..d28596d 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -21,6 +21,7 @@ const Browser = Object.freeze({ BAIDU: 'Baidu Browser', BASILISK: 'Basilisk', BLAZER: 'Blazer', + BLU: 'BLU', BOLT: 'Bolt', BOWSER: 'Bowser', BRAVE: 'Brave', diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index 5172007..f950c5d 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -585,8 +585,11 @@ /\b(opd2(\d{3}a?))(?: bui|\))/i ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '203'], '*' : OPPO }], [TYPE, TABLET]], [ + // BLU Vivo Series + /(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i + ], [MODEL, [VENDOR, 'BLU'], [TYPE, MOBILE]], [ // Vivo - /vivo (\w+)(?: bui|\))/i, + /; vivo (\w+)(?: bui|\))/i, /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ @@ -728,7 +731,7 @@ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan - /; (hmd|imo) ([\w ]+?)(?: bui|\))/i, // HMD/IMO + /; (blu|hmd|imo|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/TCL /(hp) ([\w ]+\w)/i, // HP iPAQ /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i, // Lenovo diff --git a/test/data/ua/device/alcatel.json b/test/data/ua/device/alcatel.json index edfdfcd..3cd613e 100644 --- a/test/data/ua/device/alcatel.json +++ b/test/data/ua/device/alcatel.json @@ -1,6 +1,15 @@ [ { - "desc": "Alcatel", + "desc": "Alcatel 4056W", + "ua": "Mozilla/5.0 (Mobile; ALCATEL 4056W; rv:84.0) Gecko/84.0 Firefox/84.0 KAIOS/3.0", + "expect": { + "vendor": "ALCATEL", + "model": "4056W", + "type": "mobile" + } + }, + { + "desc": "Alcatel A564C", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ALCATEL A564C Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", "expect": { "vendor": "ALCATEL", diff --git a/test/data/ua/device/blu.json b/test/data/ua/device/blu.json new file mode 100644 index 0000000..969d086 --- /dev/null +++ b/test/data/ua/device/blu.json @@ -0,0 +1,101 @@ +[ + { + "desc": "BLU Grand X LTE", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BLU Grand X LTE Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "Grand X LTE", + "type": "mobile" + } + }, + { + "desc": "BLU Neo Energy Mini", + "ua": "Mozilla/5.0 (Linux; Android 10; BLU_NEO_ENERGY_MINI Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.54 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "NEO_ENERGY_MINI", + "type": "mobile" + } + }, + { + "desc": "BLU NEO X PLUS", + "ua": "Mozilla/5.0 (Linux; Android 5.1; BLU NEO X PLUS Build/N090U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "NEO X PLUS", + "type": "mobile" + } + }, + { + "desc": "BLU STUDIO X MINI", + "ua": "Mozilla/5.0 (Linux; Android 5.1; BLU STUDIO X MINI Build/S0150UU) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.93 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "STUDIO X MINI", + "type": "mobile" + } + }, + { + "desc": "BLU Tank Mega", + "ua": "Mozilla/5.0 (Mobile; BLU_TankMega_3G; rv:48.0; CAEN) Gecko/48.0 Firefox/48.0 KAIOS/2.5.1.1", + "expect": { + "vendor": "BLU", + "model": "TankMega_3G", + "type": "mobile" + } + }, + { + "desc": "BLU TOUCHBOOK G7", + "ua": "Mozilla/5.0 (Linux; Android 5.0; BLU TOUCHBOOK G7 Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.107 Safari/537.36 OPR/29.0.1809.91837", + "expect": { + "vendor": "BLU", + "model": "TOUCHBOOK G7", + "type": "mobile" + } + }, + { + "desc": "BLU Vivo 5 Mini", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Vivo 5 Mini Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "Vivo 5 Mini", + "type": "mobile" + } + }, + { + "desc": "BLU VIVO AIR LTE", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; BLU VIVO AIR LTE Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.107 Mobile Safari/537.36 OPR/29.0.1809.91837", + "expect": { + "vendor": "BLU", + "model": "VIVO AIR LTE", + "type": "mobile" + } + }, + { + "desc": "BLU VIVO GO", + "ua": "Mozilla/5.0 (Linux; U; Android 9; VIVO GO Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/72.0.3626.121 Mobile Safari/537.36 OPR/50.0.2254.149182", + "expect": { + "vendor": "BLU", + "model": "VIVO GO", + "type": "mobile" + } + }, + { + "desc": "BLU Vivo One Plus 2019", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Vivo One Plus 2019 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/277.0.0.41.126;]", + "expect": { + "vendor": "BLU", + "model": "Vivo One Plus 2019", + "type": "mobile" + } + }, + { + "desc": "BLU VIVO SELFIE", + "ua": "Mozilla/5.0 (Linux; U; Android 5.0; es-LA; BLU VIVO SELFIE Build/LRX21M) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/11.3.5.972 U3/0.8.0 Mobile Safari/534.30", + "expect": { + "vendor": "BLU", + "model": "VIVO SELFIE", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/hmd.json b/test/data/ua/device/hmd.json index 2ca10a1..a7d38e2 100644 --- a/test/data/ua/device/hmd.json +++ b/test/data/ua/device/hmd.json @@ -1,4 +1,13 @@ [ + { + "desc": "HMD Barbie Phone", + "ua": "Mozilla/5.0 (Mobile; HMD Barbie Phone; rv:84.0) Gecko/84.0 Firefox/84.0 KAIOS/3.1", + "expect": { + "vendor": "HMD", + "model": "Barbie Phone", + "type": "mobile" + } + }, { "desc": "HMD Pulse", "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", diff --git a/test/data/ua/device/tcl.json b/test/data/ua/device/tcl.json index 1ea07a3..8c80537 100644 --- a/test/data/ua/device/tcl.json +++ b/test/data/ua/device/tcl.json @@ -296,6 +296,15 @@ "type": "mobile" } }, + { + "desc": "TCL 4056S", + "ua": "Mozilla/5.0 (Mobile; TCL 4056S; rv:84.0) Gecko/84.0 Firefox/84.0 KAIOS/3.0", + "expect": { + "vendor": "TCL", + "model": "4056S", + "type": "mobile" + } + }, { "desc": "TCL A3", "ua": "Mozilla/5.0 (Linux; Android 11; A509DL Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Mobile Safari/537.36 GSA/13.18.7.23.arm64", From af8acf9078e5952a496d395464af8178ad55ccaf Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 15 Mar 2025 00:37:56 +0700 Subject: [PATCH 73/73] Bump version `2.0.3` --- CHANGELOG.md | 18 + dist/ua-parser.min.js | 6 +- dist/ua-parser.min.mjs | 6 +- dist/ua-parser.pack.js | 6 +- dist/ua-parser.pack.mjs | 6 +- package-lock.json | 1588 +--------------------- package.json | 2 +- src/enums/ua-parser-enums.d.ts | 2 +- src/enums/ua-parser-enums.js | 2 +- src/enums/ua-parser-enums.mjs | 10 +- src/extensions/ua-parser-extensions.d.ts | 2 +- src/extensions/ua-parser-extensions.js | 2 +- src/extensions/ua-parser-extensions.mjs | 65 +- src/helpers/ua-parser-helpers.d.ts | 2 +- src/helpers/ua-parser-helpers.js | 2 +- src/helpers/ua-parser-helpers.mjs | 5 +- src/main/ua-parser.d.ts | 2 +- src/main/ua-parser.js | 6 +- src/main/ua-parser.mjs | 48 +- 19 files changed, 132 insertions(+), 1648 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f62d6ac..9f2fa9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,24 @@ --- +## Version 2.0.3 + +- Add new browser: Dooble, Ecosia, LG Browser, Otter, qutebrowser, Surf +- Add new device: BLU, Facebook Portal TV +- Improve device detection: Archos, LG, Meta Quest +- Remove jazzer.js fuzz test +- Improve `withClientHints()`: + - Browser naming adjustments: + - `HuaweiBrowser` => `Huawei Browser` + - `Miui Browser` => `MIUI Browser` + - `OperaMobile` => `Opera Mobi` + - `YaBrowser` => `Yandex` +- `extensions` submodule: + - Add new Crawler: AdIdxBot, Linespider, LinkedInBot, OpenAI Image Downloader, SemrushBot, Yahoo! Slurp + - Add new Fetcher: Better Uptime Bot, Google-PageRenderer, GoogleImageProxy, MicrosoftPreview, Snap URL Preview, SkypeUriPreview, TelegramBot + - Add new Vehicles: BMW, Jeep + - Add OS detection of WhatsApp user-agent + ## Version 2.0.2 - Fix TypeScript dependency issue diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 02d8a82..0c7f407 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.2 - Copyright © 2012-2024 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman AGPLv3 License */ -(function(window,undefined){"use strict";var LIBVERSION="2.0.2",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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.3",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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 diff --git a/dist/ua-parser.min.mjs b/dist/ua-parser.min.mjs index 6def7c8..b86273f 100644 --- a/dist/ua-parser.min.mjs +++ b/dist/ua-parser.min.mjs @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.2 - Copyright © 2012-2024 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman AGPLv3 License */ -var LIBVERSION="2.0.2",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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.3",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(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1: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)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{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{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 in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=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 diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 6807b0e..ab102f1 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.2 - Copyright © 2012-2024 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman AGPLv3 License */ -((i,l)=>{function I(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Pi,e):Pi,N.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Ri(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 Ri(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>M?Hi(i,M):i),this}]]).setUA(r),this):new P(i,e,t).getResult()}P.VERSION="2.0.2",P.BROWSER=I([v,y,B,k]),P.CPU=I([C]),P.DEVICE=I([T,x,k,G,S,e,r,t,D]),P.ENGINE=P.OS=I([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=P:exports).UAParser=P:typeof define===V&&define.amd?define(function(){return P}):Ti&&(i.UAParser=P);var Vi,Li=Ti&&(i.jQuery||i.Zepto);Li&&!Li.ua&&(Vi=new P,Li.ua=Vi.getResult(),Li.ua.get=function(){return Vi.getUA()},Li.ua.set=function(i){Vi.setUA(i);var e,t=Vi.getResult();for(e in t)Li.ua[e]=t[e]})})("object"==typeof window?window:this); \ No newline at end of file +((i,l)=>{function U(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Ii,e):Ii,j.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Bi(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 Bi(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>E?Hi(i,E):i),this}]]).setUA(r),this):new I(i,e,t).getResult()}I.VERSION="2.0.3",I.BROWSER=U([v,y,L,k]),I.CPU=U([C]),I.DEVICE=U([T,x,k,G,S,e,r,t,D]),I.ENGINE=I.OS=U([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=I:exports).UAParser=I:typeof define===R&&define.amd?define(function(){return I}):Ti&&(i.UAParser=I);var Ri,Vi=Ti&&(i.jQuery||i.Zepto);Vi&&!Vi.ua&&(Ri=new I,Vi.ua=Ri.getResult(),Vi.ua.get=function(){return Ri.getUA()},Vi.ua.set=function(i){Ri.setUA(i);var e,t=Ri.getResult();for(e in t)Vi.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 5cc94b7..6c16240 100644 --- a/dist/ua-parser.pack.mjs +++ b/dist/ua-parser.pack.mjs @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.2 - Copyright © 2012-2024 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman AGPLv3 License */ -function M(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(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})(Ei,e):Ei,N.call(this,[["getBrowser",(n=function(i){return i==f?function(){return new Ri(i,r,s,a).set("ua",r).set(c,this.getBrowser()).set(u,this.getCPU()).set(h,this.getDevice()).set(p,this.getEngine()).set(m,this.getOS()).get()}:function(){return new Ri(i,r,s[i],a).parseUA().get()}})(c)],["getCPU",n(u)],["getDevice",n(h)],["getEngine",n(p)],["getOS",n(m)],["getResult",n(f)],["getUA",function(){return r}],["setUA",function(i){return A(i)&&(r=i.length>P?Ai(i,P):i),this}]]).setUA(r),this):new I(i,e,t).getResult()}I.VERSION="2.0.2",I.BROWSER=M([g,x,C,v]),I.CPU=M([y]),I.DEVICE=M([T,k,v,G,S,i,r,e,F]),I.ENGINE=I.OS=M([g,x]);export{I as UAParser}; \ No newline at end of file +function E(i){for(var e={},o=0;o{var o,t={},r=e;if(!_i(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,M.call(this,[["getBrowser",(n=function(i){return i==f?function(){return new Pi(i,r,s,a).set("ua",r).set(c,this.getBrowser()).set(u,this.getCPU()).set(h,this.getDevice()).set(p,this.getEngine()).set(m,this.getOS()).get()}:function(){return new Pi(i,r,s[i],a).parseUA().get()}})(c)],["getCPU",n(u)],["getDevice",n(h)],["getEngine",n(p)],["getOS",n(m)],["getResult",n(f)],["getUA",function(){return r}],["setUA",function(i){return A(i)&&(r=i.length>B?Ai(i,B):i),this}]]).setUA(r),this):new j(i,e,o).getResult()}j.VERSION="2.0.3",j.BROWSER=E([g,x,C,v]),j.CPU=E([y]),j.DEVICE=E([T,k,v,L,S,i,r,e,F]),j.ENGINE=j.OS=E([g,x]);export{j as UAParser}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 187bf02..70cf439 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ua-parser-js", - "version": "2.0.2", + "version": "2.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ua-parser-js", - "version": "2.0.2", + "version": "2.0.3", "funding": [ { "type": "opencollective", @@ -35,7 +35,6 @@ "devDependencies": { "@babel/parser": "7.15.8", "@babel/traverse": "7.23.2", - "@jazzer.js/core": "^1.4.0", "@playwright/test": "^1.49.0", "jshint": "~2.13.6", "mocha": "~8.2.0", @@ -48,19 +47,6 @@ "node": "*" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -75,78 +61,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", - "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.0", - "@babel/generator": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.0", - "@babel/parser": "^7.26.0", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.26.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.26.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/core/node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/generator": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", @@ -178,22 +92,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-environment-visitor": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", @@ -231,102 +129,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports/node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.26.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-module-imports/node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.26.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", @@ -357,28 +159,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/parser": { "version": "7.15.8", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", @@ -469,108 +249,6 @@ "node": ">=6.9.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/bug-detectors": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/bug-detectors/-/bug-detectors-1.7.0.tgz", - "integrity": "sha512-ytGXkiH0G0XWXt1sm2KKdSWwEpOIN+SIe2wT6uvIO2mrUqQmLL2LnINeahL5T8L2b0+dafYDGZeVxElgsgH5eA==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "dependencies": { - "@jazzer.js/core": "1.7.0", - "@jazzer.js/hooking": "1.7.0" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, - "node_modules/@jazzer.js/core": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/core/-/core-1.7.0.tgz", - "integrity": "sha512-HGSNb8HxPjK/z84I3CZUmXd/+TqTfjjGOgXKzHK9/fmwUltLLuUcbSTkc1RDHrgT4z2EF7Tlkeo51Vp648f8Ag==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "dependencies": { - "@jazzer.js/bug-detectors": "1.7.0", - "@jazzer.js/fuzzer": "1.7.0", - "@jazzer.js/hooking": "1.7.0", - "@jazzer.js/instrumentor": "1.7.0", - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.1.6", - "tmp": "^0.2.1", - "yargs": "^17.7.2" - }, - "bin": { - "jazzer": "dist/cli.js" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, - "node_modules/@jazzer.js/fuzzer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/fuzzer/-/fuzzer-1.7.0.tgz", - "integrity": "sha512-FDTsHzUQva3G6ETowxAlBNY+aXc4J+XzKcTRtxQdIIW9wPli2qxUjlVCkPHfKCfOcdNseAygR/AIfrXfrB0iWw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.5.0", - "cmake-js": "^7.2.1", - "node-addon-api": "^7.0.0", - "prebuild-install": "^7.1.1" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, - "node_modules/@jazzer.js/hooking": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/hooking/-/hooking-1.7.0.tgz", - "integrity": "sha512-1uGhdaRVAyNTnCuThcYFnjKKWIlVnobM+LUVoRHAFe+TVFyfnV2wCKCjoj+kjZtt4fD0lL9gjkKSafbiKNzsnA==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "dependencies": { - "@babel/core": "^7.22.11" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, - "node_modules/@jazzer.js/instrumentor": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@jazzer.js/instrumentor/-/instrumentor-1.7.0.tgz", - "integrity": "sha512-YPMzL0mH8+UKGwe0r/7vhq3DsxHOxhkeqTusYTajDycwz6/51y3JC20NhX3qs1Jyd7xpIo7ANhVN0dU4V1MwMw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "dependencies": { - "@babel/core": "^7.22.11", - "@babel/generator": "^7.22.10", - "@jazzer.js/fuzzer": "1.7.0", - "@jazzer.js/hooking": "1.7.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "proper-lockfile": "^4.1.2", - "source-map-support": "^0.5.21" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -814,61 +492,6 @@ "node": ">= 8" } }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -901,43 +524,12 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/axios": { - "version": "1.7.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz", - "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -950,49 +542,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bl/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1021,68 +570,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -1109,26 +596,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001684", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz", - "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1166,15 +633,6 @@ "fsevents": "~2.1.2" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/cli": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", @@ -1188,59 +646,6 @@ "node": ">=0.2.5" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cmake-js": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-7.3.0.tgz", - "integrity": "sha512-dXs2zq9WxrV87bpJ+WbnGKv8WUBXDw8blNiwNHoRe/it+ptscxhQHKB1SJXa1w+kocLMeP28Tk4/eTCezg4o+w==", - "dev": true, - "dependencies": { - "axios": "^1.6.5", - "debug": "^4", - "fs-extra": "^11.2.0", - "lodash.isplainobject": "^4.0.6", - "memory-stream": "^1.0.0", - "node-api-headers": "^1.1.0", - "npmlog": "^6.0.2", - "rc": "^1.2.7", - "semver": "^7.5.4", - "tar": "^6.2.0", - "url-join": "^4.0.1", - "which": "^2.0.2", - "yargs": "^17.7.2" - }, - "bin": { - "cmake-js": "bin/cmake-js" - }, - "engines": { - "node": ">= 14.15.0" - } - }, - "node_modules/cmake-js/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1259,15 +664,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "bin": { - "color-support": "bin.js" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1294,18 +690,6 @@ "date-now": "^0.1.4" } }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -1369,45 +753,6 @@ "node": ">=0.10.0" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1416,12 +761,6 @@ "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true - }, "node_modules/detect-europe-js": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/detect-europe-js/-/detect-europe-js-0.1.2.tgz", @@ -1441,15 +780,6 @@ } ] }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -1536,27 +866,12 @@ "domelementtype": "1" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.67", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz", - "integrity": "sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==", - "dev": true - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/entities": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", @@ -1572,15 +887,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1643,15 +949,6 @@ "node": ">= 0.8.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -1677,12 +974,6 @@ "reusify": "^1.0.4" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1720,26 +1011,6 @@ "flat": "cli.js" } }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/form-data": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", @@ -1753,56 +1024,6 @@ "node": ">= 6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1832,44 +1053,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/gauge/node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1879,12 +1062,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1959,12 +1136,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -1992,12 +1163,6 @@ "node": ">=8" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -2049,12 +1214,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, "node_modules/htmlparser2": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", @@ -2068,26 +1227,6 @@ "readable-stream": "1.1" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2123,12 +1262,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, "node_modules/irregular-plurals": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", @@ -2250,97 +1383,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "dev": true, - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.26.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -2420,30 +1462,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -2480,12 +1498,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true - }, "node_modules/log-symbols": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", @@ -2498,42 +1510,6 @@ "node": ">=10" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -2546,38 +1522,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/memory-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-1.0.0.tgz", - "integrity": "sha512-Wm13VcsPIMdG96dzILfij09PvuS3APtcKNh7M28FsCA/w6+1mjR7hhPmfFNoilX9xU7wTdhsH5lJAm6XNzdtww==", - "dev": true, - "dependencies": { - "readable-stream": "^3.4.0" - } - }, - "node_modules/memory-stream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/memory-stream/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/meow": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", @@ -2666,18 +1610,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -2699,15 +1631,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", @@ -2722,64 +1645,6 @@ "node": ">= 6" } }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/mocha": { "version": "8.2.1", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", @@ -3098,48 +1963,6 @@ "node": "^10 || ^12 || >=13.7" } }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true - }, - "node_modules/node-abi": { - "version": "3.71.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", - "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true - }, - "node_modules/node-api-headers": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-api-headers/-/node-api-headers-1.4.0.tgz", - "integrity": "sha512-u83U3WnRbBpWlhc0sQbpF3slHRLV/a6/OXByc+QzHcLxiDiJUWLuKGZp4/ntZUchnXGOCnCq++JUEtwb1/tyow==", - "dev": true - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -3159,12 +1982,6 @@ } } }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": 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", @@ -3201,22 +2018,6 @@ "node": ">=0.10.0" } }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3393,32 +2194,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/prebuild-install": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", - "dev": true, - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -3445,33 +2220,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3510,30 +2258,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -3760,15 +2484,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3831,15 +2546,6 @@ "regexp-tree": "~0.1.1" } }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -3855,57 +2561,6 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -3915,25 +2570,6 @@ "node": ">=8" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -4004,15 +2640,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -4074,95 +2701,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tar-stream/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "engines": { - "node": ">=14.14" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4210,18 +2748,6 @@ "node": ">=14.16" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -4270,57 +2796,6 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -4424,62 +2899,12 @@ "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", "dev": true }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", @@ -4538,15 +2963,6 @@ "node": ">=8" } }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index d6a3dc1..ba1f89d 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "2.0.2", + "version": "2.0.3", "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 907f469..2fb0db5 100644 --- a/src/enums/ua-parser-enums.d.ts +++ b/src/enums/ua-parser-enums.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Enums submodule of UAParser.js v2.0.2 +// Type definitions for Enums submodule of UAParser.js v2.0.3 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index d28596d..0a53cce 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.2 +/* Enums for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/enums/ua-parser-enums.mjs b/src/enums/ua-parser-enums.mjs index 6e8257a..571eb70 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.2 +/* Enums for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ @@ -25,6 +25,7 @@ const Browser = Object.freeze({ BAIDU: 'Baidu Browser', BASILISK: 'Basilisk', BLAZER: 'Blazer', + BLU: 'BLU', BOLT: 'Bolt', BOWSER: 'Bowser', BRAVE: 'Brave', @@ -41,9 +42,11 @@ const Browser = Object.freeze({ DAUM: 'Daum', DILLO: 'Dillo', DOLPHIN: 'Dolphin', + DOOBLE: 'Dooble', DORIS: 'Doris', DRAGON: 'Dragon', DUCKDUCKGO: 'DuckDuckGo', + ECOSIA: 'Ecosia', EDGE: 'Edge', EPIPHANY: 'Epiphany', FACEBOOK: 'Facebook', @@ -82,6 +85,7 @@ const Browser = Object.freeze({ KINDLE: 'Kindle', LENOVO: 'Smart Lenovo Browser', LADYBIRD: 'Ladybird', + LG: 'LG Browser', LIBREWOLF: 'LibreWolf', LIEBAO: 'LBBROWSER', LINE: 'Line', @@ -106,10 +110,12 @@ const Browser = Object.freeze({ OMNIWEB: 'OmniWeb', OPERA: 'Opera', OPERA_COAST: 'Opera Coast', + OPERA_GX: 'Opera GX', OPERA_MINI: 'Opera Mini', OPERA_MOBI: 'Opera Mobi', OPERA_TABLET: 'Opera Tablet', OPERA_TOUCH: 'Opera Touch', + OTTER: 'Otter', OVI: 'OviBrowser', PALEMOON: 'PaleMoon', PHANTOMJS: 'PhantomJS', @@ -121,6 +127,7 @@ const Browser = Object.freeze({ QQ_LITE: 'QQBrowserLite', QUARK: 'Quark', QUPZILLA: 'QupZilla', + QUTEBROWSER: 'qutebrowser', REKONQ: 'rekonq', ROCKMELT: 'Rockmelt', SAFARI: 'Safari', @@ -137,6 +144,7 @@ const Browser = Object.freeze({ SNAPCHAT: 'Snapchat', SOGOU_EXPLORER: 'Sogou Explorer', SOGOU_MOBILE: 'Sogou Mobile', + SURF: 'Surf', SWIFTFOX: 'Swiftfox', TESLA: 'Tesla', TIKTOK: 'TikTok', diff --git a/src/extensions/ua-parser-extensions.d.ts b/src/extensions/ua-parser-extensions.d.ts index 500a0a2..3b9b63a 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.2 +// Type definitions for Helpers submodule of UAParser.js v2.0.3 // 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 e8e3f6e..6665b6d 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.2 +/* Extensions for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ diff --git a/src/extensions/ua-parser-extensions.mjs b/src/extensions/ua-parser-extensions.mjs index 8e7bc88..9770ebc 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.2 +/* Extensions for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ @@ -46,25 +46,25 @@ const Crawlers = Object.freeze({ [ // AhrefsBot - https://ahrefs.com/robot // Amazonbot - https://developer.amazon.com/amazonbot - // Bingbot - http://www.bing.com/bingbot.htm + // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0 // CCBot - https://commoncrawl.org/faq // 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 + // LinkedInBot - http://www.linkedin.com // MJ12bot - https://mj12bot.com/ // MojeekBot - https://www.mojeek.com/bot.html // OpenAI's SearchGPT - https://platform.openai.com/docs/bots // PerplexityBot - https://perplexity.ai/perplexitybot - // SemrushBot - http://www.semrush.com/bot.html // SeznamBot - http://napoveda.seznam.cz/seznambot-intro - /((?:ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, + /((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|linkedin|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, // Applebot - http://apple.com/go/applebot - /(applebot(?:-extended)?)\/([\w\.]+)/i, + /(applebot(?:-extended)?)\/?([\w\.]*)/i, // Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001 - /(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i, + /(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i, // ClaudeBot (Anthropic) /(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i, @@ -82,6 +82,9 @@ const Crawlers = Object.freeze({ // Internet Archive (archive.org) /(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i, + // SemrushBot - http://www.semrush.com/bot.html + /((?:semrush|splitsignal)bot[-abcfimostw]*)\/?([\w\.-]*)/i, + // Sogou Spider /(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i, @@ -94,8 +97,8 @@ const Crawlers = Object.freeze({ // Yeti (Naver) /(yeti)\/([\w\.]+)/i, - // aiHitBot / Diffbot / Magpie-Crawler / Omgilibot / Webzio-Extended / Screaming Frog SEO Spider / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot - /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|(?:magpie-|velenpublicweb)crawler|webzio-extended|(?:screaming frog seo |yisou)spider)\/?([\w\.]*)/i + // aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot + /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|webzio-extended|(?:screaming frog seo |line|yisou)spider)\/?([\w\.]*)/i ], [NAME, VERSION, [TYPE, CRAWLER]], @@ -112,7 +115,7 @@ const Crawlers = Object.freeze({ // Qihoo 360Spider // TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html // 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 + /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i ], [NAME, [TYPE, CRAWLER]] ] @@ -221,27 +224,35 @@ const Fetchers = Object.freeze({ // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // ChatGPT-User - https://platform.openai.com/docs/plugins/bot // DuckAssistBot - https://duckduckgo.com/duckassistbot/ - // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot + // Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot // Google Site Verifier / Meta / Yahoo! Japan // Yandex Bots - https://yandex.com/bots - /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, + /(ahrefssiteaudit|(?:bing|microsoft)preview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, // Bluesky /(bluesky) cardyb\/([\w\.]+)/i, + // Skype + /(skypeuripreview) preview\/([\w\.]+)/i, + // Slackbot - https://api.slack.com/robots /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i, // WhatsApp - /(whatsapp)\/([\w\.]+)[\/ ][ianw]/i + /(whatsapp)\/([\w\.]+)/i ], [NAME, VERSION, [TYPE, FETCHER]], [ // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots - /(cohere-ai|vercelbot|feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat|yandex(?:sitelinks|userproxy))/i + /((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i ], [NAME, [TYPE, FETCHER]], + ], + + os : [ + [/whatsapp\/[\d\.]+ (a|i)/i], + [[NAME, os => os == 'A' ? 'Android' : 'iOS' ]] ] }); @@ -252,10 +263,12 @@ const Fetchers = Object.freeze({ const InApps = Object.freeze({ browser : [ // Slack - [/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]], + [/(?:slack(?=.+electron|.+ios)|chatlyio)\/([\d\.]+)/i], + [VERSION, [NAME, 'Slack'], [TYPE, INAPP]], // Yahoo! Japan - [/jp\.co\.yahoo\.android\.yjtop\/([\d\.]+)/i], [VERSION, 'Yahoo! Japan', [TYPE, INAPP]] + [/jp\.co\.yahoo\.(?:android\.yjtop|ipn\.appli)\/([\d\.]+)/i], + [VERSION, [NAME, 'Yahoo! Japan'], [TYPE, INAPP]] ] }); @@ -331,15 +344,20 @@ const Libraries = Object.freeze({ const Vehicles = Object.freeze({ device : [ - [ - /dilink.+(byd) auto/i, // BYD - ], [VENDOR], [ + [/aftlbt962e2/i], // BMW + [[VENDOR, 'BMW']], - /(rivian) (r1t)/i, // Rivian - ], [VENDOR, MODEL], [ + [/dilink.+(byd) auto/i], // BYD + [VENDOR], - /vcc.+netfront/i, // Volvo - ], [[VENDOR, 'Volvo']] + [/aftlft962x3/i], // Jeep + [[VENDOR, 'Jeep'], [MODEL, 'Wagooner']], + + [/(rivian) (r1t)/i], // Rivian + [VENDOR, MODEL], + + [/vcc.+netfront/i], // Volvo + [[VENDOR, 'Volvo']] ] }); @@ -353,6 +371,9 @@ const Bots = Object.freeze({ ...Crawlers.browser, ...Fetchers.browser, ...Libraries.browser + ], + os : [ + ...Fetchers.os ] }); diff --git a/src/helpers/ua-parser-helpers.d.ts b/src/helpers/ua-parser-helpers.d.ts index 389e8c6..4b6c808 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.2 +// Type definitions for Helpers submodule of UAParser.js v2.0.3 // 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 daaa897..64d7e90 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.2 +/* Helpers for UAParser.js v2.0.3 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 622e27a..e47aae4 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.2 +/* Helpers for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman AGPLv3 License */ @@ -97,6 +97,9 @@ const isAIBot = (resultOrUA) => [ // Perplexity 'perplexitybot', + // Semrush + 'semrushbot-ocob', + // Timpi 'timpibot', diff --git a/src/main/ua-parser.d.ts b/src/main/ua-parser.d.ts index c22a3de..6c7c9f8 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.2 +// Type definitions for UAParser.js v2.0.3 // 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 f950c5d..a6f1091 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v2.0.2 - Copyright © 2012-2024 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman AGPLv3 License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment. @@ -19,7 +19,7 @@ // Constants ///////////// - var LIBVERSION = '2.0.2', + var LIBVERSION = '2.0.3', UA_MAX_LENGTH = 500, USER_AGENT = 'user-agent', EMPTY = '', diff --git a/src/main/ua-parser.mjs b/src/main/ua-parser.mjs index 0dfa143..00eb9bb 100644 --- a/src/main/ua-parser.mjs +++ b/src/main/ua-parser.mjs @@ -3,8 +3,8 @@ // Source: /src/main/ua-parser.js ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v2.0.2 - Copyright © 2012-2024 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman AGPLv3 License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment. @@ -21,7 +21,7 @@ // Constants ///////////// - var LIBVERSION = '2.0.2', + var LIBVERSION = '2.0.3', UA_MAX_LENGTH = 500, USER_AGENT = 'user-agent', EMPTY = '', @@ -355,11 +355,11 @@ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer - // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon - /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon)\/([-\w\.]+)/i, + // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon - /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115 - /(weibo)__([\d\.]+)/i // Weibo + /(heytap|ovi|115|surf)browser\/([\d\.]+)/i, // HeyTap/Ovi/115/Surf + /(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i // Ecosia/Weibo ], [NAME, VERSION], [ /quark(?:pc)?\/([-\w\.]+)/i // Quark ], [VERSION, [NAME, 'Quark']], [ @@ -587,8 +587,11 @@ /\b(opd2(\d{3}a?))(?: bui|\))/i ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '203'], '*' : OPPO }], [TYPE, TABLET]], [ + // BLU Vivo Series + /(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i + ], [MODEL, [VENDOR, 'BLU'], [TYPE, MOBILE]], [ // Vivo - /vivo (\w+)(?: bui|\))/i, + /; vivo (\w+)(?: bui|\))/i, /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ @@ -608,7 +611,7 @@ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, - /\blg[-e;\/ ]+((?!browser|netcast|android tv|watch)\w+)/i, + /\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch))(\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ @@ -715,6 +718,14 @@ /droid.+; (a(?:015|06[35]|142p?))/i ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [ + // Archos + /; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i, + /archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i + ], [MODEL, [VENDOR, 'Archos'], [TYPE, TABLET]], [ + /archos ([\w ]+)( b|\))/i, + /; (ac[3-6]\d\w{2,8})( b|\))/i + ], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [ + // MIXED /(imo) (tab \w+)/i, // IMO /(infinix) (x1101b?)/i // Infinix XPad @@ -722,7 +733,7 @@ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan - /; (hmd|imo) ([\w ]+?)(?: bui|\))/i, // HMD/IMO + /; (blu|hmd|imo|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/TCL /(hp) ([\w ]+\w)/i, // HP iPAQ /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i, // Lenovo @@ -730,7 +741,6 @@ ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kobo)\s(ereader|touch)/i, // Kobo - /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i // Kindle ], [VENDOR, MODEL, [TYPE, TABLET]], [ @@ -758,7 +768,9 @@ ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ - /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV + /tcast.+(lg)e?. ([-\w]+)/i // LG SmartTV + ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ + /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ @@ -770,6 +782,8 @@ ], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast, Linux-based or unknown ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ + /(portaltv)/i // Facebook Portal TV + ], [MODEL, [VENDOR, FACEBOOK], [TYPE, SMARTTV]], [ /droid.+aft(\w+)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /(shield \w+ tv)/i // Nvidia Shield TV @@ -838,7 +852,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [ /(pico) (4|neo3(?: link|pro)?)/i // Pico ], [VENDOR, MODEL, [TYPE, XR]], [ - /; (quest( \d| pro)?)/i // Oculus Quest + /(quest( \d| pro)?s?).+vr/i // Meta Quest ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [ /////////////////// @@ -933,7 +947,7 @@ /(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [ // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen - /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/; ]?([\d\.]*)/i + /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/\.; ]?([\d\.]*)/i ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ @@ -1215,7 +1229,11 @@ 'Chrome' : 'Google Chrome', 'Edge' : 'Microsoft Edge', 'Chrome WebView' : 'Android WebView', - 'Chrome Headless' : 'HeadlessChrome' + 'Chrome Headless' : 'HeadlessChrome', + 'Huawei Browser' : 'HuaweiBrowser', + 'MIUI Browser' : 'Miui Browser', + 'Opera Mobi' : 'OperaMobile', + 'Yandex' : 'YaBrowser' }); this.set(NAME, brandName) .set(VERSION, brandVersion)