From 6c671dd24688dab98da40f3d8994b6a0fca0fdf5 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 8 Apr 2021 00:43:25 +0700 Subject: [PATCH 001/104] Refactor code: saving bytes towards 15KB minified --- dist/ua-parser.min.js | 13 +- dist/ua-parser.pack.js | 13 +- package.json | 4 +- src/ua-parser.js | 676 ++++++++++++++++++++--------------------- 4 files changed, 339 insertions(+), 367 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 89a39e610..262021bee 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,4 @@ -/*!@license - * UAParser.js v0.7.27 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.27",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",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){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}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +/* UAParser.js v0.7.27 + Copyright © 2012-2021 Faisal Salman + MIT License */ +(function(window,undefined){"use strict";var LIBVERSION="0.7.27",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",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i in arr){enums[arr[i].toUpperCase()]=arr[i]}return enums},has=function(str1,str2){return typeof str1===STR_TYPE?lowerize(str2).indexOf(lowerize(str1))!==-1:false},lowerize=function(str){return str.toLowerCase()},majorize=function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,EMPTY).split(".")[0]:undefined},trim=function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,EMPTY);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)};var rgxMapper=function(ua,arrays){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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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.pack.js b/dist/ua-parser.pack.js index 67612af90..6b53d614a 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,9 +1,4 @@ -/*!@license - * UAParser.js v0.7.27 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",a="string",i="model",s="name",o="type",n="vendor",t="version",l="architecture",d="console",w="mobile",m="tablet",p="smarttv",f="wearable",h={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==a&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==a?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},g={rgx:function(i,s){for(var e,o,r,a,n,t=0;t + MIT License */ +!function(a,d){"use strict";function i(i){var e,s={};for(e in i)s[i[e].toUpperCase()]=i[e];return s}function r(i,e){return typeof i==w&&-1!==D(e).indexOf(D(i))}function n(i,e){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof e==b?i:i.substring(0,255)}function t(i,e){for(var s,o,a,r,n,t=0;t (http://faisalman.com)", - "description": "Lightweight JavaScript-based user-agent string parser", + "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ "user-agent", "parser", @@ -142,7 +142,7 @@ ], "main": "src/ua-parser.js", "scripts": { - "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments --compress --mangle", + "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments '/^ UA/' && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments '/^ UA/' --compress --mangle", "test": "jshint src/ua-parser.js && mocha -R nyan test/test.js", "test-ci": "jshint src/ua-parser.js && mocha -R spec test/test.js", "verup": "node ./node_modules/verup", diff --git a/src/ua-parser.js b/src/ua-parser.js index 2dbdf7e89..0a055f040 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,11 +1,12 @@ -/*!@license - * UAParser.js v0.7.27 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ +///////////////////////////////////////////////////////////////////////////////// +/* UAParser.js v0.7.27 + Copyright © 2012-2021 Faisal Salman + MIT License *//* + Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. + Supports browser & node.js environment. + Demo : https://faisalman.github.io/ua-parser-js + Source : https://github.com/faisalman/ua-parser-js */ +///////////////////////////////////////////////////////////////////////////////// (function (window, undefined) { @@ -15,7 +16,6 @@ // Constants ///////////// - var LIBVERSION = '0.7.27', EMPTY = '', UNKNOWN = '?', @@ -23,7 +23,7 @@ UNDEF_TYPE = 'undefined', OBJ_TYPE = 'object', STR_TYPE = 'string', - MAJOR = 'major', // deprecated + MAJOR = 'major', MODEL = 'model', NAME = 'name', TYPE = 'type', @@ -38,14 +38,30 @@ EMBEDDED = 'embedded', UA_MAX_LENGTH = 255; + var AMAZON = 'Amazon', + APPLE = 'Apple', + ASUS = 'ASUS', + BLACKBERRY = 'BlackBerry', + BROWSER = 'Browser', + CHROME = 'Chrome', + EDGE = 'Edge', + FIREFOX = 'Firefox', + GOOGLE = 'Google', + HUAWEI = 'Huawei', + LG = 'LG', + MICROSOFT = 'Microsoft', + MOTOROLA = 'Motorola', + OPERA = 'Opera', + SAMSUNG = 'Samsung', + SONY = 'Sony', + XIAOMI = 'Xiaomi', + ZEBRA = 'Zebra'; /////////// // Helper ////////// - - var util = { - extend : function (regexes, extensions) { + var extend = function (regexes, extensions) { var mergedRegexes = {}; for (var i in regexes) { if (extensions[i] && extensions[i].length % 2 === 0) { @@ -56,30 +72,32 @@ } return mergedRegexes; }, - has : function (str1, str2) { - return typeof str1 === STR_TYPE ? str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1 : false; + enumerize = function (arr) { + var enums = {}; + for (var i in arr) { + enums[arr[i].toUpperCase()] = arr[i]; + } + return enums; + }, + has = function (str1, str2) { + return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; }, - lowerize : function (str) { + lowerize = function (str) { return str.toLowerCase(); }, - major : function (version) { - return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g,'').split(".")[0] : undefined; + majorize = function (version) { + return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split('.')[0] : undefined; }, - trim : function (str, len) { - str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + trim = function (str, len) { + str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, EMPTY); return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); - } }; - /////////////// // Map helper ////////////// - - var mapper = { - - rgx : function (ua, arrays) { + var rgxMapper = function (ua, arrays) { var i = 0, j, k, p, q, matches, match; @@ -131,167 +149,145 @@ } }, - str : function (str, map) { + strMapper = function (str, map) { for (var i in map) { - // check if array + // check if current value is array if (typeof map[i] === OBJ_TYPE && map[i].length > 0) { for (var j = 0; j < map[i].length; j++) { - if (util.has(map[i][j], str)) { + if (has(map[i][j], str)) { return (i === UNKNOWN) ? undefined : i; } } - } else if (util.has(map[i], str)) { + } else if (has(map[i], str)) { return (i === UNKNOWN) ? undefined : i; } } return str; - } }; - /////////////// // String map ////////////// - - var maps = { - - browser : { - // Safari < 3.0 - oldSafari : { - version : { - '1.0' : '/8', - '1.2' : '/1', - '1.3' : '/3', - '2.0' : '/412', - '2.0.2' : '/416', - '2.0.3' : '/417', - '2.0.4' : '/419', - '?' : '/' - } - }, - oldEdge : { - version : { - '0.1' : '12.', - '21' : '13.', - '31' : '14.', - '39' : '15.', - '41' : '16.', - '42' : '17.', - '44' : '18.' - } - } + // Safari < 3.0 + var oldSafariMap = { + '1.0' : '/8', + '1.2' : '/1', + '1.3' : '/3', + '2.0' : '/412', + '2.0.2' : '/416', + '2.0.3' : '/417', + '2.0.4' : '/419', + '?' : '/' }, - - os : { - windows : { - version : { - 'ME' : '4.90', - 'NT 3.11' : 'NT3.51', - 'NT 4.0' : 'NT4.0', - '2000' : 'NT 5.0', - 'XP' : ['NT 5.1', 'NT 5.2'], - 'Vista' : 'NT 6.0', - '7' : 'NT 6.1', - '8' : 'NT 6.2', - '8.1' : 'NT 6.3', - '10' : ['NT 6.4', 'NT 10.0'], - 'RT' : 'ARM' - } - } - } + oldEdgeMap = { + '0.1' : '12.', + '21' : '13.', + '31' : '14.', + '39' : '15.', + '41' : '16.', + '42' : '17.', + '44' : '18.' + }, + windowsVersionMap = { + 'ME' : '4.90', + 'NT 3.11' : 'NT3.51', + 'NT 4.0' : 'NT4.0', + '2000' : 'NT 5.0', + 'XP' : ['NT 5.1', 'NT 5.2'], + 'Vista' : 'NT 6.0', + '7' : 'NT 6.1', + '8' : 'NT 6.2', + '8.1' : 'NT 6.3', + '10' : ['NT 6.4', 'NT 10.0'], + 'RT' : 'ARM' }; - ////////////// // Regex map ///////////// - var regexes = { browser : [[ /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS - ], [VERSION, [NAME, 'Chrome']], [ + ], [VERSION, [NAME, CHROME]], [ /(?:edgios|edga|edg)\/([\w\.]+)/i // Microsoft Edge - ], [VERSION, [NAME, 'Edge']], [ + ], [VERSION, [NAME, EDGE]], [ /edge\/([\w\.]+)/i // Old Edge (Trident) - ], [[VERSION, mapper.str, maps.browser.oldEdge.version], [NAME, 'Edge']], [ + ], [[VERSION, strMapper, oldEdgeMap], [NAME, EDGE]], [ // Presto based - /(opera\smini)\/([\w\.-]+)/i, // Opera Mini - /(opera\s[mobiletab]{3,6})\b.+version\/([\w\.-]+)/i, // Opera Mobi/Tablet + /(opera mini)\/([\w\.-]+)/i, // Opera Mini + /(opera [mobiletab]{3,6})\b.+version\/([\w\.-]+)/i, // Opera Mobi/Tablet /(opera)(?:.+version\/|[\/\s]+)([\w\.]+)/i, // Opera ], [NAME, VERSION], [ /opios[\/\s]+([\w\.]+)/i // Opera mini on iphone >= 8.0 - ], [VERSION, [NAME, 'Opera Mini']], [ - /\sopr\/([\w\.]+)/i // Opera Webkit - ], [VERSION, [NAME, 'Opera']], [ + ], [VERSION, [NAME, OPERA+' Mini']], [ + /\bopr\/([\w\.]+)/i // Opera Webkit + ], [VERSION, [NAME, OPERA]], [ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based - /(avant\s|iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser + /(avant |iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(ba?idubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser - /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer + /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer - // Webkit/KHTML based - /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon)\/([\w\.-]+)/i, - // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon - /(rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ + // 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|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([\w\.-]+)/i, + // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ - /(?:[\s\/]uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser - ], [VERSION, [NAME, 'UCBrowser']], [ - /(?:windowswechat)?\sqbcore\/([\w\.]+)\b.*(?:windowswechat)?/i // WeChat Desktop for Windows Built-in Browser + /(?:\buc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser + ], [VERSION, [NAME, 'UC'+BROWSER]], [ + /\bqbcore\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ /micromessenger\/([\w\.]+)/i // WeChat ], [VERSION, [NAME, 'WeChat']], [ /konqueror\/([\w\.]+)/i // Konqueror ], [VERSION, [NAME, 'Konqueror']], [ - /trident.+rv[:\s]([\w\.]{1,9})\b.+like\sgecko/i // IE11 + /trident.+rv[:\s]([\w\.]{1,9})\b.+like gecko/i // IE11 ], [VERSION, [NAME, 'IE']], [ /yabrowser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, 'Yandex']], [ /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser - ], [[NAME, /(.+)/, '$1 Secure Browser'], VERSION], [ - /focus\/([\w\.]+)/i // Firefox Focus - ], [VERSION, [NAME, 'Firefox Focus']], [ - /opt\/([\w\.]+)/i // Opera Touch - ], [VERSION, [NAME, 'Opera Touch']], [ - /coc_coc_browser\/([\w\.]+)/i // Coc Coc Browser + ], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [ + /\bfocus\/([\w\.]+)/i // Firefox Focus + ], [VERSION, [NAME, FIREFOX+' Focus']], [ + /\bopt\/([\w\.]+)/i // Opera Touch + ], [VERSION, [NAME, OPERA+' Touch']], [ + /coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser ], [VERSION, [NAME, 'Coc Coc']], [ /dolfin\/([\w\.]+)/i // Dolphin ], [VERSION, [NAME, 'Dolphin']], [ /coast\/([\w\.]+)/i // Opera Coast - ], [VERSION, [NAME, 'Opera Coast']], - [/xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser - ], [VERSION, [NAME, 'MIUI Browser']], [ + ], [VERSION, [NAME, OPERA+' Coast']], [ + /miuibrowser\/([\w\.]+)/i // MIUI Browser + ], [VERSION, [NAME, 'MIUI '+BROWSER]], [ /fxios\/([\w\.-]+)/i // Firefox for iOS - ], [VERSION, [NAME, 'Firefox']], [ - /(qihu|qhbrowser|qihoobrowser|360browser)/i // 360 - ], [[NAME, '360 Browser']], [ + ], [VERSION, [NAME, FIREFOX]], [ + /\bqihu|(qi?ho?o?|360)browser/i // 360 + ], [[NAME, '360 '+BROWSER]], [ /(oculus|samsung|sailfish)browser\/([\w\.]+)/i - ], [[NAME, /(.+)/, '$1 Browser'], VERSION], [ // Oculus/Samsung/Sailfish Browser + ], [[NAME, /(.+)/, '$1 '+BROWSER], VERSION], [ // Oculus/Samsung/Sailfish Browser /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ - /\s(electron)\/([\w\.]+)\ssafari/i, // Electron-based App - /(tesla)(?:\sqtcarbrowser|\/(20[12]\d\.[\w\.-]+))/i, // Tesla + /(electron)\/([\w\.]+) safari/i, // Electron-based App + /(tesla)(?:\sqtcarbrowser|\/(20\d\d\.[\w\.-]+))/i, // Tesla /m?(qqbrowser|baiduboxapp|2345Explorer)[\/\s]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [ - /(MetaSr)[\/\s]?([\w\.]+)/i, // SouGouBrowser - /(LBBROWSER)/i // LieBao Browser + /(metasr)[\/\s]?([\w\.]+)/i, // SouGouBrowser + /(lbbrowser)/i // LieBao Browser ], [NAME], [ // WebView - /;fbav\/([\w\.]+);/i // Facebook App for iOS & Android with version - ], [VERSION, [NAME, 'Facebook']], [ - /FBAN\/FBIOS|FB_IAB\/FB4A/i // Facebook App for iOS & Android without version - ], [[NAME, 'Facebook']], [ - /safari\s(line)\/([\w\.]+)/i, // Line App for iOS + /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android + ], [[NAME, 'Facebook'], VERSION], [ + /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(chromium|instagram)[\/\s]([\w\.-]+)/i // Chromium/Instagram ], [NAME, VERSION], [ @@ -299,13 +295,13 @@ ], [VERSION, [NAME, 'GSA']], [ /headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless - ], [VERSION, [NAME, 'Chrome Headless']], [ + ], [VERSION, [NAME, CHROME+' Headless']], [ /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView - ], [[NAME, 'Chrome WebView'], VERSION], [ + ], [[NAME, CHROME+' WebView'], VERSION], [ - /droid.+\sversion\/([\w\.]+)\b.+(?:mobile\ssafari|safari)/i // Android Browser - ], [VERSION, [NAME, 'Android Browser']], [ + /droid.+\sversion\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser + ], [VERSION, [NAME, 'Android '+BROWSER]], [ /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ @@ -315,7 +311,7 @@ /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 - ], [NAME, [VERSION, mapper.str, maps.browser.oldSafari.version]], [ + ], [NAME, [VERSION, strMapper, oldSafariMap]], [ /(webkit|khtml)\/([\w\.]+)/i ], [NAME, VERSION], [ @@ -323,21 +319,21 @@ // Gecko based /(navigator|netscape)\/([\w\.-]+)/i // Netscape ], [[NAME, 'Netscape'], VERSION], [ - /ile\svr;\srv:([\w\.]+)\).+firefox/i // Firefox Reality - ], [VERSION, [NAME, 'Firefox Reality']], [ + /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality + ], [VERSION, [NAME, FIREFOX+' Reality']], [ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox - /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, + /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror - /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, + /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix - /(firefox)\/([\w\.]+)\s[\w\s\-]+\/[\w\.]+$/i, // Other Firefox-based + /(firefox)\/([\w\.]+)/i, // Other Firefox-based /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla // Other /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir - /(links)\s\(([\w\.]+)/i, // Links + /(links) \(([\w\.]+)/i, // Links /(gobrowser)\/?([\w\.]*)/i, // GoBrowser /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser /(mosaic)[\/\s]([\w\.]+)/i // Mosaic @@ -350,7 +346,7 @@ ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i // IA32 (quicktime) - ], [[ARCHITECTURE, util.lowerize]], [ + ], [[ARCHITECTURE, lowerize]], [ /((?:i[346]|x)86)[;\)]/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ @@ -362,18 +358,18 @@ ], [[ARCHITECTURE, 'armhf']], [ // PocketPC mistakenly identified as PowerPC - /windows\s(ce|mobile);\sppc;/i + /windows\s(ce|mobile); ppc;/i ], [[ARCHITECTURE, 'arm']], [ - /((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i // PowerPC - ], [[ARCHITECTURE, /ower/, '', util.lowerize]], [ + /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC + ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ /(sun4\w)[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i + /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC - ], [[ARCHITECTURE, util.lowerize]] + ], [[ARCHITECTURE, lowerize]] ], device : [[ @@ -384,135 +380,135 @@ ///////////////////////// // Samsung - /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus\s10)/i - ], [MODEL, [VENDOR, 'Samsung'], [TYPE, TABLET]], [ - /\b((?:s[cgp]h|gt|sm)-\w+|galaxy\snexus)/i, - /\ssamsung[\s-]([\w-]+)/i, + /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i + ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ + /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, + /samsung[\s-]([\w-]+)/i, /sec-(sgh\w+)/i - ], [MODEL, [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ // Apple /\((ip(?:hone|od)[\s\w]*);/i // iPod/iPhone - ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ /\((ipad);[\w\s\),;-]+apple/i, // iPad - /applecoremedia\/[\w\.]+\s\((ipad)/i, + /applecoremedia\/[\w\.]+ \((ipad)/i, /\b(ipad)\d\d?,\d\d?[;\]].+ios/i - ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [ + ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i, - ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [ - /d\/huawei([\w\s-]+)[;\)]/i, - /\b(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, + ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ + /huawei([\w\s-]+)[;\)]/i, + /\b(nexus 6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, /\b(\w{2,4}-[atu][ln][01259][019])[;\)\s]/i - ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi - /\b(poco[\s\w]+)(?:\sbuild|\))/i, // Xiaomi POCO - /\b;\s(\w+)\sbuild\/hm\1/i, // Xiaomi Hongmi 'numeric' models - /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi - /\b(redmi[\s\-_]?(?:note|k)?[\w\s_]+)(?:\sbuild|\))/i, // Xiaomi Redmi - /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i // Xiaomi Mi - ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ - /\b(mi[\s\-_]?(?:pad)(?:[\w\s_]+))(?:\sbuild|\))/i // Mi Pad tablets - ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [ + /\b(poco[\s\w]+)(?: bui|\))/i, // Xiaomi POCO + /\b;\s(\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models + /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?) bui/i, // Xiaomi Hongmi + /\b(redmi[\s\-_]?(?:note|k)?[\w\s_]+)(?: bui|\))/i, // Xiaomi Redmi + /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?) bui/i // Xiaomi Mi + ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ + /\b(mi[\s\-_]?(?:pad)(?:[\w\s_]+))(?: bui|\))/i // Mi Pad tablets + ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO - /;\s(\w+)\sbuild.+\soppo/i, - /\s(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007)\b/i + /; (\w+) bui.+ oppo/i, + /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007)\b/i ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ // Vivo - /\svivo\s(\w+)(?:\sbuild|\))/i, - /\s(v[12]\d{3}\w?[at])(?:\sbuild|;)/i + /vivo (\w+)(?: bui|\))/i, + /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ // Realme - /\s(rmx[12]\d{3})(?:\sbuild|;)/i + /\b(rmx[12]\d{3})(?: bui|;)/i ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [ // Motorola - /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)\b[\w\s]+build\//i, - /\smot(?:orola)?[\s-](\w*)/i, - /((?:moto[\s\w\(\)]+|xt\d{3,4}|nexus\s6)(?=\sbuild|\)))/i - ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ - /\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i - ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ + /\b(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w\s]+build\//i, + /\bmot(?:orola)?[\s-](\w*)/i, + /((?:moto[\s\w\(\)]+|xt\d{3,4}|nexus\s6)(?= bui|\)))/i + ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ + /\b(mz60\d|xoom[\s2]{0,2}) build\//i + ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ // LG - /((?=lg)?[vl]k\-?\d{3})\sbuild|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i - ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [ + /((?=lg)?[vl]k\-?\d{3})\sbui|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i + ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm-?f100[nv]?|nexus\s[45])/i, - /lg[e;\s\/-]+((?!browser|netcast)\w+)/i, - /\blg(\-?[\d\w]+)\sbuild/i - ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ + /\blg[e;\s\/-]+((?!browser|netcast)\w+)/i, + /\blg(\-?[\d\w]+)\sbui/i + ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo /(ideatab[\w\-\s]+)/i, - /lenovo\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|yt[\d\w-]{6}|tb[\d\w-]{6})/i // Lenovo tablets + /lenovo\s?(s[56]000[\w-]+|tab(?:[\s\w]+)|yt[\d\w-]{6}|tb[\d\w-]{6})/i ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ // Nokia - /(?:maemo|nokia).*(n900|lumia\s\d+)/i, + /(?:maemo|nokia).*(n900|lumia \d+)/i, /nokia[\s_-]?([\w\.-]*)/i ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ // Google - /droid.+;\s(pixel\sc)[\s)]/i // Google Pixel C - ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [ - /droid.+;\s(pixel[\s\daxl]{0,6})(?:\sbuild|\))/i // Google Pixel - ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [ + /(pixel c)\b/i // Google Pixel C + ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ + /droid.+; (pixel[\s\daxl]{0,6})(?: bui|\))/i // Google Pixel + ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i - ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [ - /sony\stablet\s[ps]\sbuild\//i, - /(?:sony)?sgp\w+(?:\sbuild\/|\))/i - ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [ + /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i + ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ + /sony tablet [ps]/i, + /\b(?:sony)?sgp\w+(?: bui|\))/i + ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [ // OnePlus /\s(kb2005|in20[12]5|be20[12][59])\b/i, - /\ba000(1)\sbuild/i, // OnePlus - /\boneplus\s(a\d{4})[\s)]/i + /\ba000(1) bui/i, + /oneplus (a\d{4})[\s)]/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ // Amazon /(alexa)webm/i, - /(kf[a-z]{2}wi)(\sbuild\/|\))/i, // Kindle Fire without Silk - /(kf[a-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD - ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ - /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone - ], [[MODEL, 'Fire Phone'], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ + /(kf[a-z]{2}wi)( bui|\))/i, // Kindle Fire without Silk + /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD + ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [ + /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone + ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [ // BlackBerry - /\((playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook + /(playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook ], [MODEL, VENDOR, [TYPE, TABLET]], [ - /((?:bb[a-f]|st[hv])100-\d)/i, + /\b((?:bb[a-f]|st[hv])100-\d)/i, /\(bb10;\s(\w+)/i // BlackBerry 10 - ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [ // Asus - /(?:\b|asus_)(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus\s7|padfone|p00[cj])/i - ], [MODEL, [VENDOR, 'ASUS'], [TYPE, TABLET]], [ - /\s(z[es]6[027][01][km][ls]|zenfone\s\d\w?)\b/i - ], [MODEL, [VENDOR, 'ASUS'], [TYPE, MOBILE]], [ + /(?:\b|asus_)(transfo[prime\s]{4,10}\s\w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i + ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [ + /\s(z[es]6[027][01][km][ls]|zenfone \d\w?)\b/i + ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ // HTC - /(nexus\s9)/i // HTC Nexus 9 + /(nexus 9)/i // HTC Nexus 9 ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ - /(htc)[;_\s-]{1,2}([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC + /(htc)[;_\s-]{1,2}([\w\s]+(?=\)| bui)|\w+)/i, // HTC // ZTE /(zte)-(\w*)/i, - /(alcatel|geeksphone|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic|sony)[_\s-]?([\w-]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ // Acer - /droid[x\d\.\s;]+\s([ab][1-7]\-?[0178a]\d\d?)/i + /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [ // Meizu - /droid.+;\s(m[1-5]\snote)\sbuild/i, + /droid.+; (m[1-5] note) bui/i, /\bmz-([\w-]{2,})/i ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ @@ -521,94 +517,94 @@ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron /(hp)\s([\w\s]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus - /(microsoft);\s(lumia[\s\w]+)/i, // Microsoft Lumia + /(microsoft); (lumia[\s\w]+)/i, // Microsoft Lumia /(lenovo)[_\s-]?([\w-]+)/i, // Lenovo - /linux;.+(jolla);/i, // Jolla - /droid.+;\s(oppo)\s?([\w\s]+)\sbuild/i // OPPO + /(jolla)/i, // Jolla + /(oppo)\s?([\w\s]+)\sbui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(archos)\s(gamepad2?)/i, // Archos + /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i, // Kindle - /\s(nook)[\w\s]+build\/(\w+)/i, // Nook - /(dell)\s(strea[kpr\s\d]*[\dko])/i, // Dell Streak - /[;\/]\s?(le[\s\-]+pan)[\s\-]+(\w{1,9})\sbuild/i, // Le Pan Tablets - /[;\/]\s?(trinity)[\-\s]*(t\d{3})\sbuild/i, // Trinity Tablets - /\b(gigaset)[\s\-]+(q\w{1,9})\sbuild/i, // Gigaset Tablets - /\b(vodafone)\s([\w\s]+)(?:\)|\sbuild)/i // Vodafone + /(nook)[\w\s]+build\/(\w+)/i, // Nook + /(dell) (strea[kpr\s\d]*[\dko])/i, // Dell Streak + /(le[\s\-]+pan)[\s\-]+(\w{1,9})\sbui/i, // Le Pan Tablets + /(trinity)[\-\s]*(t\d{3})\sbui/i, // Trinity Tablets + /(gigaset)[\s\-]+(q\w{1,9})\sbui/i, // Gigaset Tablets + /(vodafone)\s([\w\s]+)(?:\)|\sbui)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ - /\s(surface\sduo)\s/i // Surface Duo - ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, TABLET]], [ - /droid\s[\d\.]+;\s(fp\du?)\sbuild/i + /(surface duo)/i // Surface Duo + ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ + /droid\s[\d\.]+; (fp\du?) b/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ - /\s(u304aa)\sbuild/i // AT&T + /(u304aa)/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ - /sie-(\w*)/i // Siemens + /\bsie-(\w*)/i // Siemens ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ - /[;\/]\s?(rct\w+)\sbuild/i // RCA Tablets + /\b(rct\w+) b/i // RCA Tablets ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ - /[;\/\s](venue[\d\s]{2,7})\sbuild/i // Dell Venue Tablets + /\b(venue[\d\s]{2,7}) b/i // Dell Venue Tablets ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ - /[;\/]\s?(q(?:mv|ta)\w+)\sbuild/i // Verizon Tablet + /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ - /[;\/]\s(?:barnes[&\s]+noble\s|bn[rt])([\w\s\+]*)\sbuild/i // Barnes & Noble Tablet + /\b(?:barnes[&\s]+noble |bn[rt])([\w\s\+]*) b/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [ - /[;\/]\s(tm\d{3}\w+)\sbuild/i + /\b(tm\d{3}\w+) b/i ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ - /;\s(k88)\sbuild/i // ZTE K Series Tablet + /\b(k88) b/i // ZTE K Series Tablet ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ - /;\s(nx\d{3}j)\sbuild/i // ZTE Nubia + /\b(nx\d{3}j) b/i // ZTE Nubia ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ - /[;\/]\s?(gen\d{3})\sbuild.*49h/i // Swiss GEN Mobile + /\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ - /[;\/]\s?(zur\d{3})\sbuild/i // Swiss ZUR Tablet + /\b(zur\d{3}) b/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /[;\/]\s?((zeki)?tb.*\b)\sbuild/i // Zeki Tablets + /\b((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ - /[;\/]\s([yr]\d{2})\sbuild/i, - /[;\/]\s(dragon[\-\s]+touch\s|dt)(\w{5})\sbuild/i // Dragon Touch Tablet + /\b([yr]\d{2}) b/i, + /\b(dragon[\-\s]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ - /[;\/]\s?(ns-?\w{0,9})\sbuild/i // Insignia Tablets + /\b(ns-?\w{0,9}) b/i // Insignia Tablets ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ - /[;\/]\s?((nxa|Next)-?\w{0,9})\sbuild/i // NextBook Tablets + /\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ - /[;\/]\s?(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05]))\sbuild/i - ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones - /[;\/]\s?(lvtel\-)?(v1[12])\sbuild/i // LvTel Phones + /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones + ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ + /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ - /;\s(ph-1)\s/i - ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1 - /[;\/]\s?(v(100md|700na|7011|917g).*\b)\sbuild/i // Envizen Tablets + /\b(ph-1)\s/i // Essential PH-1 + ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ + /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ - /[;\/]\s?(trio[\s\w\-\.]+)\sbuild/i // MachSpeed Tablets + /\b(trio[\s\w\-\.]+) b/i // MachSpeed Tablets ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ - /[;\/]\s?tu_(1491)\sbuild/i // Rotor Tablets + /\btu_(1491) b/i // Rotor Tablets ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ - /(shield[\w\s]+)\sbuild/i // Nvidia Shield Tablets + /(shield[\w\s]+) b/i // Nvidia Shield Tablets ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ - /(sprint)\s(\w+)/i // Sprint Phones + /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin - ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ - /droid\s[\d\.]+;\s(cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra - ], [MODEL, [VENDOR, 'Zebra'], [TYPE, TABLET]], [ - /droid\s[\d\.]+;\s(ec30|ps20|tc[2-8]\d[kx])\)/i - ], [MODEL, [VENDOR, 'Zebra'], [TYPE, MOBILE]], [ + ], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [ + /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra + ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [ + /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i + ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [ /////////////////// // CONSOLES /////////////////// - /\s(ouya)\s/i, // Ouya - /(nintendo)\s([wids3utch]+)/i // Nintendo + /(ouya)/i, // Ouya + /(nintendo) ([wids3utch]+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ - /droid.+;\s(shield)\sbuild/i // Nvidia + /droid.+; (shield) bui/i // Nvidia ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ - /(playstation\s[345portablevi]+)/i // Playstation - ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [ - /[\s\(;](xbox(?:\sone)?(?!;\sxbox))[\s\);]/i // Microsoft Xbox - ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ + /(playstation [345portablevi]+)/i // Playstation + ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ + /\b(xbox(?: one)?(?!; xbox))[\s\);]/i // Microsoft Xbox + ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [ /////////////////// // SMARTTVS @@ -617,52 +613,52 @@ /smart-tv.+(samsung)/i // Samsung ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i - ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [ - /(?:linux;\snetcast.+smarttv|lg\snetcast\.tv-201\d)/i, // LG SmartTV - ], [[VENDOR, 'LG'], [TYPE, SMARTTV]], [ + ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ + /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i, // LG SmartTV + ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple)\s?tv/i // Apple TV - ], [VENDOR, [MODEL, 'Apple TV'], [TYPE, SMARTTV]], [ + ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast - ], [[MODEL, 'Chromecast'], [VENDOR, 'Google'], [TYPE, SMARTTV]], [ - /droid.+aft([\w])(\sbuild\/|\))/i // Fire TV - ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [ + ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ + /droid.+aft(\w)( bui|\))/i // Fire TV + ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices - ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [ - /[\s\/\(](android\s|smart[-\s]?|opera\s)tv[;\)\s]/i // SmartTV from Unidentified Vendors + ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ + /[\s\/\(](android |smart[-\s]?|opera )tv[;\)\s]/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ /////////////////// // WEARABLES /////////////////// - /((pebble))app\/[\d\.]+\s/i // Pebble + /((pebble))app/i // Pebble ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ - /droid.+;\s(glass)\s\d/i // Google Glass - ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ - /droid\s[\d\.]+;\s(wt63?0{2,3})\)/i - ], [MODEL, [VENDOR, 'Zebra'], [TYPE, WEARABLE]], [ + /droid.+; (glass) \d/i // Google Glass + ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ + /droid.+; (wt63?0{2,3})\)/i + ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ /////////////////// // EMBEDDED /////////////////// - /(tesla)(?:\sqtcarbrowser|\/20[12]\d\.[\w\.-]+)/i // Tesla + /(tesla)(?: qtcarbrowser|\/[\w\.-]+)/i // Tesla ], [VENDOR, [TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) /////////////////// - /droid .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i // Android Phones from Unidentified Vendors + /droid .+?;\s([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?;\s([^;]+?)(?: build|\) applewebkit).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors + /droid .+?;\s([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ - /\s(tablet|tab)[;\/]/i, // Unidentifiable Tablet - /\s(mobile)(?:[;\/]|\ssafari)/i // Unidentifiable Mobile - ], [[TYPE, util.lowerize]], [ - /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device + /\b(tablet|tab)[;\/]/i, // Unidentifiable Tablet + /\b(mobile)(?:[;\/]| safari)/i // Unidentifiable Mobile + ], [[TYPE, lowerize]], [ + /(android[\w\.\s\-]{0,9});.+buil/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']], [ /(phone)/i ], [[TYPE, MOBILE]] @@ -670,8 +666,8 @@ engine : [[ - /windows.+\sedge\/([\w\.]+)/i // EdgeHTML - ], [VERSION, [NAME, 'EdgeHTML']], [ + /windows.+ edge\/([\w\.]+)/i // EdgeHTML + ], [VERSION, [NAME, EDGE+'HTML']], [ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink ], [VERSION, [NAME, 'Blink']], [ @@ -690,60 +686,60 @@ os : [[ // Windows - /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes) + /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ - /(windows)\snt\s6\.2;\s(arm)/i, // Windows RT - /(windows\sphone(?:\sos)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i - ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [ - /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i - ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [ + /(windows) nt 6\.2; (arm)/i, // Windows RT + /(windows phone(?: os)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone + /(windows mobile|windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i + ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ + /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i + ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ // iOS/macOS - /ip[honead]{2,4}\b(?:.*os\s([\w]+)\slike\smac|;\sopera)/i, // iOS + /ip[honead]{2,4}\b(?:.*os ([\w]+) like\smac|; opera)/i, // iOS /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ - /(mac\sos\sx)\s?([\w\s\.]*)/i, - /(macintosh|mac(?=_powerpc)\s)(?!.+haiku)/i // Mac OS + /(mac os x)\s?([\w\s\.]*)/i, + /(macintosh|mac(?=_powerpc) )(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS - /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, + /(android|webos|palm os|qnx|bada|rim tablet os|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 - ], [VERSION, [NAME, 'BlackBerry']], [ + ], [VERSION, [NAME, BLACKBERRY]], [ /(?:symbian\s?os|symbos|s60(?=;)|series60)[\/\s-]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS - ], [[NAME, 'Firefox OS']], [ + ], [[NAME, FIREFOX+' OS']], [ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS ], [VERSION, [NAME, 'webOS']], [ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast - ], [VERSION, [NAME, 'Chromecast']], [ - /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS + ], [VERSION, [NAME, CHROME+'cast']], [ + /(cros) [\w]+\s([\w\.]+\w)/i // Chromium OS ], [[NAME, 'Chromium OS'], VERSION],[ // Console - /(nintendo|playstation)\s([wids345portablevuch]+)/i, // Nintendo/Playstation - /(xbox);\s+xbox\s([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) + /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation + /(xbox);\s+xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) // GNU/Linux based /(mint)[\/\s\(\)]?(\w*)/i, // Mint /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux - /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?=\slinux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus|raspbian)(?:\sgnu\/linux)?(?:\slinux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, + /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus|raspbian)(?: gnu\/linux)?(?: linux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux /(gnu)\s?([\w\.]*)/i, // GNU // BSD based - /\s([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + /\b([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly /(haiku)\s(\w+)/i // Haiku ], [NAME, VERSION], [ @@ -751,20 +747,20 @@ /(sunos)\s?([\w\.\d]*)/i // Solaris ], [[NAME, 'Solaris'], VERSION], [ /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris - /(aix)\s((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX - /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms|fuchsia)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia + /(aix) ((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX + /(plan 9|minix|beos|os\/2|amigaos|morphos|risc os|openvms|fuchsia)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia /(unix)\s?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] }; - ///////////////// // Constructor //////////////// + var UAParser = function (ua, extensions) { - if (typeof ua === 'object') { + if (typeof ua === OBJ_TYPE) { extensions = ua; ua = undefined; } @@ -773,33 +769,43 @@ return new UAParser(ua, extensions).getResult(); } - var _ua = ua || ((typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); - var _rgxmap = extensions ? util.extend(regexes, extensions) : regexes; + var _ua = ua || ((typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); + var _rgxmap = extensions ? extend(regexes, extensions) : regexes; this.getBrowser = function () { - var _browser = { name: undefined, version: undefined }; - mapper.rgx.call(_browser, _ua, _rgxmap.browser); - _browser.major = util.major(_browser.version); // deprecated + var _browser = {}; + _browser[NAME] = undefined; + _browser[VERSION] = undefined; + rgxMapper.call(_browser, _ua, _rgxmap.browser); + _browser.major = majorize(_browser.version); return _browser; }; this.getCPU = function () { - var _cpu = { architecture: undefined }; - mapper.rgx.call(_cpu, _ua, _rgxmap.cpu); + var _cpu = {}; + _cpu[ARCHITECTURE] = undefined; + rgxMapper.call(_cpu, _ua, _rgxmap.cpu); return _cpu; }; this.getDevice = function () { - var _device = { vendor: undefined, model: undefined, type: undefined }; - mapper.rgx.call(_device, _ua, _rgxmap.device); + var _device = {}; + _device[VENDOR] = undefined; + _device[MODEL] = undefined; + _device[TYPE] = undefined; + rgxMapper.call(_device, _ua, _rgxmap.device); return _device; }; this.getEngine = function () { - var _engine = { name: undefined, version: undefined }; - mapper.rgx.call(_engine, _ua, _rgxmap.engine); + var _engine = {}; + _engine[NAME] = undefined; + _engine[VERSION] = undefined; + rgxMapper.call(_engine, _ua, _rgxmap.engine); return _engine; }; this.getOS = function () { - var _os = { name: undefined, version: undefined }; - mapper.rgx.call(_os, _ua, _rgxmap.os); + var _os = {}; + _os[NAME] = undefined; + _os[VERSION] = undefined; + rgxMapper.call(_os, _ua, _rgxmap.os); return _os; }; this.getResult = function () { @@ -816,7 +822,7 @@ return _ua; }; this.setUA = function (ua) { - _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? util.trim(ua, UA_MAX_LENGTH) : ua; + _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua; return this; }; this.setUA(_ua); @@ -824,39 +830,15 @@ }; UAParser.VERSION = LIBVERSION; - UAParser.BROWSER = { - NAME : NAME, - MAJOR : MAJOR, // deprecated - VERSION : VERSION - }; - UAParser.CPU = { - ARCHITECTURE : ARCHITECTURE - }; - UAParser.DEVICE = { - MODEL : MODEL, - VENDOR : VENDOR, - TYPE : TYPE, - CONSOLE : CONSOLE, - MOBILE : MOBILE, - SMARTTV : SMARTTV, - TABLET : TABLET, - WEARABLE: WEARABLE, - EMBEDDED: EMBEDDED - }; - UAParser.ENGINE = { - NAME : NAME, - VERSION : VERSION - }; - UAParser.OS = { - NAME : NAME, - VERSION : VERSION - }; + UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]); + UAParser.CPU = enumerize([ARCHITECTURE]); + UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]); + UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]); /////////// // Export ////////// - // check js environment if (typeof(exports) !== UNDEF_TYPE) { // nodejs env @@ -866,11 +848,11 @@ exports.UAParser = UAParser; } else { // requirejs env (optional) - if (typeof(define) === 'function' && define.amd) { + if (typeof(define) === FUNC_TYPE && define.amd) { define(function () { return UAParser; }); - } else if (typeof window !== 'undefined') { + } else if (typeof window !== UNDEF_TYPE) { // browser env window.UAParser = UAParser; } @@ -881,15 +863,15 @@ // In AMD env the global scope should be kept clean, but jQuery is an exception. // jQuery always exports to global scope, unless jQuery.noConflict(true) is used, // and we should catch that. - var $ = typeof window !== 'undefined' && (window.jQuery || window.Zepto); + var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto); if ($ && !$.ua) { var parser = new UAParser(); $.ua = parser.getResult(); $.ua.get = function () { return parser.getUA(); }; - $.ua.set = function (uastring) { - parser.setUA(uastring); + $.ua.set = function (ua) { + parser.setUA(ua); var result = parser.getResult(); for (var prop in result) { $.ua[prop] = result[prop]; From 9200e53787a7c5ec5fe143780bf5c3bf3b32da7d Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 8 Apr 2021 21:06:52 +0700 Subject: [PATCH 002/104] Update readme: use https for demo link --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 30871ebfa..8afe2ceb7 100644 --- a/readme.md +++ b/readme.md @@ -15,7 +15,7 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data with relatively small footprint (~17KB minified, ~6KB gzipped) that can be used either in browser (client-side) or node.js (server-side). * Author : Faisal Salman <> -* Demo : http://faisalman.github.io/ua-parser-js +* Demo : https://faisalman.github.io/ua-parser-js * Source : https://github.com/faisalman/ua-parser-js # Documentation From c39590b673c87d82234139eb485f5345434d2030 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 8 Apr 2021 22:33:23 +0700 Subject: [PATCH 003/104] Test for Firefox UAs, add new browser: Klar, add new OS: Maemo Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox --- readme.md | 12 +++---- src/ua-parser.js | 27 ++++++++-------- test/browser-test.json | 40 +++++++++++++++++++++++ test/cpu-test.json | 16 ++++++++++ test/device-test.json | 72 ++++++++++++++++++++++++++++++++++++++++++ test/os-test.json | 65 +++++++++++++++++++++++++++++++++++++- 6 files changed, 211 insertions(+), 21 deletions(-) diff --git a/readme.md b/readme.md index 8afe2ceb7..08102cb28 100644 --- a/readme.md +++ b/readme.md @@ -41,7 +41,7 @@ Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, Firefox [Reality], Flock, Flow, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, -Kindle, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, +Kindle, Klar, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, @@ -88,11 +88,11 @@ NetSurf, Presto, Tasman, Trident, w3m, WebKit # Possible 'os.name' AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, -Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Mageia, Mandriva, MeeGo, -Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, -PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, RISC OS, -Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, -VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... +Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Maemo, Mageia, Mandriva, +MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, +PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, +RISC OS, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, +Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 0a055f040..2daa2a70b 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -323,8 +323,8 @@ ], [VERSION, [NAME, FIREFOX+' Reality']], [ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox - /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, - // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror + /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/\s]?([\w\.\+]+)/i, + // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix /(firefox)\/([\w\.]+)/i, // Other Firefox-based @@ -626,7 +626,7 @@ ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /[\s\/\(](android |smart[-\s]?|opera )tv[;\)\s]/i // SmartTV from Unidentified Vendors + /\b(android tv|smart[-\s]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ /////////////////// @@ -655,13 +655,12 @@ ], [MODEL, [TYPE, MOBILE]], [ /droid .+?;\s([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ - /\b(tablet|tab)[;\/]/i, // Unidentifiable Tablet - /\b(mobile)(?:[;\/]| safari)/i // Unidentifiable Mobile - ], [[TYPE, lowerize]], [ + /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet + ], [[TYPE, TABLET]], [ + /(phone|mobile(?:[;\/]| safari))/i // Unidentifiable Mobile + ], [[TYPE, MOBILE]], [ /(android[\w\.\s\-]{0,9});.+buil/i // Generic Android Device - ], [MODEL, [VENDOR, 'Generic']], [ - /(phone)/i - ], [[TYPE, MOBILE]] + ], [MODEL, [VENDOR, 'Generic']] ], engine : [[ @@ -690,7 +689,7 @@ ], [NAME, VERSION], [ /(windows) nt 6\.2; (arm)/i, // Windows RT /(windows phone(?: os)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows mobile|windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i + /(windows mobile|windows)[\s\/]?([ntce\d\.\s]+[\w\.]+)(?!.+xbox)/i ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ @@ -703,8 +702,8 @@ /(macintosh|mac(?=_powerpc) )(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ - // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS - /(android|webos|palm os|qnx|bada|rim tablet os|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, + // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/Maemo/MeeGo/Contiki/Sailfish OS + /(android|webos|palm os|qnx|bada|rim tablet os|maemo|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 @@ -713,8 +712,8 @@ ], [VERSION, [NAME, BLACKBERRY]], [ /(?:symbian\s?os|symbos|s60(?=;)|series60)[\/\s-]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ - /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS - ], [[NAME, FIREFOX+' OS']], [ + /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w\s]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS + ], [VERSION, [NAME, FIREFOX+' OS']], [ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS ], [VERSION, [NAME, 'webOS']], [ diff --git a/test/browser-test.json b/test/browser-test.json index 1947fe078..7158045b6 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -159,6 +159,16 @@ "major" : "2" } }, + { + "desc" : "Camino on Mac", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Camino/2.2.1", + "expect" : + { + "name" : "Camino", + "version" : "2.2.1", + "major" : "2" + } + }, { "desc" : "Chimera", "ua" : "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; pl-PL; rv:1.0.1) Gecko/20021111 Chimera/0.6", @@ -429,6 +439,16 @@ "major" : "1" } }, + { + "desc" : "Firefox for Maemo (Nokia N900)", + "ua" : "Mozilla/5.0 (Maemo; Linux armv7l; rv:10.0.1) Gecko/20100101 Firefox/10.0.1 Fennec/10.0.1", + "expect" : + { + "name" : "Fennec", + "version" : "10.0.1", + "major" : "10" + } + }, { "desc": "Firefox Focus", "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/6.1.1 Chrome/68.0.3440.91 Mobile Safari/537.36", @@ -958,6 +978,16 @@ "major" : "2" } }, + { + "desc" : "SeaMonkey on Mac", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:10.0.1) Gecko/20100101 Firefox/10.0.1 SeaMonkey/2.7.1", + "expect" : + { + "name" : "SeaMonkey", + "version" : "2.7.1", + "major" : "2" + } + }, { "desc" : "Silk Browser", "ua" : "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-84)", @@ -1228,6 +1258,16 @@ "major" : "1" } }, + { + "desc" : "Firefox iOS using iPad", + "ua" : "Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4", + "expect" : + { + "name" : "Firefox", + "version" : "1.0", + "major" : "1" + } + }, { "desc" : "QQ on iOS", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Mobile/14A456 QQ/6.5.3.410 V1_IPH_SQ_6.5.3_1_APP_A Pixel/1080 Core/UIWebView NetType/WIFI Mem/26", diff --git a/test/cpu-test.json b/test/cpu-test.json index 773c9f6d3..efa1c5b93 100644 --- a/test/cpu-test.json +++ b/test/cpu-test.json @@ -79,6 +79,14 @@ "architecture" : "arm" } }, + { + "desc" : "Nokia N900 Linux mobile", + "ua" : "Mozilla/5.0 (Maemo; Linux armv7l; rv:10.0) Gecko/20100101 Firefox/10.0 Fennec/10.0", + "expect" : + { + "architecture" : "arm" + } + }, { "desc" : "ARMEABI", "ua" : "[FBAN/FB4A;FBAV/237.0.0.44.120;FBBV/170693408;FBDM/{density=1.75,width=720,height=1280};FBLC/en_US;FBRV/172067074;FBCR/ ;FBMF/samsung;FBBD/samsung;FBPN/com.facebook.katana;FBDV/SM-S367VL;FBSV/9;FBBK/1;FBOP/19;FBCA/armeabi-v7a:armeabi;]", @@ -135,6 +143,14 @@ "architecture" : "ppc" } }, + { + "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" : + { + "architecture" : "ppc" + } + }, { "desc" : "UltraSPARC", "ua" : "Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.9b5) Gecko/2008032620 Firefox/3.0b5", diff --git a/test/device-test.json b/test/device-test.json index fb4b9143e..41da99fcc 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -2442,5 +2442,77 @@ "model": "V1916A", "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" + } } ] diff --git a/test/os-test.json b/test/os-test.json index 27c5427b5..3b8002541 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -134,6 +134,24 @@ "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.y" + } + }, + { + "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.y" + } + }, { "desc" : "BlackBerry", "ua" : "BlackBerry9300/5.0.0.912 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/378", @@ -278,6 +296,15 @@ "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", @@ -320,7 +347,25 @@ "expect" : { "name" : "Firefox OS", - "version" : "undefined" + "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" } }, { @@ -683,6 +728,24 @@ "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" : "Mac OS", + "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" : "Mac OS", + "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", From 36b2275add551510b859b289af639cc02bf98437 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 12:19:01 +0700 Subject: [PATCH 004/104] Improve detection rule for Mac on PowerPC --- src/ua-parser.js | 2 +- test/os-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index fc3df6e83..0885ab28a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -701,7 +701,7 @@ /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ /(mac os x)\s?([\w\s\.]*)/i, - /(macintosh|mac(?=_powerpc) )(?!.+haiku)/i // Mac OS + /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/Maemo/MeeGo/Contiki/Sailfish OS diff --git a/test/os-test.json b/test/os-test.json index 3b8002541..be59b19b5 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -728,6 +728,15 @@ "version" : "undefined" } }, + { + "desc" : "Mac OS on PowerPC", + "ua" : "Mozilla/4.0 (compatible; MSIE 5.0b1; Mac_PowerPC)", + "expect" : + { + "name" : "Mac OS", + "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", From f715023f476f3026ef2fabbb2250e1df1d6ac0e3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 12:24:34 +0700 Subject: [PATCH 005/104] Improve device detection: categorize PDA as mobile --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 0885ab28a..cfc0861b0 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -659,7 +659,7 @@ ], [MODEL, [TYPE, TABLET]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet ], [[TYPE, TABLET]], [ - /(phone|mobile(?:[;\/]| safari))/i // Unidentifiable Mobile + /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ /(android[\w\.\s\-]{0,9});.+buil/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] diff --git a/test/device-test.json b/test/device-test.json index 41da99fcc..eab90704a 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -2514,5 +2514,14 @@ "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" + } } ] From 559ecaacb6aa471f2cb5b88c10cfc5f6d64203d6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 12:28:24 +0700 Subject: [PATCH 006/104] Improve browser detection: Netscape with version --- src/ua-parser.js | 2 +- test/browser-test.json | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index cfc0861b0..94d34fe59 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -319,7 +319,7 @@ ], [NAME, VERSION], [ // Gecko based - /(navigator|netscape)\/([\w\.-]+)/i // Netscape + /(navigator|netscape\d?)\/([\w\.-]+)/i // Netscape ], [[NAME, 'Netscape'], VERSION], [ /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality ], [VERSION, [NAME, FIREFOX+' Reality']], [ diff --git a/test/browser-test.json b/test/browser-test.json index 7c1c8ff6a..c77e3168f 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -748,6 +748,16 @@ "major" : "8" } }, + { + "desc" : "Netscape 6", + "ua" : "Mozilla/5.0 (Windows; U; Win95; de-DE; rv:0.9.2) Gecko/20010726 Netscape6/6.1", + "expect" : + { + "name" : "Netscape", + "version" : "6.1", + "major" : "6" + } + }, { "desc" : "Nokia Browser", "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaN8-00/025.007; 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", From c53a2a1f72e3b632bcfaafb757f074d8c6056cac Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 12:55:37 +0700 Subject: [PATCH 007/104] Improve os detection: Windows Mobile without version --- src/ua-parser.js | 4 ++-- test/os-test.json | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 94d34fe59..8ce831f71 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -690,8 +690,8 @@ /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ /(windows) nt 6\.2; (arm)/i, // Windows RT - /(windows phone(?: os)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows mobile|windows)[\s\/]?([ntce\d\.\s]+[\w\.]+)(?!.+xbox)/i + /(windows (?:phone(?: os)?|mobile))[\s\/]?([\d\.\s\w]*)/i, // Windows Phone + /(windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ diff --git a/test/os-test.json b/test/os-test.json index be59b19b5..14590f393 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -107,6 +107,15 @@ "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", @@ -140,7 +149,7 @@ "expect" : { "name" : "Windows", - "version" : "NT x.y" + "version" : "NT x" } }, { @@ -149,7 +158,7 @@ "expect" : { "name" : "Windows", - "version" : "NT x.y" + "version" : "NT x" } }, { From c05e4e837fe67a9d820cc9e7d5895c0e2ae216d8 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 13:11:25 +0700 Subject: [PATCH 008/104] Add new OS: HP-UX --- readme.md | 6 +++--- src/ua-parser.js | 2 +- test/os-test.json | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 08102cb28..806cf74eb 100644 --- a/readme.md +++ b/readme.md @@ -88,9 +88,9 @@ NetSurf, Presto, Tasman, Trident, w3m, WebKit # Possible 'os.name' AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, -Haiku, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Maemo, Mageia, Mandriva, -MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, -PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, +Haiku, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Maemo, Mageia, +Mandriva, MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, +Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, RISC OS, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... diff --git a/src/ua-parser.js b/src/ua-parser.js index 8ce831f71..b7a69259d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -749,7 +749,7 @@ ], [[NAME, 'Solaris'], VERSION], [ /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris /(aix) ((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX - /(plan 9|minix|beos|os\/2|amigaos|morphos|risc os|openvms|fuchsia)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia + /(plan 9|minix|beos|os\/2|amigaos|morphos|risc os|openvms|fuchsia|hp-ux)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia/HP-UX /(unix)\s?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] diff --git a/test/os-test.json b/test/os-test.json index 14590f393..8ba00952b 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -997,5 +997,14 @@ "name" : "", "version" : "" } + }, + { + "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" + } } ] From 3792900410e11d0525709148931b29f9053d9406 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 13:46:06 +0700 Subject: [PATCH 009/104] Add new browsers: Obigo, UP.Browser --- readme.md | 6 +++--- src/ua-parser.js | 9 +++------ test/browser-test.json | 30 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index 806cf74eb..b03e7b884 100644 --- a/readme.md +++ b/readme.md @@ -43,12 +43,12 @@ Firefox [Reality], Flock, Flow, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceAp IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, -Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Oculus Browser, +Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Obigo, Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, -SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, Vivaldi, Waterfox, WeChat, -Weibo, Yandex, baidu, iCab, w3m, Whale Browser... +SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, UP.Browser, Vivaldi, +Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index b7a69259d..92c177b1b 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -333,12 +333,9 @@ /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i, - // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir - /(links) \(([\w\.]+)/i, // Links - /(gobrowser)\/?([\w\.]*)/i, // GoBrowser - /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser - /(mosaic)[\/\s]([\w\.]+)/i // Mosaic + /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\s\.]?browser)[\/\s-]?v?([\w\.]+)/i, + // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser + /(links) \(([\w\.]+)/i // Links ], [NAME, VERSION] ], diff --git a/test/browser-test.json b/test/browser-test.json index c77e3168f..2f4c2e0fb 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -768,6 +768,26 @@ "major" : "7" } }, + { + "desc" : "Obigo", + "ua" : "LG-GS290/V100 Obigo/WAP2.0 Profile/MIDP-2.1 Configuration/CLDC-1.1", + "expect" : + { + "name" : "Obigo", + "version" : "WAP2.0", + "major" : "2" + } + }, + { + "desc" : "Obigo", + "ua" : "LG/KU990i/v10a Browser/Obigo-Q05A/3.6 MMS/LG-MMS-V1.0/1.2 Java/ASVM/1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1", + "expect" : + { + "name" : "Obigo", + "version" : "Q05A", + "major" : "05" + } + }, { "desc" : "Oculus Browser", "ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G920I Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/3.4.9 SamsungBrowser/4.0 Chrome/57.0.2987.146 Mobile VR Safari/537.36", @@ -1128,6 +1148,16 @@ "major" : "7" } }, + { + "desc" : "UPBrowser", + "ua" : "BenQ-CF61/1.00/WAP2.0/MIDP2.0/CLDC1.0 UP.Browser/6.3.0.4.c.1.102 (GUI) MMP/2.0", + "expect" : + { + "name" : "UP.Browser", + "version" : "6.3.0.4.c.1.102", + "major" : "6" + } + }, { "desc": "WeChat on iOS", "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H321 MicroMessenger/6.3.6 NetType/WIFI Language/zh_CN", From 9bed2b143705d467398075304b4c8904be017817 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 12 Apr 2021 15:16:28 +0700 Subject: [PATCH 010/104] Add new device vendor: Roku Source: https://github.com/WhichBrowser/Parser-PHP/blob/master/tests/data/television/roku.yaml --- readme.md | 2 +- src/ua-parser.js | 7 +++++-- test/device-test.json | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index b03e7b884..bcd4d3b64 100644 --- a/readme.md +++ b/readme.md @@ -64,7 +64,7 @@ console, mobile, tablet, smarttv, wearable, embedded Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, Essential, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, OPPO, Ouya, -Palm, Panasonic, Pebble, Polytron, Realme, RIM, Samsung, Sharp, Siemens, +Palm, Panasonic, Pebble, Polytron, Realme, RIM, Roku, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically diff --git a/src/ua-parser.js b/src/ua-parser.js index 92c177b1b..72fdc1c84 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -90,8 +90,10 @@ return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split('.')[0] : undefined; }, trim = function (str, len) { - str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, EMPTY); - return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); + if (typeof(str) === STR_TYPE) { + str = str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, EMPTY); + return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); + } }; /////////////// @@ -623,6 +625,7 @@ ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ + /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ /\b(android tv|smart[-\s]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors diff --git a/test/device-test.json b/test/device-test.json index eab90704a..8d83c6d3e 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -846,6 +846,33 @@ "type": "smarttv" } }, + { + "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": "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", From ca83d4c9c3bdb3b9c44db8cadf1844e8b3d59bda Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 16 Apr 2021 07:11:23 +0700 Subject: [PATCH 011/104] Refine some OS detection Source: - https://www.zytrax.com/tech/web/browser_ids.htm - https://developers.whatismybrowser.com/useragents/explore/operating_system_name/ --- src/ua-parser.js | 18 ++---- test/os-test.json | 162 ++++++++++++++++++++++++++++++---------------- 2 files changed, 115 insertions(+), 65 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 72fdc1c84..53a5cf5ba 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -704,8 +704,8 @@ /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ - // Mobile OSes // Android/WebOS/Palm/QNX/Bada/RIM/Maemo/MeeGo/Contiki/Sailfish OS - /(android|webos|palm os|qnx|bada|rim tablet os|maemo|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i, + // Mobile OSes // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS + /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[\/\s-]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 @@ -730,26 +730,22 @@ /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation /(xbox);\s+xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) - // GNU/Linux based + // Other + /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm /(mint)[\/\s\(\)]?(\w*)/i, // Mint /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux - /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus|raspbian)(?: gnu\/linux)?(?: linux)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, - // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware - // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus + /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki)(?: gnu\/linux)?(?: enterprise)?(?:[\s-]linux)?(?:-gnu)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, + // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux /(gnu)\s?([\w\.]*)/i, // GNU - - // BSD based /\b([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly /(haiku)\s(\w+)/i // Haiku ], [NAME, VERSION], [ - - // Other /(sunos)\s?([\w\.\d]*)/i // Solaris ], [[NAME, 'Solaris'], VERSION], [ /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris /(aix) ((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX - /(plan 9|minix|beos|os\/2|amigaos|morphos|risc os|openvms|fuchsia|hp-ux)/i, // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia/HP-UX + /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX /(unix)\s?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] diff --git a/test/os-test.json b/test/os-test.json index 8ba00952b..d614487af 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -667,11 +667,11 @@ }, { "desc" : "Solaris", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7) Gecko/20070606", "expect" : { - "name" : "", - "version" : "" + "name" : "Solaris", + "version" : "sun4u" } }, { @@ -703,11 +703,11 @@ }, { "desc" : "DragonFly", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1) Gecko/20090720 Firefox/3.5.1", "expect" : { - "name" : "", - "version" : "" + "name" : "DragonFly", + "version" : "undefined" } }, { @@ -847,137 +847,173 @@ }, { "desc" : "AIX", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; U; AIX 000138384C00; en-US; rv:1.0.1) Gecko/20030213 Netscape/7.0", "expect" : { - "name" : "", - "version" : "" + "name" : "AIX", + "version" : "undefined" } }, { "desc" : "Plan9", - "ua" : "", + "ua" : "NCSA_Mosaic/5.0 (X11;Plan 9 4.0)", "expect" : { - "name" : "", - "version" : "" + "name" : "Plan 9", + "version" : "4.0" } }, { "desc" : "Minix", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; Original ; Minix 3.3 ; rv:3.0)", "expect" : { - "name" : "", - "version" : "" + "name" : "Minix", + "version" : "3.3" } }, { "desc" : "BeOS", - "ua" : "", + "ua" : "Mozilla/5.0 (BeOS; U; BeOS BePC; en-US; rv:1.8.1.8pre) Gecko/20070926 SeaMonkey/1.1.5pre", "expect" : { - "name" : "", - "version" : "" + "name" : "BeOS", + "version" : "undefined" } }, { "desc" : "OS/2", - "ua" : "", + "ua" : "Links (2.1pre14; OS/2 1 i386; 80x33)", "expect" : { - "name" : "", - "version" : "" + "name" : "OS/2", + "version" : "undefined" } }, { "desc" : "AmigaOS", - "ua" : "", + "ua" : "Mozilla/4.0 (compatible; AWEB 3.4 SE; AmigaOS)", "expect" : { - "name" : "", - "version" : "" + "name" : "AmigaOS", + "version" : "undefined" } }, { "desc" : "MorphOS", - "ua" : "", + "ua" : "AmigaVoyager/3.4.4 (MorphOS/PPC native)", "expect" : { - "name" : "", - "version" : "" + "name" : "MorphOS", + "version" : "undefined" } }, { "desc" : "UNIX", - "ua" : "", + "ua" : "Surf/0.4.1 (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)", "expect" : { - "name" : "", - "version" : "" + "name" : "Unix", + "version" : "undefined" } }, { "desc" : "Joli", - "ua" : "", + "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" : "", - "version" : "" + "name" : "Joli", + "version" : "1.2" } }, { "desc" : "CentOS", - "ua" : "", + "ua" : "Konqueror/15.13 (CentOS Linux 7.4; cs-CZ;)", "expect" : { - "name" : "", - "version" : "" + "name" : "CentOS", + "version" : "7.4" } }, { "desc" : "PCLinuxOS", - "ua" : "", + "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" : "", - "version" : "" + "name" : "PCLinuxOS", + "version" : "1.9.2.13-1pclos2010" } }, { "desc" : "RedHat", - "ua" : "", + "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" : "", - "version" : "" + "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" : "", + "ua" : "Flock/2.16 (Zenwalk 7.3; es_PR;)", "expect" : { - "name" : "", - "version" : "" + "name" : "Zenwalk", + "version" : "7.3" } }, { "desc" : "Hurd", - "ua" : "", + "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" : "", - "version" : "" + "name" : "Hurd", + "version" : "0.9" } }, { "desc" : "Linux", - "ua" : "", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36", "expect" : { - "name" : "", - "version" : "" + "name" : "Linux", + "version" : "x86_64" } }, { @@ -991,11 +1027,11 @@ }, { "desc" : "Palm OS", - "ua" : "", + "ua" : "Mozilla/4.76 [en] (PalmOS; U; WebPro3.0; Palm-Arz1)", "expect" : { - "name" : "", - "version" : "" + "name" : "Palm", + "version" : "undefined" } }, { @@ -1006,5 +1042,23 @@ "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" + } } ] From ca644313d629896aa857a1c412753d06e28cb718 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 16 Apr 2021 07:15:50 +0700 Subject: [PATCH 012/104] Remove oldEdge map --- src/ua-parser.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 53a5cf5ba..8b8986b6a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -184,15 +184,6 @@ '2.0.4' : '/419', '?' : '/' }, - oldEdgeMap = { - '0.1' : '12.', - '21' : '13.', - '31' : '14.', - '39' : '15.', - '41' : '16.', - '42' : '17.', - '44' : '18.' - }, windowsVersionMap = { 'ME' : '4.90', 'NT 3.11' : 'NT3.51', @@ -219,9 +210,6 @@ ], [VERSION, [NAME, 'Chrome']], [ /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge ], [VERSION, [NAME, 'Edge']], [ - // breaking change (reserved for next major release): - ///edge\/([\w\.]+)/i // Old Edge (Trident) - //], [[VERSION, mapper.str, maps.browser.oldEdge.version], [NAME, 'Edge']], [ // Presto based /(opera mini)\/([\w\.-]+)/i, // Opera Mini From 8e55e001779e136271cdf8b4ed977868e32e84ec Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 16 Apr 2021 23:02:11 +0700 Subject: [PATCH 013/104] Replace `\s` with space, saving ~0,3KB --- dist/ua-parser.min.js | 13 +-- dist/ua-parser.pack.js | 13 +-- src/ua-parser.js | 230 ++++++++++++++++++++--------------------- 3 files changed, 123 insertions(+), 133 deletions(-) diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index f5421ebaf..14b5e8c5d 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,9 +1,4 @@ -/*!@license - * UAParser.js v0.7.28 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.28",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",EMBEDDED="embedded",UA_MAX_LENGTH=255;var util={extend:function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},has:function(str1,str2){return typeof str1===STR_TYPE?str2.toLowerCase().indexOf(str1.toLowerCase())!==-1:false},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,"").split(".")[0]:undefined},trim:function(str,len){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var mapper={rgx:function(ua,arrays){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}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;jUA_MAX_LENGTH?util.trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define==="function"&&define.amd){define(function(){return UAParser})}else if(typeof window!=="undefined"){window.UAParser=UAParser}}var $=typeof window!=="undefined"&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); +/* UAParser.js v0.7.28 + Copyright © 2012-2021 Faisal Salman + MIT License */ +(function(window,undefined){"use strict";var LIBVERSION="0.7.28",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",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i in arr){enums[arr[i].toUpperCase()]=arr[i]}return enums},has=function(str1,str2){return typeof str1===STR_TYPE?lowerize(str2).indexOf(lowerize(str1))!==-1:false},lowerize=function(str){return str.toLowerCase()},majorize=function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,EMPTY).split(".")[0]:undefined},trim=function(str,len){if(typeof str===STR_TYPE){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,EMPTY);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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.pack.js b/dist/ua-parser.pack.js index c12e548dc..34c92c5fa 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,9 +1,4 @@ -/*!@license - * UAParser.js v0.7.28 - * Lightweight JavaScript-based User-Agent string parser - * https://github.com/faisalman/ua-parser-js - * - * Copyright © 2012-2021 Faisal Salman - * Licensed under MIT License - */ -!function(r,b){"use strict";var u="function",e="undefined",c="object",a="string",i="model",s="name",o="type",n="vendor",t="version",l="architecture",w="console",d="mobile",m="tablet",p="smarttv",f="wearable",h="embedded",g={extend:function(i,s){var e,o={};for(e in i)s[e]&&s[e].length%2==0?o[e]=s[e].concat(i[e]):o[e]=i[e];return o},has:function(i,s){return typeof i==a&&-1!==s.toLowerCase().indexOf(i.toLowerCase())},lowerize:function(i){return i.toLowerCase()},major:function(i){return typeof i==a?i.replace(/[^\d\.]/g,"").split(".")[0]:b},trim:function(i,s){return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof s==e?i:i.substring(0,255)}},v={rgx:function(i,s){for(var e,o,r,a,n,t=0;t + MIT License */ +!function(r,d){"use strict";function i(i){var e,o={};for(e in i)o[i[e].toUpperCase()]=i[e];return o}function t(i,e){return typeof i==w&&-1!==B(e).indexOf(B(i))}function n(i,e){if(typeof i==w)return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof e==b?i:i.substring(0,255)}function s(i,e){for(var o,a,r,t,n,s=0;s= 8.0 + /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 ], [VERSION, [NAME, OPERA+' Mini']], [ /\bopr\/([\w\.]+)/i // Opera Webkit ], [VERSION, [NAME, OPERA]], [ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle - /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer + /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based - /(avant |iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser - /(ba?idubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser + /(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser + /(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer // 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|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([\w\.-]+)/i, + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ - /(?:\buc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser + /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser ], [VERSION, [NAME, 'UC'+BROWSER]], [ /\bqbcore\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ @@ -242,7 +242,7 @@ ], [VERSION, [NAME, 'WeChat']], [ /konqueror\/([\w\.]+)/i // Konqueror ], [VERSION, [NAME, 'Konqueror']], [ - /trident.+rv[:\s]([\w\.]{1,9})\b.+like gecko/i // IE11 + /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11 ], [VERSION, [NAME, 'IE']], [ /yabrowser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, 'Yandex']], [ @@ -260,7 +260,7 @@ ], [VERSION, [NAME, OPERA+' Coast']], [ /miuibrowser\/([\w\.]+)/i // MIUI Browser ], [VERSION, [NAME, 'MIUI '+BROWSER]], [ - /fxios\/([\w\.-]+)/i // Firefox for iOS + /fxios\/([-\w\.]+)/i // Firefox for iOS ], [VERSION, [NAME, FIREFOX]], [ /\bqihu|(qi?ho?o?|360)browser/i // 360 ], [[NAME, '360 '+BROWSER]], [ @@ -269,10 +269,10 @@ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ /(electron)\/([\w\.]+) safari/i, // Electron-based App - /(tesla)(?:\sqtcarbrowser|\/(20\d\d\.[\w\.-]+))/i, // Tesla - /m?(qqbrowser|baiduboxapp|2345Explorer)[\/\s]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser + /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla + /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [ - /(metasr)[\/\s]?([\w\.]+)/i, // SouGouBrowser + /(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser /(lbbrowser)/i // LieBao Browser ], [NAME], [ @@ -281,49 +281,49 @@ ], [[NAME, 'Facebook'], VERSION], [ /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android - /(chromium|instagram)[\/\s]([\w\.-]+)/i // Chromium/Instagram + /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram ], [NAME, VERSION], [ - /\bgsa\/([\w\.]+)\s.*safari\//i // Google Search Appliance on iOS + /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ - /headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless + /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME+' Headless']], [ - /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView + / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, CHROME+' WebView'], VERSION], [ - /droid.+\sversion\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser + /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser ], [VERSION, [NAME, 'Android '+BROWSER]], [ - /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia + /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ - /version\/([\w\.]+)\s.*mobile\/\w+\s(safari)/i // Mobile Safari + /version\/([\w\.]+) .*mobile\/\w+ (safari)/i // Mobile Safari ], [VERSION, [NAME, 'Mobile Safari']], [ - /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile + /version\/([\w\.]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ - /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 + /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 ], [NAME, [VERSION, strMapper, oldSafariMap]], [ /(webkit|khtml)\/([\w\.]+)/i ], [NAME, VERSION], [ // Gecko based - /(navigator|netscape\d?)\/([\w\.-]+)/i // Netscape + /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape ], [[NAME, 'Netscape'], VERSION], [ /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality ], [VERSION, [NAME, FIREFOX+' Reality']], [ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox - /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/\s]?([\w\.\+]+)/i, + /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i, // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar - /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i, + /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix /(firefox)\/([\w\.]+)/i, // Other Firefox-based - /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla + /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\s\.]?browser)[\/\s-]?v?([\w\.]+)/i, + /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser /(links) \(([\w\.]+)/i // Links ], [NAME, VERSION] @@ -331,7 +331,7 @@ cpu : [[ - /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i // AMD64 (x64) + /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i // AMD64 (x64) ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i // IA32 (quicktime) @@ -347,10 +347,10 @@ ], [[ARCHITECTURE, 'armhf']], [ // PocketPC mistakenly identified as PowerPC - /windows\s(ce|mobile); ppc;/i + /windows (ce|mobile); ppc;/i ], [[ARCHITECTURE, 'arm']], [ - /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC + /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ /(sun4\w)[;\)]/i // SPARC @@ -372,14 +372,14 @@ /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, - /samsung[\s-]([\w-]+)/i, + /samsung[- ]([-\w]+)/i, /sec-(sgh\w+)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ // Apple - /\((ip(?:hone|od)[\s\w]*);/i // iPod/iPhone + /\((ip(?:hone|od)[\w ]*);/i // iPod/iPhone ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ - /\((ipad);[\w\s\),;-]+apple/i, // iPad + /\((ipad);[-\w\),; ]+apple/i, // iPad /applecoremedia\/[\w\.]+ \((ipad)/i, /\b(ipad)\d\d?,\d\d?[;\]].+ios/i ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ @@ -387,19 +387,19 @@ // Huawei /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i, ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ - /huawei([\w\s-]+)[;\)]/i, + /huawei([-\w ]+)[;\)]/i, /\b(nexus 6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, - /\b(\w{2,4}-[atu][ln][01259][019])[;\)\s]/i + /\b(\w{2,4}-[atu][ln][01259][019])[;\) ]/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi - /\b(poco[\s\w]+)(?: bui|\))/i, // Xiaomi POCO - /\b;\s(\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models - /\b(hm[\s\-_]?note?[\s_]?(?:\d\w)?) bui/i, // Xiaomi Hongmi - /\b(redmi[\s\-_]?(?:note|k)?[\w\s_]+)(?: bui|\))/i, // Xiaomi Redmi - /\b(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?) bui/i // Xiaomi Mi + /\b(poco[\w ]+)(?: 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 + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte)?[_ ]?(?:\d?\w?)[_ ]?(?:plus)?) bui/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ - /\b(mi[\s\-_]?(?:pad)(?:[\w\s_]+))(?: bui|\))/i // Mi Pad tablets + /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO @@ -417,48 +417,48 @@ ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [ // Motorola - /\b(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w\s]+build\//i, - /\bmot(?:orola)?[\s-](\w*)/i, - /((?:moto[\s\w\(\)]+|xt\d{3,4}|nexus\s6)(?= bui|\)))/i + /\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 ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ - /\b(mz60\d|xoom[\s2]{0,2}) build\//i + /\b(mz60\d|xoom[2 ]{0,2}) build\//i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ // LG - /((?=lg)?[vl]k\-?\d{3})\sbui|\s3\.[\s\w;-]{10}lg?-([06cv9]{3,4})/i + /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ - /(lm-?f100[nv]?|nexus\s[45])/i, - /\blg[e;\s\/-]+((?!browser|netcast)\w+)/i, - /\blg(\-?[\d\w]+)\sbui/i + /(lm-?f100[nv]?|nexus [45])/i, + /\blg[-e;\/ ]+((?!browser|netcast)\w+)/i, + /\blg(\-?[\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo - /(ideatab[\w\-\s]+)/i, - /lenovo\s?(s[56]000[\w-]+|tab(?:[\s\w]+)|yt[\d\w-]{6}|tb[\d\w-]{6})/i + /(ideatab[-\w ]+)/i, + /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ // Nokia /(?:maemo|nokia).*(n900|lumia \d+)/i, - /nokia[\s_-]?([\w\.-]*)/i + /nokia[-_ ]?([-\w\.]*)/i ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ // Google /(pixel c)\b/i // Google Pixel C ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ - /droid.+; (pixel[\s\daxl]{0,6})(?: bui|\))/i // Google Pixel + /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i + /droid.+ ([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ /sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [ // OnePlus - /\s(kb2005|in20[12]5|be20[12][59])\b/i, + / (kb2005|in20[12]5|be20[12][59])\b/i, /\ba000(1) bui/i, - /oneplus (a\d{4})[\s)]/i + /oneplus (a\d{4})[) ]/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ // Amazon @@ -470,26 +470,26 @@ ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [ // BlackBerry - /(playbook);[\w\s\),;-]+(rim)/i // BlackBerry PlayBook + /(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook ], [MODEL, VENDOR, [TYPE, TABLET]], [ /\b((?:bb[a-f]|st[hv])100-\d)/i, - /\(bb10;\s(\w+)/i // BlackBerry 10 + /\(bb10; (\w+)/i // BlackBerry 10 ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [ // Asus - /(?:\b|asus_)(transfo[prime\s]{4,10}\s\w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i + /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [ - /\s(z[es]6[027][01][km][ls]|zenfone \d\w?)\b/i + / (z[es]6[027][01][km][ls]|zenfone \d\w?)\b/i ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ // HTC /(nexus 9)/i // HTC Nexus 9 ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ - /(htc)[;_\s-]{1,2}([\w\s]+(?=\)| bui)|\w+)/i, // HTC + /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC // ZTE /(zte)-(\w*)/i, - /(alcatel|geeksphone|nexian|panasonic|sony)[_\s-]?([\w-]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic|sony)[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ // Acer @@ -498,34 +498,34 @@ // Meizu /droid.+; (m[1-5] note) bui/i, - /\bmz-([\w-]{2,})/i + /\bmz-([-\w]{2,})/i ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ // MIXED - /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\s_-]?([\w-]*)/i, + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron - /(hp)\s([\w\s]+\w)/i, // HP iPAQ + /(hp) ([\w ]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus - /(microsoft); (lumia[\s\w]+)/i, // Microsoft Lumia - /(lenovo)[_\s-]?([\w-]+)/i, // Lenovo + /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia + /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo /(jolla)/i, // Jolla - /(oppo)\s?([\w\s]+)\sbui/i // OPPO + /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i, // Kindle - /(nook)[\w\s]+build\/(\w+)/i, // Nook - /(dell) (strea[kpr\s\d]*[\dko])/i, // Dell Streak - /(le[\s\-]+pan)[\s\-]+(\w{1,9})\sbui/i, // Le Pan Tablets - /(trinity)[\-\s]*(t\d{3})\sbui/i, // Trinity Tablets - /(gigaset)[\s\-]+(q\w{1,9})\sbui/i, // Gigaset Tablets - /(vodafone)\s([\w\s]+)(?:\)|\sbui)/i // Vodafone + /(nook)[\w ]+build\/(\w+)/i, // Nook + /(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak + /(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets + /(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets + /(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets + /(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone ], [VENDOR, MODEL, [TYPE, TABLET]], [ /(surface duo)/i // Surface Duo ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ - /droid\s[\d\.]+; (fp\du?) b/i // Fairphone + /droid [\d\.]+; (fp\du?) b/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ /(u304aa)/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ @@ -533,11 +533,11 @@ ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ /\b(rct\w+) b/i // RCA Tablets ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ - /\b(venue[\d\s]{2,7}) b/i // Dell Venue Tablets + /\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ - /\b(?:barnes[&\s]+noble |bn[rt])([\w\s\+]*) b/i // Barnes & Noble Tablet + /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [ /\b(tm\d{3}\w+) b/i ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ @@ -552,7 +552,7 @@ /\b((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ /\b([yr]\d{2}) b/i, - /\b(dragon[\-\s]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet + /\b(dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ /\b(ns-?\w{0,9}) b/i // Insignia Tablets ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ @@ -562,15 +562,15 @@ ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ - /\b(ph-1)\s/i // Essential PH-1 + /\b(ph-1) /i // Essential PH-1 ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ - /\b(trio[\s\w\-\.]+) b/i // MachSpeed Tablets + /\b(trio[-\w\. ]+) b/i // MachSpeed Tablets ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ /\btu_(1491) b/i // Rotor Tablets ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ - /(shield[\w\s]+) b/i // Nvidia Shield Tablets + /(shield[\w ]+) b/i // Nvidia Shield Tablets ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ @@ -592,7 +592,7 @@ ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ /(playstation [345portablevi]+)/i // Playstation ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ - /\b(xbox(?: one)?(?!; xbox))[\s\);]/i // Microsoft Xbox + /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [ /////////////////// @@ -605,7 +605,7 @@ ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i, // LG SmartTV ], [[VENDOR, LG], [TYPE, SMARTTV]], [ - /(apple)\s?tv/i // Apple TV + /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ @@ -614,9 +614,9 @@ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku - /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices + /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /\b(android tv|smart[-\s]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors + /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors ], [[TYPE, SMARTTV]], [ /////////////////// @@ -634,22 +634,22 @@ // EMBEDDED /////////////////// - /(tesla)(?: qtcarbrowser|\/[\w\.-]+)/i // Tesla + /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla ], [VENDOR, [TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) /////////////////// - /droid .+?;\s([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors + /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?;\s([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors + /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ - /(android[\w\.\s\-]{0,9});.+buil/i // Generic Android Device + /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] ], @@ -664,8 +664,8 @@ /(presto)\/([\w\.]+)/i, // Presto /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna /ekioh(flow)\/([\w\.]+)/i, // Flow - /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links - /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab + /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links + /(icab)[\/ ]([23]\.[\d\.]+)/i // iCab ], [NAME, VERSION], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko @@ -678,31 +678,31 @@ /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ /(windows) nt 6\.2; (arm)/i, // Windows RT - /(windows (?:phone(?: os)?|mobile))[\s\/]?([\d\.\s\w]*)/i, // Windows Phone - /(windows)[\s\/]?([ntce\d\.\s]+\w)(?!.+xbox)/i + /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone + /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ // iOS/macOS - /ip[honead]{2,4}\b(?:.*os ([\w]+) like\smac|; opera)/i, // iOS + /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ - /(mac os x)\s?([\w\s\.]*)/i, - /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS + /(mac os x) ?([\w\. ]*)/i, + /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ // Mobile OSes // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS - /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[\/\s-]?([\w\.]*)/i, + /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry - /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS + /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ - /(?:symbian\s?os|symbos|s60(?=;)|series60)[\/\s-]?([\w\.]*)/i // Symbian + /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ - /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w\s]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS + /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS ], [VERSION, [NAME, FIREFOX+' OS']], [ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS @@ -711,30 +711,30 @@ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast ], [VERSION, [NAME, CHROME+'cast']], [ - /(cros) [\w]+\s([\w\.]+\w)/i // Chromium OS + /(cros) [\w]+ ([\w\.]+\w)/i // Chromium OS ], [[NAME, 'Chromium OS'], VERSION],[ // Console /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation - /(xbox);\s+xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) + /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) // Other /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm - /(mint)[\/\s\(\)]?(\w*)/i, // Mint - /(mageia|vectorlinux)[;\s]/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)(?: gnu\/linux)?(?: enterprise)?(?:[\s-]linux)?(?:-gnu)?[\/\s-]?(?!chrom|package)([\w\.-]*)/i, + /(mint)[\/\(\) ]?(\w*)/i, // Mint + /(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)(?: 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 - /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux - /(gnu)\s?([\w\.]*)/i, // GNU - /\b([frentopc-]{0,4}bsd|dragonfly)\s?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly - /(haiku)\s(\w+)/i // Haiku + /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux + /(gnu) ?([\w\.]*)/i, // GNU + /\b([-frentopc]{0,4}bsd|dragonfly) ?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + /(haiku) (\w+)/i // Haiku ], [NAME, VERSION], [ - /(sunos)\s?([\w\.\d]*)/i // Solaris + /(sunos) ?([\w\.\d]*)/i // Solaris ], [[NAME, 'Solaris'], VERSION], [ - /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris - /(aix) ((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX + /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris + /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX - /(unix)\s?([\w\.]*)/i // UNIX + /(unix) ?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] }; From 7b3aa9fc15ad70ac33295c797971cbe5046222a6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 18 Apr 2021 14:00:18 +0700 Subject: [PATCH 014/104] ES3 compat-fix: remove trailing comma --- .jshintrc | 3 +++ src/ua-parser.js | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 .jshintrc diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 000000000..5798043ca --- /dev/null +++ b/.jshintrc @@ -0,0 +1,3 @@ +{ + "esversion": 3 +} \ No newline at end of file diff --git a/src/ua-parser.js b/src/ua-parser.js index 5b3b5dd4a..8c7186b61 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -214,7 +214,7 @@ // Presto based /(opera mini)\/([-\w\.]+)/i, // Opera Mini /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet - /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i, // Opera + /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera ], [NAME, VERSION], [ /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 ], [VERSION, [NAME, OPERA+' Mini']], [ @@ -385,7 +385,7 @@ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei - /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i, + /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /huawei([-\w ]+)[;\)]/i, /\b(nexus 6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, @@ -603,7 +603,7 @@ ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ - /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i, // LG SmartTV + /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i // LG SmartTV ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ @@ -645,7 +645,7 @@ ], [MODEL, [TYPE, MOBILE]], [ /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [MODEL, [TYPE, TABLET]], [ - /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i, // Unidentifiable Tablet + /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ From 837042a3e8c65628349ed40ec74e4ec6c2a9ae5b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 22 Apr 2021 07:00:28 +0700 Subject: [PATCH 015/104] Improve device detection: Huawei, Xiaomi, Realme, LG, OnePlus, ASUS, ZTE, Fairphone --- src/ua-parser.js | 28 +- test/device-test.json | 2930 ++++++++++++++++++++++------------------- 2 files changed, 1622 insertions(+), 1336 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 8c7186b61..5a5c28fe1 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -385,21 +385,20 @@ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei - /\b((?:agr|ags[23]|bah2?|sht?)-a?[lw]\d{2})/i + /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ - /huawei([-\w ]+)[;\)]/i, - /\b(nexus 6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?|ele-l\d\d)/i, - /\b(\w{2,4}-[atu][ln][01259][019])[;\) ]/i + /(?:huawei|honor)([-\w ]+)[;\)]/i, + /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi /\b(poco[\w ]+)(?: bui|\))/i, // Xiaomi POCO /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models - /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi + /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi - /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte)?[_ ]?(?:\d?\w?)[_ ]?(?:plus)?) bui/i // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ - /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets + /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO @@ -413,7 +412,7 @@ ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ // Realme - /\b(rmx[12]\d{3})(?: bui|;)/i + /\b(rmx[12]\d{3})(?: bui|;|\))/i ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [ // Motorola @@ -427,9 +426,9 @@ // LG /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ - /(lm-?f100[nv]?|nexus [45])/i, + /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, /\blg[-e;\/ ]+((?!browser|netcast)\w+)/i, - /\blg(\-?[\d\w]+) bui/i + /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo @@ -457,8 +456,7 @@ // OnePlus / (kb2005|in20[12]5|be20[12][59])\b/i, - /\ba000(1) bui/i, - /oneplus (a\d{4})[) ]/i + /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ // Amazon @@ -479,7 +477,7 @@ // Asus /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [ - / (z[es]6[027][01][km][ls]|zenfone \d\w?)\b/i + / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ // HTC @@ -488,7 +486,7 @@ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC // ZTE - /(zte)-(\w*)/i, + /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, /(alcatel|geeksphone|nexian|panasonic|sony)[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ @@ -525,7 +523,7 @@ /(surface duo)/i // Surface Duo ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ - /droid [\d\.]+; (fp\du?) b/i // Fairphone + /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ /(u304aa)/i // AT&T ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index 8d83c6d3e..c8bd7c446 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -97,6 +97,15 @@ "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", @@ -205,6 +214,24 @@ "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": "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", @@ -269,2286 +296,2547 @@ } }, { - "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", + "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": "Apple", - "model": "iPad", + "vendor": "Huawei", + "model": "BAH-L09", "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/]", + "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": "Apple", - "model": "iPad", + "vendor": "Huawei", + "model": "BAH2-W19", "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]", + "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": "Apple", - "model": "iPad", + "vendor": "Huawei", + "model": "SHT-AL09", "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", + "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": "Apple", - "model": "iPod touch", - "type": "mobile" + "vendor": "Huawei", + "model": "AGS2-L09", + "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", + "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": "Lenovo", - "model": "TAB 2 A7", + "vendor": "Huawei", + "model": "AGR-W09", "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;]", + { + "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": "Lenovo", - "model": "PB2-650M", - "type": "mobile" + "vendor": "Huawei", + "model": "AGS3-W09", + "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", + "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": "Lenovo", - "model": "YT3-X90F", + "vendor": "Huawei", + "model": "AGR-L09", "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", + "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": "Lenovo", - "model": "TB-X304F", + "vendor": "Huawei", + "model": "BTV-W09", "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", + "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": "Lenovo", - "model": "TAB 2 A7", - "type": "tablet" + "vendor": "Huawei", + "model": "BLA-L29", + "type": "mobile" } }, { - "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", + "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": "Lenovo", - "model": "TB-7304X", - "type": "tablet" + "vendor": "Huawei", + "model": "TAH-AN00", + "type": "mobile" } }, { - "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", + "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": "Lenovo", - "model": "TB-X606F", - "type": "tablet" + "vendor": "Huawei", + "model": "TET-AN00", + "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", + "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 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": "LG", - "model": "K500", + "vendor": "Huawei", + "model": "ANE-LX1", "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", + "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": "LG", - "model": "Nexus 4", + "vendor": "Huawei", + "model": "CLT-L29", "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", + "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": "LG", - "model": "Nexus 4", + "vendor": "Huawei", + "model": "ELE-L29", "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", + "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": "LG", - "model": "Nexus 5", + "vendor": "Huawei", + "model": "VOG-L29", "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", + "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": "LG", - "model": "LM-F100N", + "vendor": "Huawei", + "model": "ANA-AN00", "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)", + "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": "LG", - "model": "undefined", - "type": "smarttv" + "vendor": "Huawei", + "model": "ELS-AN00", + "type": "mobile" } }, { - "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", + "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": "LG", - "model": "undefined", - "type": "smarttv" + "vendor": "Huawei", + "model": "EBG-AN10", + "type": "mobile" } }, { - "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", + "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": "Meizu", - "model": "M5 Note", + "vendor": "Huawei", + "model": "CDY-AN90", "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", + "desc": "Huawei Enjoy10e", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", "expect": { - "vendor": "Microsoft", - "model": "Lumia 950", + "vendor": "Huawei", + "model": "MED-AL00", "type": "mobile" } }, { - "desc": "Microsoft Surface Duo", - "ua": "Dalvik/2.1.0 (Linux; U; Android 10; Surface Duo Build/2020.1014.61)", + "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": "Microsoft", - "model": "Surface Duo", - "type": "tablet" + "vendor": "Huawei", + "model": "DLI-L22", + "type": "mobile" } }, { - "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", + "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": "Motorola", - "model": "XT1097", + "vendor": "Huawei", + "model": "PLK-L01", "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": "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": "Huawei", + "model": "HRY-LX1", + "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": "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": "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", + "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": "Motorola", - "model": "Nexus 6", + "vendor": "Huawei", + "model": "JSN-L21", "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", + "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": "Motorola", - "model": "DROID RAZR 4G", + "vendor": "Huawei", + "model": "MRD-LX1N", "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", + "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": "Motorola", - "model": "razr", + "vendor": "Huawei", + "model": "JKM-LX2", "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", + "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": "Apple", - "model": "iPhone", + "vendor": "Huawei", + "model": "AMN-LX3", "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/]", + "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": "Apple", - "model": "iPhone", + "vendor": "Huawei", + "model": "SNE-LX1", "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/]", + "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": "Apple", - "model": "iPhone", + "vendor": "Huawei", + "model": "WAS-LX1A", "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/]", + "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": "Apple", - "model": "iPhone", + "vendor": "Huawei", + "model": "DRA-LX5", "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/]", + "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": "Apple", - "model": "iPhone", + "vendor": "Huawei", + "model": "BKK-LX2", "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", + "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": "iPod touch", - "type": "mobile" + "model": "iPad", + "type": "tablet" } }, { - "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", + "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": "Motorola", - "model": "XT1058", - "type": "mobile" + "vendor": "Apple", + "model": "iPad", + "type": "tablet" } }, { - "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", + "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": "Motorola", - "model": "moto g(6) play", - "type": "mobile" + "vendor": "Apple", + "model": "iPad", + "type": "tablet" } }, { - "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", + "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": "Motorola", - "model": "moto g(7) supra", + "vendor": "Apple", + "model": "iPod touch", "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", + "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": "Motorola", - "model": "Moto E (4)", - "type": "mobile" + "vendor": "Lenovo", + "model": "TAB 2 A7", + "type": "tablet" } }, - { - "desc": "Nokia3xx", - "ua": "Nokia303/14.87 CLDC-1.1", + { + "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": "Nokia", - "model": "303", + "vendor": "Lenovo", + "model": "PB2-650M", "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", + "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": "Nokia", - "model": "3.2", - "type": "mobile" + "vendor": "Lenovo", + "model": "YT3-X90F", + "type": "tablet" } }, { - "desc": "Nokia N9", - "ua": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", + "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": "Nokia", - "model": "N9", - "type": "mobile" + "vendor": "Lenovo", + "model": "TB-X304F", + "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", + "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": "Nokia", - "model": "2720 Flip", - "type": "mobile" + "vendor": "Lenovo", + "model": "TAB 2 A7", + "type": "tablet" } }, { - "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", + "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": "OnePlus", - "model": "1", - "type": "mobile" + "vendor": "Lenovo", + "model": "TB-7304X", + "type": "tablet" } }, { - "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", + "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": "OnePlus", - "model": "1", - "type": "mobile" + "vendor": "Lenovo", + "model": "TB-X606F", + "type": "tablet" } }, { - "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", + "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": "OnePlus", - "model": "A3000", + "vendor": "LG", + "model": "LM-V405", "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", + "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": "OnePlus", - "model": "A6003", + "vendor": "LG", + "model": "LM-X410.F", "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", + "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": "OnePlus", - "model": "A6010", + "vendor": "LG", + "model": "LM-X410.FGN", "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", + "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": "OnePlus", - "model": "KB2005", + "vendor": "LG", + "model": "LM-Q720", "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", + "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": "OnePlus", - "model": "IN2025", + "vendor": "LG", + "model": "LM-G710VM", "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", + "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": "OnePlus", - "model": "BE2015", + "vendor": "LG", + "model": "K500", "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", + "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": "OnePlus", - "model": "BE2029", + "vendor": "LG", + "model": "Nexus 4", "type": "mobile" } }, { - "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", + "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": "OPPO", - "model": "R831T", + "vendor": "LG", + "model": "Nexus 4", "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", + "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": "OPPO", - "model": "R7s", + "vendor": "LG", + "model": "Nexus 5", "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", + "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": "OPPO", - "model": "CPH1803", + "vendor": "LG", + "model": "LM-F100N", "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", + "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": "OPPO", - "model": "CPH2083", - "type": "mobile" + "vendor": "LG", + "model": "undefined", + "type": "smarttv" } }, { - "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", + "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": "OPPO", - "model": "PCAT00", - "type": "mobile" + "vendor": "LG", + "model": "undefined", + "type": "smarttv" } }, { - "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", + "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": "OPPO", - "model": "PCLM50", + "vendor": "Meizu", + "model": "M5 Note", "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", + "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": "OPPO", - "model": "PEAM00", + "vendor": "Microsoft", + "model": "Lumia 950", "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", + "desc": "Microsoft Surface Duo", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; Surface Duo Build/2020.1014.61)", "expect": { - "vendor": "OPPO", - "model": "PDPM00", - "type": "mobile" + "vendor": "Microsoft", + "model": "Surface Duo", + "type": "tablet" } }, { - "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", + "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": "OPPO", - "model": "PDNT00", + "vendor": "Motorola", + "model": "XT1097", "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" : "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": "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" : "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": "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", + "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": "Realme", - "model": "RMX1811", + "vendor": "Motorola", + "model": "Nexus 6", "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", + "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": "Realme", - "model": "RMX2193", + "vendor": "Motorola", + "model": "DROID RAZR 4G", "type": "mobile" } }, { - "desc": "Philips SmartTV", - "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", + "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": "Philips", - "model": "", - "type": "smarttv" + "vendor": "Motorola", + "model": "razr", + "type": "mobile" } }, { - "desc": "Roku", - "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", + "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": "Roku", - "model": "", - "type": "smarttv" + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" } }, { - "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)", + "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": "Roku", - "model": "DVP-8.10", - "type": "smarttv" + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" } }, { - "desc": "Roku", - "ua": "Roku4640X/DVP-7.70 (297.70E04154A)", + "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": "Roku", - "model": "DVP-7.70", - "type": "smarttv" + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" } }, { - "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", + "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": "Amazon", - "model": "KFTT", - "type": "tablet" + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" } }, { - "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", + "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": "Amazon", - "model": "KFTT", - "type": "tablet" + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-A217F", + "vendor": "Apple", + "model": "iPod touch", "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", + "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": "Samsung", - "model": "SM-A315G", + "vendor": "Motorola", + "model": "XT1058", "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", + "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": "Samsung", - "model": "SM-A505F", + "vendor": "Motorola", + "model": "moto g(6) play", "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", + "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": "Samsung", - "model": "SM-A805F", + "vendor": "Motorola", + "model": "moto g(7) supra", "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", + "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": "Samsung", - "model": "SM-F900U", + "vendor": "Motorola", + "model": "Moto E (4)", "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", + "desc": "Nokia3xx", + "ua": "Nokia303/14.87 CLDC-1.1", "expect": { - "vendor": "Samsung", - "model": "SM-F700N", + "vendor": "Nokia", + "model": "303", "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", + "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": "Samsung", - "model": "SM-F916B", + "vendor": "Nokia", + "model": "3.2", "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", + "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": "Samsung", - "model": "SM-G970F", + "vendor": "Nokia", + "model": "N9", "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", + "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": "Samsung", - "model": "SM-N976V", + "vendor": "Nokia", + "model": "2720 Flip", "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", + "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": "Samsung", - "model": "SM-C5000", + "vendor": "OnePlus", + "model": "A0001", "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", + "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": "Samsung", - "model": "GT-N5100", - "type": "tablet" + "vendor": "OnePlus", + "model": "A0001", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-T231", - "type": "tablet" + "vendor": "OnePlus", + "model": "A2003", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-P610", - "type": "tablet" + "vendor": "OnePlus", + "model": "A3000", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-P550", - "type": "tablet" + "vendor": "OnePlus", + "model": "A6003", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-T515", - "type": "tablet" + "vendor": "OnePlus", + "model": "A6010", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-T870", - "type": "tablet" + "vendor": "OnePlus", + "model": "KB2005", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-T700", - "type": "tablet" + "vendor": "OnePlus", + "model": "IN2025", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-T520", - "type": "tablet" + "vendor": "OnePlus", + "model": "BE2015", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "SM-P605", - "type": "tablet" + "vendor": "OnePlus", + "model": "BE2029", + "type": "mobile" } }, { - "desc": "Samsung SmartTV2011", - "ua": "HbbTV/1.1.1 (;;;;;) Maple;2011", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2011", - "type": "smarttv" + "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": "Samsung SmartTV2012", - "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit", + "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": "Samsung", - "model": "SmartTV2012", - "type": "smarttv" + "vendor": "OPPO", + "model": "R7s", + "type": "mobile" } }, { - "desc": "Samsung SmartTV2014", - "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2014;T-NT14UDEUC-1060.4;;) WebKit", + "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": "Samsung", - "model": "SmartTV2014", - "type": "smarttv" + "vendor": "OPPO", + "model": "CPH1803", + "type": "mobile" } }, { - "desc": "Samsung SmartTV", - "ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42", + "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": "undefined", - "model": "undefined", - "type": "smarttv" + "vendor": "OPPO", + "model": "CPH2083", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "undefined", - "type": "smarttv" + "vendor": "OPPO", + "model": "PCAT00", + "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", + "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": "Sony", - "model": "G8141", + "vendor": "OPPO", + "model": "PCLM50", "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", + "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": "Sony", - "model": "C5303", + "vendor": "OPPO", + "model": "PEAM00", "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", + "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": "Sony", - "model": "SO-02F", + "vendor": "OPPO", + "model": "PDPM00", "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", + "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": "Sony", - "model": "D6653", + "vendor": "OPPO", + "model": "PDNT00", "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", + "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": "Sony", - "model": "SOL25", + "vendor": "OPPO", + "model": "PAFM00", "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", + "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": "Sony", - "model": "C5302", + "vendor": "OPPO", + "model": "X9007", "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", + "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": "Sony", - "model": "XQ-AD51", + "vendor": "Realme", + "model": "RMX1811", "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", + "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": "Sony", - "model": "XQ-AT51", + "vendor": "Realme", + "model": "RMX1941", "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", + "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": "Sony", - "model": "XQ-AU52", + "vendor": "Realme", + "model": "RMX2193", "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", + "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": "Sony", - "model": "XQ-AQ52", + "vendor": "Realme", + "model": "RMX1801", "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", + "desc": "Philips SmartTV", + "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" + "vendor": "Philips", + "model": "", + "type": "smarttv" } }, { - "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", + "desc": "Roku", + "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" + "vendor": "Roku", + "model": "", + "type": "smarttv" } }, { - "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", + "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": "Sony", - "model": "Xperia Tablet", - "type": "tablet" + "vendor": "Roku", + "model": "DVP-8.10", + "type": "smarttv" } }, { - "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", + "desc": "Roku", + "ua": "Roku4640X/DVP-7.70 (297.70E04154A)", "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" + "vendor": "Roku", + "model": "DVP-7.70", + "type": "smarttv" } }, { - "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": "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" : "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": "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": "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", + "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": "Xiaomi", - "model": "2013023", + "vendor": "Samsung", + "model": "SM-A217F", "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", + "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": "Xiaomi", - "model": "HM NOTE 1W", + "vendor": "Samsung", + "model": "SM-A315G", "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", + "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": "Xiaomi", - "model": "MI 3C", + "vendor": "Samsung", + "model": "SM-A505F", "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", + "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": "Xiaomi", - "model": "MI 5", + "vendor": "Samsung", + "model": "SM-A805F", "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", + "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": "Xiaomi", - "model": "MI 6", + "vendor": "Samsung", + "model": "SM-F900U", "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", + "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": "Xiaomi", - "model": "MI 5s Plus", + "vendor": "Samsung", + "model": "SM-F700N", "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", + "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": "Xiaomi", - "model": "Mi A1", + "vendor": "Samsung", + "model": "SM-F916B", "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", + "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": "Xiaomi", - "model": "MI NOTE LTE", + "vendor": "Samsung", + "model": "SM-G970F", "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", + "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": "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;]", + "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": "Xiaomi", - "model": "MI PAD 2", + "vendor": "Samsung", + "model": "SM-C5000", + "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": "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", + "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": "Xiaomi", - "model": "MI PAD 4 PLUS", + "vendor": "Samsung", + "model": "SM-T231", "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", + "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": "Xiaomi", - "model": "POCO X2", - "type": "mobile" + "vendor": "Samsung", + "model": "SM-P610", + "type": "tablet" } }, { - "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", + "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": "Xiaomi", - "model": "Redmi 4A", - "type": "mobile" + "vendor": "Samsung", + "model": "SM-P550", + "type": "tablet" } }, { - "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", + "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": "Xiaomi", - "model": "Redmi K30 5G", - "type": "mobile" + "vendor": "Samsung", + "model": "SM-T515", + "type": "tablet" } }, { - "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", + "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": "Xiaomi", - "model": "Redmi K30 Pro", - "type": "mobile" + "vendor": "Samsung", + "model": "SM-T870", + "type": "tablet" } }, { - "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", + "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": "Xiaomi", - "model": "Redmi Note 3", - "type": "mobile" + "vendor": "Samsung", + "model": "SM-T700", + "type": "tablet" } }, { - "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", + "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": "Xiaomi", - "model": "Redmi Note 9 Pro Max", - "type": "mobile" + "vendor": "Samsung", + "model": "SM-T520", + "type": "tablet" } }, { - "desc": "PlayStation 4", - "ua": "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", + "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": "Sony", - "model": "PlayStation 4", - "type": "console" + "vendor": "Samsung", + "model": "SM-P605", + "type": "tablet" } }, { - "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", + "desc": "Samsung SmartTV2011", + "ua": "HbbTV/1.1.1 (;;;;;) Maple;2011", "expect": { - "vendor": "Sony", - "model": "Playstation 5", - "type": "console" + "vendor": "Samsung", + "model": "SmartTV2011", + "type": "smarttv" } }, { - "desc": "PlayStation Vita", - "ua": "Mozilla/5.0 (PlayStation Vita 3.52) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2", + "desc": "Samsung SmartTV2012", + "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit", "expect": { - "vendor": "Sony", - "model": "PlayStation Vita", - "type": "console" + "vendor": "Samsung", + "model": "SmartTV2012", + "type": "smarttv" } }, { - "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", + "desc": "Samsung SmartTV2014", + "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2014;T-NT14UDEUC-1060.4;;) WebKit", "expect": { - "vendor": "Nintendo", - "model": "Switch", - "type": "console" + "vendor": "Samsung", + "model": "SmartTV2014", + "type": "smarttv" } }, { - "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", + "desc": "Samsung SmartTV", + "ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42", "expect": { - "vendor": "Nintendo", - "model": "WiiU", - "type": "console" + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" } }, { - "desc": "Nintendo Wii", - "ua": "Opera/9.10 (Nintendo Wii; U; ; 1621; en)", + "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": "Nintendo", - "model": "Wii", - "type": "console" + "vendor": "Samsung", + "model": "undefined", + "type": "smarttv" } }, { - "desc": "Nintendo 3DS", - "ua": "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7610.EU", + "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": "Nintendo", - "model": "3DS", - "type": "console" + "vendor": "Sony", + "model": "G8141", + "type": "mobile" } }, { - "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", + "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": "Nintendo", - "model": "3DS", - "type": "console" + "vendor": "Sony", + "model": "C5303", + "type": "mobile" } }, { - "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", + "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": "Samsung", - "model": "Galaxy Nexus", + "vendor": "Sony", + "model": "SO-02F", "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", + "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": "Samsung", - "model": "SM-C900F", + "vendor": "Sony", + "model": "D6653", "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", + "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": "Samsung", - "model": "SM-G900F", + "vendor": "Sony", + "model": "SOL25", "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", + "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": "Samsung", - "model": "SM-G920I", + "vendor": "Sony", + "model": "C5302", "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", + "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": "Samsung", - "model": "SM-G925I", + "vendor": "Sony", + "model": "XQ-AD51", "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", + "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": "Samsung", - "model": "SM-N920C", + "vendor": "Sony", + "model": "XQ-AT51", "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", + "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": "Samsung", - "model": "SM-N920C", + "vendor": "Sony", + "model": "XQ-AU52", "type": "mobile" } }, { - "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", + "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": "Google", - "model": "Chromecast", - "type": "smarttv" + "vendor": "Sony", + "model": "XQ-AQ52", + "type": "mobile" } }, { - "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", + "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": "Google", - "model": "Pixel C", + "vendor": "Sony", + "model": "Xperia Tablet", "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", + "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": "Google", - "model": "Pixel C", + "vendor": "Sony", + "model": "Xperia Tablet", "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", + "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": "Google", - "model": "Pixel", - "type": "mobile" + "vendor": "Sony", + "model": "Xperia 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", + "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": "Google", - "model": "Pixel XL", - "type": "mobile" + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" } }, { - "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" : "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": "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" : "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": "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", + "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": "Google", - "model": "Pixel 2 XL", + "vendor": "Xiaomi", + "model": "2013023", "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", + "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": "Google", - "model": "Pixel 2 XL", + "vendor": "Xiaomi", + "model": "HM NOTE 1W", "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", + "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": "Google", - "model": "Pixel 3", + "vendor": "Xiaomi", + "model": "MI 3C", "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", + "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": "Google", - "model": "Pixel 3 XL", + "vendor": "Xiaomi", + "model": "MI 5", "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", + "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": "Google", - "model": "Pixel 3 XL", + "vendor": "Xiaomi", + "model": "MI 6", "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", + "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": "Google", - "model": "Pixel 3a", + "vendor": "Xiaomi", + "model": "MI 5s Plus", "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", + "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": "Google", - "model": "Pixel 3a XL", + "vendor": "Xiaomi", + "model": "Mi A1", "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", + "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": "Google", - "model": "Pixel 4", + "vendor": "Xiaomi", + "model": "MI NOTE LTE", "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", + "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": "Google", - "model": "Pixel 4a", + "vendor": "Xiaomi", + "model": "MI-ONE Plus", "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", + "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": "Google", - "model": "Pixel 4 XL", + "vendor": "Xiaomi", + "model": "MI MAX 3", "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", + "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": "Google", - "model": "Pixel 5", + "vendor": "Xiaomi", + "model": "Mi A1", "type": "mobile" } }, { - "desc": "Generic Android Device", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)", + "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": "Generic", - "model": "Android 6.0.1" + "vendor": "Xiaomi", + "model": "Mi A2 Lite", + "type": "mobile" } }, { - "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", + "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": { - "model": "F-04K", + "vendor": "Xiaomi", + "model": "Mi 9 SE", "type": "mobile" } }, { - "desc": "Android Phone Unidentified Vendor (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", + "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": { - "model": "SH-02M", + "vendor": "Xiaomi", + "model": "Mi A2", "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", + "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": { - "model": "F-02K", + "vendor": "Xiaomi", + "model": "MI PAD 2", "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", + "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": { - "model": "d-02K", + "vendor": "Xiaomi", + "model": "MI PAD 4 PLUS", "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", + "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": "LG", - "model": "VK700", - "type": "tablet" + "vendor": "Xiaomi", + "model": "POCO X2", + "type": "mobile" } }, { - "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", + "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": "LG", - "model": "LK430", - "type": "tablet" + "vendor": "Xiaomi", + "model": "Redmi 4A", + "type": "mobile" } }, { - "desc": "RCA Voyager III Tablet", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; RCT6973W43 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "RCA", - "model": "RCT6973W43", - "type": "tablet" + "vendor": "Xiaomi", + "model": "Redmi K30 5G", + "type": "mobile" } }, { - "desc": "RCA Voyager II Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.0; RCT6773W22B Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "RCA", - "model": "RCT6773W22B", - "type": "tablet" + "vendor": "Xiaomi", + "model": "Redmi K30 Pro", + "type": "mobile" } }, { - "desc": "Verizon Quanta Tablet", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; QMV7B Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "Verizon", - "model": "QMV7B", - "type": "tablet" + "vendor": "Xiaomi", + "model": "Redmi Note 3", + "type": "mobile" } }, { - "desc": "Verizon Ellipsis 8 Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; QTAQZ3 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "Verizon", - "model": "QTAQZ3", - "type": "tablet" + "vendor": "Xiaomi", + "model": "Redmi Note 9 Pro Max", + "type": "mobile" } }, { - "desc": "Verizon Ellipsis 8HD Tablet", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; QTASUN1 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Safari/537.36", + "desc": "PlayStation 4", + "ua": "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", "expect": { - "vendor": "Verizon", - "model": "QTASUN1", - "type": "tablet" + "vendor": "Sony", + "model": "PlayStation 4", + "type": "console" } }, { - "desc": "Dell Venue 8 Tablet", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Venue 8 3830 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "Dell", - "model": "Venue 8 3830", - "type": "tablet" + "vendor": "Sony", + "model": "Playstation 5", + "type": "console" } }, { - "desc": "Dell Venue 7 Tablet", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Venue 7 3730 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "desc": "PlayStation Vita", + "ua": "Mozilla/5.0 (PlayStation Vita 3.52) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2", "expect": { - "vendor": "Dell", - "model": "Venue 7 3730", - "type": "tablet" + "vendor": "Sony", + "model": "PlayStation Vita", + "type": "console" } }, { - "desc": "Barnes & Noble Nook HD+ Tablet", - "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; Barnes & Noble Nook HD+ Build/JZO54K; CyanogenMod-10) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "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": "Barnes & Noble", - "model": "Nook HD+", - "type": "tablet" + "vendor": "Nintendo", + "model": "Switch", + "type": "console" } }, { - "desc": "Barnes & Noble V400 Tablet", - "ua": "Mozilla/5.0 (Linux; Android 4.0.4; BNTV400 Build/IMM76L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.111 Safari/537.36", + "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": "Barnes & Noble", - "model": "V400", - "type": "tablet" + "vendor": "Nintendo", + "model": "WiiU", + "type": "console" } }, { - "desc": "NuVision TM101A540N Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.1; TM101A540N Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/50.0.2661.86 Safari/537.36", + "desc": "Nintendo Wii", + "ua": "Opera/9.10 (Nintendo Wii; U; ; 1621; en)", "expect": { - "vendor": "NuVision", - "model": "TM101A540N", - "type": "tablet" + "vendor": "Nintendo", + "model": "Wii", + "type": "console" } }, { - "desc": "ZTE-Z431", - "ua": "ZTE-Z431/1.4.0 NetFront/4.2 QTV5.1 Profile/MIDP-2.1 Configuration/CLDC-1.1", + "desc": "Nintendo 3DS", + "ua": "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7610.EU", "expect": { - "vendor": "ZTE", - "model": "Z431", - "type": "mobile" + "vendor": "Nintendo", + "model": "3DS", + "type": "console" } }, { - "desc": "ZTE", - "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; ZTE-Z740G Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "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": "ZTE", - "model": "Z740G", - "type": "mobile" + "vendor": "Nintendo", + "model": "3DS", + "type": "console" } }, { - "desc": "ZTE K Series Tablet", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; K88 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "ZTE", - "model": "K88", - "type": "tablet" + "vendor": "Samsung", + "model": "Galaxy Nexus", + "type": "mobile" } }, { - "desc": "ZTE Nubia Red Magic 3", - "ua": "Mozilla/5.0 (Linux; Android 9; NX629J Build/PKQ1.190321.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/45016 Mobile Safari/537.36 MMWEBID/4064 MicroMessenger/7.0.10.1580(0x27000A34) Process/tools NetType/WIFI Language/zh_CN ABI/arm64", + "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": "ZTE", - "model": "NX629J", + "vendor": "Samsung", + "model": "SM-C900F", "type": "mobile" } }, { - "desc": "Swizz GEN610", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; GEN610 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36", + "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": "Swiss", - "model": "GEN610", + "vendor": "Samsung", + "model": "SM-G900F", "type": "mobile" } }, { - "desc": "Swizz ZUR700", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ZUR700 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Safari/537.36", + "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": "Swiss", - "model": "ZUR700", - "type": "tablet" + "vendor": "Samsung", + "model": "SM-G920I", + "type": "mobile" } }, { - "desc": "Zeki TB782b Tablet", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-US; TB782B Build/IMM76D) AppleWebKit/534.31 (KHTML, like Gecko) UCBrowser/9.0.2.299 U3/0.8.0 Mobile Safari/534.31", + "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": "Zeki", - "model": "TB782B", - "type": "tablet" + "vendor": "Samsung", + "model": "SM-G925I", + "type": "mobile" } }, { - "desc": "Dragon Touch Tablet", - "ua": "Mozilla/5.0 (Linux; Android 4.0.4; DT9138B Build/IMM76D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Mobile Safari/537.36", + "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": "Dragon Touch", - "model": "9138B", - "type": "tablet" + "vendor": "Samsung", + "model": "SM-N920C", + "type": "mobile" } }, { - "desc": "Insignia Tablet", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; NS-P08A7100 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Safari/537.36", + "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": "Insignia", - "model": "NS-P08A7100", - "type": "tablet" + "vendor": "Samsung", + "model": "SM-N920C", + "type": "mobile" } }, { - "desc": "Voice Xtreme V75", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.1; en-us; V75 Build/JOP40D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "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": "Voice", - "model": "V75", - "type": "mobile" + "vendor": "Google", + "model": "Chromecast", + "type": "smarttv" } }, { - "desc": "LvTel V11", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; V11 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Safari/537.36", + "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": "LvTel", - "model": "V11", - "type": "mobile" + "vendor": "Google", + "model": "Pixel C", + "type": "tablet" } }, { - "desc": "Envizen Tablet V100MD", - "ua": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; V100MD Build/V100MD.20130816) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "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": "Envizen", - "model": "V100MD", + "vendor": "Google", + "model": "Pixel C", "type": "tablet" } }, { - "desc": "Rotor Tablet", - "ua": "mozilla/5.0 (linux; android 5.0.1; tu_1491 build/lrx22c) applewebkit/537.36 (khtml, like gecko) chrome/43.0.2357.93 safari/537.36", + "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": "Rotor", - "model": "1491", - "type": "tablet" + "vendor": "Google", + "model": "Pixel", + "type": "mobile" } }, { - "desc": "MachSpeed Tablets", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Trio 7.85 vQ Build/Trio_7.85_vQ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36", + "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": "MachSpeed", - "model": "Trio 7.85 vQ", - "type": "tablet" + "vendor": "Google", + "model": "Pixel XL", + "type": "mobile" } }, { - "desc": "Trinity Tablets", - "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Trinity T101 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Safari/537.36", + "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": "Trinity", - "model": "T101", - "type": "tablet" + "vendor": "Google", + "model": "Pixel XL", + "type": "mobile" } }, { - "desc": "NextBook Next7", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; Next7P12 Build/IMM76I) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "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": "NextBook", - "model": "Next7P12", - "type": "tablet" + "vendor": "Google", + "model": "Pixel 2", + "type": "mobile" } }, { - "desc": "NextBook Tablets", - "ua": "Mozilla/5.0 (Linux; Android 5.0; NXA8QC116 Build/LRX21V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "NextBook", - "model": "NXA8QC116", - "type": "tablet" + "vendor": "Google", + "model": "Pixel 2 XL", + "type": "mobile" } }, { - "desc": "Le Pan Tablets", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Le Pan TC802A Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "Le Pan", - "model": "TC802A", - "type": "tablet" + "vendor": "Google", + "model": "Pixel 2 XL", + "type": "mobile" } }, { - "desc": "Le Pan Tablets", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Le Pan TC802A Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "Le Pan", - "model": "TC802A", - "type": "tablet" + "vendor": "Google", + "model": "Pixel 3", + "type": "mobile" } }, { - "desc": "Amazon Alexa Echo Show", - "ua": "AlexaWebMediaPlayer/1.0.200641.0 (Linux;Android 5.1.1)", + "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": "Amazon", - "model": "Alexa", - "type": "tablet" + "vendor": "Google", + "model": "Pixel 3 XL", + "type": "mobile" } }, { - "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", + "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": "Amazon", - "model": "KFSAWI", - "type": "tablet" + "vendor": "Google", + "model": "Pixel 3 XL", + "type": "mobile" } }, { - "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", + "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": "Amazon", - "model": "KFSAWI", - "type": "tablet" + "vendor": "Google", + "model": "Pixel 3a", + "type": "mobile" } }, { - "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", + "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": "Amazon", - "model": "KFMAWI", - "type": "tablet" + "vendor": "Google", + "model": "Pixel 3a XL", + "type": "mobile" } }, { - "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", + "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": "Amazon", - "model": "B", - "type": "smarttv" + "vendor": "Google", + "model": "Pixel 4", + "type": "mobile" } }, { - "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", + "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": "Amazon", - "model": "T", - "type": "smarttv" + "vendor": "Google", + "model": "Pixel 4a", + "type": "mobile" } }, { - "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", + "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": "undefined", - "model": "undefined", - "type": "smarttv" + "vendor": "Google", + "model": "Pixel 4 XL", + "type": "mobile" } }, { - "desc": "Gigaset Tablet", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Gigaset QV830 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "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": "Gigaset", - "model": "QV830", + "vendor": "Google", + "model": "Pixel 5", + "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": "Android Phone Unidentified Vendor (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": { + "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": "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", + "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": { - "vendor": "Huawei", - "model": "BAH-L09", + "model": "d-02K", "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", + "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": "Huawei", - "model": "BAH2-W19", + "vendor": "LG", + "model": "VK700", "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", + "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": "Huawei", - "model": "SHT-AL09", + "vendor": "LG", + "model": "LK430", "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", + "desc": "RCA Voyager III Tablet", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; RCT6973W43 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", "expect": { - "vendor": "Huawei", - "model": "AGS2-L09", + "vendor": "RCA", + "model": "RCT6973W43", "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", + "desc": "RCA Voyager II Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.0; RCT6773W22B Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", "expect": { - "vendor": "Huawei", - "model": "AGR-W09", + "vendor": "RCA", + "model": "RCT6773W22B", "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", + "desc": "Verizon Quanta Tablet", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; QMV7B Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", "expect": { - "vendor": "Huawei", - "model": "AGS3-W09", + "vendor": "Verizon", + "model": "QMV7B", "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", + "desc": "Verizon Ellipsis 8 Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; QTAQZ3 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", "expect": { - "vendor": "Huawei", - "model": "AGR-L09", + "vendor": "Verizon", + "model": "QTAQZ3", "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", + "desc": "Verizon Ellipsis 8HD Tablet", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; QTASUN1 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Safari/537.36", "expect": { - "vendor": "Huawei", - "model": "BLA-L29", + "vendor": "Verizon", + "model": "QTASUN1", + "type": "tablet" + } + }, + { + "desc": "Dell Venue 8 Tablet", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Venue 8 3830 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "expect": { + "vendor": "Dell", + "model": "Venue 8 3830", + "type": "tablet" + } + }, + { + "desc": "Dell Venue 7 Tablet", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Venue 7 3730 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "expect": { + "vendor": "Dell", + "model": "Venue 7 3730", + "type": "tablet" + } + }, + { + "desc": "Barnes & Noble Nook HD+ Tablet", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; Barnes & Noble Nook HD+ Build/JZO54K; CyanogenMod-10) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Barnes & Noble", + "model": "Nook HD+", + "type": "tablet" + } + }, + { + "desc": "Barnes & Noble V400 Tablet", + "ua": "Mozilla/5.0 (Linux; Android 4.0.4; BNTV400 Build/IMM76L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.111 Safari/537.36", + "expect": { + "vendor": "Barnes & Noble", + "model": "V400", + "type": "tablet" + } + }, + { + "desc": "NuVision TM101A540N Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1; TM101A540N Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/50.0.2661.86 Safari/537.36", + "expect": { + "vendor": "NuVision", + "model": "TM101A540N", + "type": "tablet" + } + }, + { + "desc": "ZTE-Z431", + "ua": "ZTE-Z431/1.4.0 NetFront/4.2 QTV5.1 Profile/MIDP-2.1 Configuration/CLDC-1.1", + "expect": { + "vendor": "ZTE", + "model": "Z431", "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", + "desc": "ZTE", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; ZTE-Z740G Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "expect": { - "vendor": "Huawei", - "model": "TAH-AN00", + "vendor": "ZTE", + "model": "Z740G", "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", + "desc": "ZTE K Series Tablet", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; K88 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", "expect": { - "vendor": "Huawei", - "model": "TET-AN00", + "vendor": "ZTE", + "model": "K88", + "type": "tablet" + } + }, + { + "desc": "ZTE Nubia Red Magic 3", + "ua": "Mozilla/5.0 (Linux; Android 9; NX629J Build/PKQ1.190321.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/45016 Mobile Safari/537.36 MMWEBID/4064 MicroMessenger/7.0.10.1580(0x27000A34) Process/tools NetType/WIFI Language/zh_CN ABI/arm64", + "expect": { + "vendor": "ZTE", + "model": "NX629J", "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": "ZTE Blade A5", + "ua": "Mozilla/5.0 (Linux; Android 9; ZTE Blade A5 2019) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "ZTE", + "model": "Blade A5 2019", + "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": "ZTE BLADE V0730", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ZTE BLADE V0730) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "ZTE", + "model": "BLADE V0730", + "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": "ZTE B2017G", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE B2017G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "ZTE", + "model": "B2017G", + "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", + "desc": "Swizz GEN610", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; GEN610 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36", "expect": { - "vendor": "Huawei", - "model": "ANE-LX1", + "vendor": "Swiss", + "model": "GEN610", "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 Enjoy10e", - "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", - "expect": { - "vendor": "Huawei", - "model": "MED-AL00", - "type": "mobile" - } - }, - { - "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": "AT&T Radiant Core U304AA", - "ua": "Dalvik/2.1.0 (Linux; U; Android 9; U304AA Build/P00610)", - "expect": { - "vendor": "AT&T", - "model": "U304AA", - "type": "mobile" - } - }, - { - "desc": "Vodafone Smart Tab 4G", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; Vodafone Smart Tab 4G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", - "expect": { - "vendor": "Vodafone", - "model": "Smart Tab 4G", - "type": "tablet" - } - }, - { - "desc": "Vodafone Smart ultra 6", - "ua": "Mozilla/5.0 (Linux; Android 5.0.2; Vodafone Smart ultra 6 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "Vodafone", - "model": "Smart ultra 6", - "type": "tablet" - } - }, - { - "desc": "4ife 4K Smart TV Box", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; 4ife 4K Smart TV Box Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 Vinebre", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "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": { - "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 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 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": "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" + "desc": "Swizz ZUR700", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ZUR700 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Safari/537.36", + "expect": { + "vendor": "Swiss", + "model": "ZUR700", + "type": "tablet" + } + }, + { + "desc": "Zeki TB782b Tablet", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-US; TB782B Build/IMM76D) AppleWebKit/534.31 (KHTML, like Gecko) UCBrowser/9.0.2.299 U3/0.8.0 Mobile Safari/534.31", + "expect": { + "vendor": "Zeki", + "model": "TB782B", + "type": "tablet" + } + }, + { + "desc": "Dragon Touch Tablet", + "ua": "Mozilla/5.0 (Linux; Android 4.0.4; DT9138B Build/IMM76D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Mobile Safari/537.36", + "expect": { + "vendor": "Dragon Touch", + "model": "9138B", + "type": "tablet" + } + }, + { + "desc": "Insignia Tablet", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; NS-P08A7100 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Safari/537.36", + "expect": { + "vendor": "Insignia", + "model": "NS-P08A7100", + "type": "tablet" + } + }, + { + "desc": "Voice Xtreme V75", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.1; en-us; V75 Build/JOP40D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Voice", + "model": "V75", + "type": "mobile" + } + }, + { + "desc": "LvTel V11", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; V11 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Safari/537.36", + "expect": { + "vendor": "LvTel", + "model": "V11", + "type": "mobile" + } + }, + { + "desc": "Envizen Tablet V100MD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; V100MD Build/V100MD.20130816) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "Envizen", + "model": "V100MD", + "type": "tablet" + } + }, + { + "desc": "Rotor Tablet", + "ua": "mozilla/5.0 (linux; android 5.0.1; tu_1491 build/lrx22c) applewebkit/537.36 (khtml, like gecko) chrome/43.0.2357.93 safari/537.36", + "expect": { + "vendor": "Rotor", + "model": "1491", + "type": "tablet" + } + }, + { + "desc": "MachSpeed Tablets", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Trio 7.85 vQ Build/Trio_7.85_vQ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36", + "expect": { + "vendor": "MachSpeed", + "model": "Trio 7.85 vQ", + "type": "tablet" + } + }, + { + "desc": "Trinity Tablets", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Trinity T101 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Safari/537.36", + "expect": { + "vendor": "Trinity", + "model": "T101", + "type": "tablet" + } + }, + { + "desc": "NextBook Next7", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; Next7P12 Build/IMM76I) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "NextBook", + "model": "Next7P12", + "type": "tablet" + } + }, + { + "desc": "NextBook Tablets", + "ua": "Mozilla/5.0 (Linux; Android 5.0; NXA8QC116 Build/LRX21V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "expect": { + "vendor": "NextBook", + "model": "NXA8QC116", + "type": "tablet" + } + }, + { + "desc": "Le Pan Tablets", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Le Pan TC802A Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "expect": { + "vendor": "Le Pan", + "model": "TC802A", + "type": "tablet" + } + }, + { + "desc": "Le Pan Tablets", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Le Pan TC802A Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "expect": { + "vendor": "Le Pan", + "model": "TC802A", + "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": "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": "Gigaset Tablet", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Gigaset QV830 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", + "expect": { + "vendor": "Gigaset", + "model": "QV830", + "type": "tablet" + } + }, + { + "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": "AT&T Radiant Core U304AA", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; U304AA Build/P00610)", + "expect": { + "vendor": "AT&T", + "model": "U304AA", + "type": "mobile" + } + }, + { + "desc": "Vodafone Smart Tab 4G", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; Vodafone Smart Tab 4G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", + "expect": { + "vendor": "Vodafone", + "model": "Smart Tab 4G", + "type": "tablet" + } + }, + { + "desc": "Vodafone Smart ultra 6", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; Vodafone Smart ultra 6 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "Vodafone", + "model": "Smart ultra 6", + "type": "tablet" + } + }, + { + "desc": "4ife 4K Smart TV Box", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; 4ife 4K Smart TV Box Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 Vinebre", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "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": { + "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 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 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": "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" + } } - } ] From e5e13adc812b2e485ecf5efbedce7077f7d312cd Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 24 Apr 2021 21:15:16 +0700 Subject: [PATCH 016/104] Improve CPU detection for ARM64 --- src/ua-parser.js | 4 ++-- test/cpu-test.json | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 5a5c28fe1..eac88384d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -340,7 +340,7 @@ /((?:i[346]|x)86)[;\)]/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ - /\b(aarch64|armv?8e?l?)\b/i // ARM64 + /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 ], [[ARCHITECTURE, 'arm64']], [ /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF @@ -356,7 +356,7 @@ /(sun4\w)[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?:64|(?=v(?:[1-7]|[5-7]1)l?|;|eabi))|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i + /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?: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/cpu-test.json b/test/cpu-test.json index efa1c5b93..cf314f9c8 100644 --- a/test/cpu-test.json +++ b/test/cpu-test.json @@ -111,6 +111,22 @@ "architecture" : "arm64" } }, + { + "desc" : "ARM64", + "ua" : "Mozilla/5.0 (Windows NT 10.0; ARM64; RM-1096) AppleWebKit/537.36 (KHTML like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393", + "expect" : + { + "architecture" : "arm64" + } + }, + { + "desc" : "ARM64", + "ua" : "Mozilla/5.0 (Linux; arm_64; Android 9; HRY-LX1T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 YaBrowser/19.12.1.121.00 Mobile Safari/537.36", + "expect" : + { + "architecture" : "arm64" + } + }, { "desc" : "Pocket PC", "ua" : "Opera/9.7 (Windows Mobile; PPC; Opera Mobi/35166; U; en) Presto/2.2.1", From 1e7b6d2e8bccdc5719243c81123b7709bca0d064 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 24 Apr 2021 21:50:18 +0700 Subject: [PATCH 017/104] Improve device detection: LG Android TV --- src/ua-parser.js | 4 ++-- test/device-test.json | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index eac88384d..15677d3a4 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -427,7 +427,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)\w+)/i, + /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ @@ -601,7 +601,7 @@ ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ - /(?:nux; netcast.+smarttv|lg netcast\.tv-201\d)/i // LG SmartTV + /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ diff --git a/test/device-test.json b/test/device-test.json index c8bd7c446..885db1417 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -826,6 +826,15 @@ "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": "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", From 03c915277aac43e68379a4500819bd7a8d5bb28e Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 24 Apr 2021 23:04:16 +0700 Subject: [PATCH 018/104] Add new OS: Android-x86, Deepin, elementary OS, GhostBSD, Linspire, Manjaro, Sabayon User-Agent source: whatismybrowser.com --- readme.md | 14 +++++----- src/ua-parser.js | 10 ++++--- test/os-test.json | 68 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/readme.md b/readme.md index bcd4d3b64..456d1105c 100644 --- a/readme.md +++ b/readme.md @@ -86,13 +86,13 @@ NetSurf, Presto, Tasman, Trident, w3m, WebKit ```sh # Possible 'os.name' -AIX, Amiga OS, Android, Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, -Contiki, Fedora, Firefox OS, FreeBSD, Debian, DragonFly, Fuchsia, Gentoo, GNU, -Haiku, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linux, Mac OS, Maemo, Mageia, -Mandriva, MeeGo, Minix, Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, -Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, -RISC OS, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, -Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... +AIX, Amiga OS, Android[-x86], Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, +Contiki, Fedora, Firefox OS, FreeBSD, Debian, Deepin, DragonFly, elementary OS, +Fuchsia, Gentoo, GhostBSD, GNU, Haiku, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linspire, +Linux, Mac OS, Maemo, Mageia, Mandriva, Manjaro, MeeGo, Minix, Mint, Morph OS, NetBSD, +Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, +Raspbian, RedHat, RIM Tablet OS, RISC OS, Sabayon, Sailfish, Series40, Slackware, Solaris, +SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 15677d3a4..ea9e50613 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -690,7 +690,9 @@ /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ - // Mobile OSes // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS + // Mobile OSes + /droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86 + ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS @@ -720,11 +722,11 @@ /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm /(mint)[\/\(\) ]?(\w*)/i, // Mint /(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)(?: 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 + /([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 /(gnu) ?([\w\.]*)/i, // GNU - /\b([-frentopc]{0,4}bsd|dragonfly) ?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly /(haiku) (\w+)/i // Haiku ], [NAME, VERSION], [ /(sunos) ?([\w\.\d]*)/i // Solaris diff --git a/test/os-test.json b/test/os-test.json index d614487af..a0eb41269 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -604,11 +604,11 @@ }, { "desc" : "Slackware", - "ua" : "", + "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" : "", - "version" : "" + "name" : "Slackware", + "version" : "13.37" } }, { @@ -1017,12 +1017,12 @@ } }, { - "desc" : "GNU", - "ua" : "", + "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" : "", - "version" : "" + "name" : "Deepin", + "version" : "15.5" } }, { @@ -1060,5 +1060,59 @@ "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" + } } ] From 39e8d4af0314117c4733ad9a9397ad32a0e42732 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 15 Jun 2021 12:49:19 +0700 Subject: [PATCH 019/104] Fix #500 Sharp devices misjudged as Huawei devices --- src/ua-parser.js | 8 ++++++-- test/device-test.json | 30 +++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index ea9e50613..2a6236707 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -385,10 +385,10 @@ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ // Huawei - /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b/i + /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, - /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b/i + /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi @@ -499,6 +499,10 @@ /\bmz-([-\w]{2,})/i ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ + // Sharp + /\b(sh-?[altvz]?\d\d[a-ekm]?)/i + ], [MODEL, [VENDOR, 'Sharp'], [TYPE, MOBILE]], [ + // MIXED /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron diff --git a/test/device-test.json b/test/device-test.json index 885db1417..794500ced 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1539,6 +1539,33 @@ "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 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": "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", @@ -2197,9 +2224,10 @@ } }, { - "desc": "Android Phone Unidentified Vendor (docomo SH-02M)", + "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" } From 299283c436ad29f67242e928f8185ed53c194876 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 22 Jul 2021 20:30:54 +0700 Subject: [PATCH 020/104] Fix #506 - add test for Huawei ART-L29 --- test/device-test.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/device-test.json b/test/device-test.json index 794500ced..ae9392fe8 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -583,6 +583,15 @@ "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", From 825edbbf91276e5e0843be15b592da090fbc43d4 Mon Sep 17 00:00:00 2001 From: liujunlve Date: Fri, 30 Jul 2021 15:32:56 +0800 Subject: [PATCH 021/104] Fix #509 add support for Internet Explorer 8 --- src/ua-parser.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index 2a6236707..3581c9a33 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -114,6 +114,7 @@ // try matching uastring with regexes while (j < regex.length && !matches) { + if (!regex[j]) { break; } matches = regex[j++].exec(ua); if (!!matches) { From 47c310e20380e15fa0575b45ba4c1a8d01bf00d2 Mon Sep 17 00:00:00 2001 From: Ziding Zhang Date: Thu, 16 Sep 2021 16:11:51 +0100 Subject: [PATCH 022/104] Create SECURITY.md A simple instruction for security researchers. --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..de525bbf5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security issues to `f@faisalman.com` From 336ce2b9502923fb931615598dfb0baefed04f5d Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 17 Sep 2021 23:24:42 +0700 Subject: [PATCH 023/104] Improve regex efficiency when trimming long ua string https://blog.stevenlevithan.com/archives/faster-trim-javascript --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 2a6236707..7d8beb671 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -91,7 +91,7 @@ }, trim = function (str, len) { if (typeof(str) === STR_TYPE) { - str = str.replace(/^\s+|\s+$/g, EMPTY); + str = str.replace(/^\s\s*/, EMPTY).replace(/\s\s*$/, EMPTY); return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); } }; From 15aa73de406695607ebe3c0cc9921baf02d7c437 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 09:15:49 -0700 Subject: [PATCH 024/104] Add Huawei models --- src/ua-parser.js | 2 +- test/device-test.json | 117 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7d8beb671..5f8a265f5 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -388,7 +388,7 @@ /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, - /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i + /\b(nexus 6p|lya-l0c|yale?\-a?l\d{2}[ad]?|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi diff --git a/test/device-test.json b/test/device-test.json index ae9392fe8..60a7b2346 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -268,6 +268,24 @@ "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", @@ -421,6 +439,42 @@ "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 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", @@ -502,6 +556,69 @@ "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)", From b542df155ac339cd2a7e67e6634e0f1068208ad3 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 11:01:28 -0700 Subject: [PATCH 025/104] Sony Xperia 1ii --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7d8beb671..1a88d279f 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -448,7 +448,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+ ([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i + /droid.+ ([c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ /sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i diff --git a/test/device-test.json b/test/device-test.json index ae9392fe8..1a26d9a1b 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1647,6 +1647,15 @@ "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", From 62cc99d7cf56254bf0b131d00136020ba4b4d3f9 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 12:23:49 -0700 Subject: [PATCH 026/104] Samsung Galaxy S20 5G --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7d8beb671..2f6711270 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -371,7 +371,7 @@ // Samsung /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ - /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, + /\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i, /samsung[- ]([-\w]+)/i, /sec-(sgh\w+)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ diff --git a/test/device-test.json b/test/device-test.json index ae9392fe8..4311a78f8 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1404,6 +1404,15 @@ "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", From ffc03acd64069d287e02c675bb963dfa21103117 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 12:31:16 -0700 Subject: [PATCH 027/104] Add different oculus browser --- test/browser-test.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/browser-test.json b/test/browser-test.json index 2f4c2e0fb..afd576e44 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -789,7 +789,7 @@ } }, { - "desc" : "Oculus Browser", + "desc" : "Oculus Browser", "ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G920I Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/3.4.9 SamsungBrowser/4.0 Chrome/57.0.2987.146 Mobile VR Safari/537.36", "expect" : { @@ -798,6 +798,16 @@ "major" : "3" } }, + { + "desc" : "Oculus Browser", + "ua" : "Mozilla/5.0 (Linux; Android 7.1.1; Pacific Build/N9F27L) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/4.0.0.17 SamsungBrowser/4.0 Chrome/61.0.3163.109 Mobile VR Safari/537.36", + "expect" : + { + "name" : "Oculus Browser", + "version" : "3.4.9", + "major" : "3" + } + }, { "desc" : "OmniWeb", "ua" : "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US) AppleWebKit/85 (KHTML, like Gecko) OmniWeb/v558.48", From f57bd9523d81f9e20d5f7aca8a918d38646c8a89 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 15:31:02 -0700 Subject: [PATCH 028/104] Oculus devices --- src/ua-parser.js | 9 +++++++-- test/browser-test.json | 24 ++++++++++++++++++++++-- test/device-test.json | 18 ++++++++++++++++++ test/test.js | 4 ++-- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7d8beb671..e6108cf6d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -56,7 +56,8 @@ SAMSUNG = 'Samsung', SONY = 'Sony', XIAOMI = 'Xiaomi', - ZEBRA = 'Zebra'; + ZEBRA = 'Zebra', + FACEBOOK = 'Facebook'; /////////// // Helper @@ -278,7 +279,7 @@ // WebView /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android - ], [[NAME, 'Facebook'], VERSION], [ + ], [[NAME, FACEBOOK], VERSION], [ /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram @@ -631,6 +632,10 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ + /quest 2/i + ], [[MODEL, 'Quest 2'], [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ + /quest/i + ], [[MODEL, 'Quest'], [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ /////////////////// // EMBEDDED diff --git a/test/browser-test.json b/test/browser-test.json index afd576e44..ca3777711 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -804,8 +804,28 @@ "expect" : { "name" : "Oculus Browser", - "version" : "3.4.9", - "major" : "3" + "version" : "4.0.0.17", + "major" : "4" + } + }, + { + "desc" : "Oculus Browser", + "ua" : "Mozilla/5.0 (Linux; Android 9; SM-N960F) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/6.2.11.181027543 SamsungBrowser/4.0 Chrome/74.0.3729.182 Mobile VR Safari/537.36", + "expect" : + { + "name" : "Oculus Browser", + "version" : "6.2.11.181027543", + "major" : "6" + } + }, + { + "desc" : "Oculus Browser (NOTE PARIS FROM https://developer.oculus.com/documentation/web/browser-specs/)", + "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" : + { + "name" : "Oculus Browser", + "version" : "15.0.0.0.22.280317669", + "major" : "15" } }, { diff --git a/test/device-test.json b/test/device-test.json index ae9392fe8..3a60d8ed5 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1053,6 +1053,24 @@ "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": "wearable" + } + }, + { + "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": "wearable" + } + }, { "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", diff --git a/test/test.js b/test/test.js index ad54ef43e..58c9b3d32 100644 --- a/test/test.js +++ b/test/test.js @@ -39,7 +39,8 @@ var methods = [ 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'; @@ -62,7 +63,6 @@ for (var i in methods) { 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); From ee743946e8df499f7b77a521b13ed3de9a2d2149 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 15:40:04 -0700 Subject: [PATCH 029/104] cleanup --- test/browser-test.json | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/test/browser-test.json b/test/browser-test.json index ca3777711..393aba75b 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -789,7 +789,7 @@ } }, { - "desc" : "Oculus Browser", + "desc" : "Oculus Browser", "ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G920I Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/3.4.9 SamsungBrowser/4.0 Chrome/57.0.2987.146 Mobile VR Safari/537.36", "expect" : { @@ -800,26 +800,6 @@ }, { "desc" : "Oculus Browser", - "ua" : "Mozilla/5.0 (Linux; Android 7.1.1; Pacific Build/N9F27L) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/4.0.0.17 SamsungBrowser/4.0 Chrome/61.0.3163.109 Mobile VR Safari/537.36", - "expect" : - { - "name" : "Oculus Browser", - "version" : "4.0.0.17", - "major" : "4" - } - }, - { - "desc" : "Oculus Browser", - "ua" : "Mozilla/5.0 (Linux; Android 9; SM-N960F) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/6.2.11.181027543 SamsungBrowser/4.0 Chrome/74.0.3729.182 Mobile VR Safari/537.36", - "expect" : - { - "name" : "Oculus Browser", - "version" : "6.2.11.181027543", - "major" : "6" - } - }, - { - "desc" : "Oculus Browser (NOTE PARIS FROM https://developer.oculus.com/documentation/web/browser-specs/)", "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" : { From 79535f5d612128e062ccca921a1c38cfedb2c31f Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 21 Sep 2021 15:40:47 -0700 Subject: [PATCH 030/104] cleanup --- test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index 58c9b3d32..ad54ef43e 100644 --- a/test/test.js +++ b/test/test.js @@ -39,8 +39,7 @@ var methods = [ 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'; @@ -63,6 +62,7 @@ for (var i in methods) { 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); From 343d584f8f74a15fcaa621e1ad76b425db8119c8 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Mon, 4 Oct 2021 09:06:00 -0700 Subject: [PATCH 031/104] change to single line regex --- src/ua-parser.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index e6108cf6d..0453e5081 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -632,10 +632,8 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ - /quest 2/i - ], [[MODEL, 'Quest 2'], [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ - /quest/i - ], [[MODEL, 'Quest'], [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ + /(quest( 2)?)/i // Oculus Quest + ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ /////////////////// // EMBEDDED From 191fed912779a0fd1db46319c956353feb8e4ff2 Mon Sep 17 00:00:00 2001 From: Ryohei Shima Date: Fri, 22 Oct 2021 12:23:36 +0900 Subject: [PATCH 032/104] Enable to detect OPPO Reno5 A correctly. --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index ce1342418..8df1885a3 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -404,7 +404,7 @@ // OPPO /; (\w+) bui.+ oppo/i, - /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007)\b/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]], [ // Vivo diff --git a/test/device-test.json b/test/device-test.json index d0a5f897c..da6a820ee 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1242,6 +1242,15 @@ "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", From 139fbc321a36ff663aac471a61d109728ac17f0b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 22 Oct 2021 23:14:37 +0700 Subject: [PATCH 033/104] Securing the 0.7.x version (issue #536) --- bower.json | 2 +- package.js | 2 +- package.json | 2 +- SECURITY.md => security.md | 0 src/ua-parser.js | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename SECURITY.md => security.md (100%) diff --git a/bower.json b/bower.json index 6539b1b8e..d3adc9361 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.28", + "version": "0.7.30", "authors": [ "Faisal Salman " ], diff --git a/package.js b/package.js index 8ff9001ef..c463dd56d 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.7.28', + version: '0.7.30', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index 83864f436..ccb22f398 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.7.28", + "version": "0.7.30", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/SECURITY.md b/security.md similarity index 100% rename from SECURITY.md rename to security.md diff --git a/src/ua-parser.js b/src/ua-parser.js index ce1342418..967d940b3 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.7.28', + var LIBVERSION = '0.7.30', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 051aa5d284157ea4147f8ee23282f7c4117d71c3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 22 Oct 2021 23:23:12 +0700 Subject: [PATCH 034/104] Securing the 0.8.x version (issue #536) --- bower.json | 2 +- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bower.json b/bower.json index d3adc9361..c6b738bd4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.30", + "version": "0.8.1", "authors": [ "Faisal Salman " ], diff --git a/package.js b/package.js index c463dd56d..180cb62b8 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.7.30', + version: '0.8.1', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index ccb22f398..d03ca751c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.7.30", + "version": "0.8.1", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index 967d940b3..79cb0e660 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.7.30', + var LIBVERSION = '0.8.1', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 29d5e43342170414c4b7e88e76d87e4adb43c389 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 22 Oct 2021 23:25:44 +0700 Subject: [PATCH 035/104] Securing the 1.x version (issue #536) --- bower.json | 2 +- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bower.json b/bower.json index c6b738bd4..277a8aedd 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.8.1", + "version": "1.0.1", "authors": [ "Faisal Salman " ], diff --git a/package.js b/package.js index 180cb62b8..40c3678a2 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.8.1', + version: '1.0.1', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index d03ca751c..9faf964fb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.8.1", + "version": "1.0.1", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index 79cb0e660..1e88c0a27 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.8.1', + var LIBVERSION = '1.0.1', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From fbd2c6853c8e6c69646295ba40dc4d6a3a0ee951 Mon Sep 17 00:00:00 2001 From: chenhui9279 Date: Mon, 25 Oct 2021 16:44:54 +0800 Subject: [PATCH 036/104] feat: require the use of `===` and `!==` --- src/ua-parser.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 1e88c0a27..ae6066d37 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -123,7 +123,7 @@ q = props[p]; // check if given property is actually array if (typeof q === OBJ_TYPE && q.length > 0) { - if (q.length == 2) { + if (q.length === 2) { if (typeof q[1] == FUNC_TYPE) { // assign modified match this[q[0]] = q[1].call(this, match); @@ -131,7 +131,7 @@ // assign given value, ignore regex match this[q[0]] = q[1]; } - } else if (q.length == 3) { + } else if (q.length === 3) { // check whether function or regex if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { // call function (usually string mapper) @@ -140,7 +140,7 @@ // sanitize match using given regex this[q[0]] = match ? match.replace(q[1], q[2]) : undefined; } - } else if (q.length == 4) { + } else if (q.length === 4) { this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined; } } else { From 10c978eca5a44873213b6c077fbf0f3580e4c2b8 Mon Sep 17 00:00:00 2001 From: sunny-mwx <30586210+sunny-mwx@users.noreply.github.com> Date: Tue, 26 Oct 2021 17:35:34 +0800 Subject: [PATCH 037/104] Update ua-parser.js --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 1e88c0a27..b1105134d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -76,7 +76,7 @@ }, enumerize = function (arr) { var enums = {}; - for (var i in arr) { + for (var i=0; i Date: Tue, 26 Oct 2021 11:36:19 +0200 Subject: [PATCH 038/104] =?UTF-8?q?=E2=9C=A8=20Use=20AST=20to=20verify=20w?= =?UTF-8?q?hether=20regexes=20are=20safe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 ++ test/test.js | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 9faf964fb..8e9b59c73 100644 --- a/package.json +++ b/package.json @@ -160,6 +160,8 @@ ] }, "devDependencies": { + "@babel/parser": "7.15.8", + "@babel/traverse": "7.15.4", "jshint": "~2.12.0", "mocha": "~8.2.0", "requirejs": "^2.3.2", diff --git a/test/test.js b/test/test.js index ad54ef43e..71d1f46e1 100644 --- a/test/test.js +++ b/test/test.js @@ -2,6 +2,8 @@ var fs = require('fs'); var safe = require('safe-regex'); var assert = require('assert'); var requirejs = require('requirejs'); +var parseJS = require('@babel/parser').parse; +var traverse = require('@babel/traverse').default; var UAParser = require('./../src/ua-parser'); var browsers = require('./browser-test.json'); var cpus = require('./cpu-test.json'); @@ -137,12 +139,19 @@ describe('Testing regexes', function () { var regexes; - // todo: use AST-based instead of grep - before('Read main js file', function (done) { - fs.readFile('src/ua-parser.js', 'utf8', function (err, data) { - regexes = data.match(/(\/.+\/[ig]+)(?=[,\s\n])/g); - done(); + before('Read main js file', function () { + var code = fs.readFileSync('src/ua-parser.js', 'utf8').toString(); + var ast = parseJS(code, { sourceType: "script" }); + regexes = []; + traverse(ast, { + RegExpLiteral: (path) => { + regexes.push(path.node.pattern); + } }); + + if (regexes.length === 0) { + throw new Error("Regexes cannot be empty!"); + } }); describe('Begin testing', function () { @@ -156,4 +165,4 @@ describe('Testing regexes', function () { }); }); }); -}) \ No newline at end of file +}); From 97f3368ef053d63e24a04421dec1a55e73dbf2af Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 27 Oct 2021 14:00:19 +0700 Subject: [PATCH 039/104] Bump version 0.7.31 --- bower.json | 2 +- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 4 ++-- src/ua-parser.js | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bower.json b/bower.json index 277a8aedd..618bac584 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "1.0.1", + "version": "0.7.31", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 14b5e8c5d..08dc9d5e3 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.28 +/* UAParser.js v0.7.31 Copyright © 2012-2021 Faisal Salman MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.28",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",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i in arr){enums[arr[i].toUpperCase()]=arr[i]}return enums},has=function(str1,str2){return typeof str1===STR_TYPE?lowerize(str2).indexOf(lowerize(str1))!==-1:false},lowerize=function(str){return str.toLowerCase()},majorize=function(version){return typeof version===STR_TYPE?version.replace(/[^\d\.]/g,EMPTY).split(".")[0]:undefined},trim=function(str,len){if(typeof str===STR_TYPE){str=str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,EMPTY);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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="0.7.31",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",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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.pack.js b/dist/ua-parser.pack.js index 34c92c5fa..da1bb2678 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.28 +/* UAParser.js v0.7.31 Copyright © 2012-2021 Faisal Salman MIT License */ -!function(r,d){"use strict";function i(i){var e,o={};for(e in i)o[i[e].toUpperCase()]=i[e];return o}function t(i,e){return typeof i==w&&-1!==B(e).indexOf(B(i))}function n(i,e){if(typeof i==w)return i=i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),typeof e==b?i:i.substring(0,255)}function s(i,e){for(var o,a,r,t,n,s=0;s (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ @@ -156,7 +156,7 @@ ], "regs": [ "^((?:\\$|(\\s*\\*\\s*@)|(\\s*(?:var|,)?\\s+))(?:LIBVERSION|version)[\\s\\:='\"]+)([0-9]+(?:\\.[0-9]+){2,2})", - "^(\\s?\\*.*v)([0-9]+(?:\\.[0-9]+){2,2})" + "^(\\/?\\s?\\*.*v)([0-9]+(?:\\.[0-9]+){2,2})" ] }, "devDependencies": { diff --git a/src/ua-parser.js b/src/ua-parser.js index abedd15ff..196bb85cc 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v0.7.28 +/* UAParser.js v0.7.31 Copyright © 2012-2021 Faisal Salman MIT License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '1.0.1', + var LIBVERSION = '0.7.31', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 23ad60ea689e2d25ec9e403bf128d3b974c341cb Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 18 Dec 2021 01:31:40 +0700 Subject: [PATCH 040/104] Fix #559: Sony Xperia 1 III misidentified as Acer tablet --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 196bb85cc..56fefcccd 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -449,7 +449,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ // Sony - /droid.+ ([c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i + /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ /sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i diff --git a/test/device-test.json b/test/device-test.json index da6a820ee..1b98a7680 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1602,6 +1602,15 @@ "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 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", From 7ddb2575bd1c021a3e5c708ece6f6205103843d3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 18 Dec 2021 15:13:19 +0700 Subject: [PATCH 041/104] Fix #533: Detect Sony BRAVIA as SmartTV --- src/ua-parser.js | 4 +++- test/device-test.json | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 56fefcccd..44599fede 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -488,7 +488,7 @@ // ZTE /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, - /(alcatel|geeksphone|nexian|panasonic|sony)[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ // Acer @@ -616,6 +616,8 @@ ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i // Sharp ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ + /(bravia[\w- ]+) bui/i // Sony + ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ diff --git a/test/device-test.json b/test/device-test.json index 1b98a7680..988e18613 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1746,6 +1746,15 @@ "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" : "Tesla", "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", From f761a89ab2c2e53055d83a1d07acf677cb960d5f Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 13 Jan 2022 00:35:56 +0700 Subject: [PATCH 042/104] Fix #562 - Xiaomi Mi CC9 --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 44599fede..05e1e1f49 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -397,7 +397,7 @@ /\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 - /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ diff --git a/test/device-test.json b/test/device-test.json index 988e18613..d87e616bc 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1901,6 +1901,15 @@ "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 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;]", From a29213960c7a1b80fded50d82936002fd0ccb939 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 28 Jan 2022 22:16:51 +0700 Subject: [PATCH 043/104] Fix #561 - Increase UA_MAX_LENGTH to 275 --- src/ua-parser.js | 2 +- test/browser-test.json | 10 ++++++++++ test/test.js | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 05e1e1f49..881a850b5 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -37,7 +37,7 @@ SMARTTV = 'smarttv', WEARABLE = 'wearable', EMBEDDED = 'embedded', - UA_MAX_LENGTH = 255; + UA_MAX_LENGTH = 275; var AMAZON = 'Amazon', APPLE = 'Apple', diff --git a/test/browser-test.json b/test/browser-test.json index 393aba75b..bce9f2280 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1463,5 +1463,15 @@ "version" : "4.2.7", "major" : "4" } + }, + { + "desc" : "IE11 on Windows 7 (ua length >255)", + "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64; APCPMS=^N201205020840572565478A37A6F9C41BD33F_9975^; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MARKANYEPS#25118; Zoom 3.6.0; rv:11.0) like Gecko", + "expect" : + { + "name" : "IE", + "version" : "11.0", + "major" : "11" + } } ] diff --git a/test/test.js b/test/test.js index 71d1f46e1..fc7ebc537 100644 --- a/test/test.js +++ b/test/test.js @@ -109,7 +109,7 @@ describe('Extending Regex', function () { }); describe('User-agent length', function () { - var UA_MAX_LENGTH = 255; + var UA_MAX_LENGTH = 275; // Real data from https://stackoverflow.com/questions/654921/how-big-can-a-user-agent-string-get#answer-6595973 var uaString = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; (R1 1.6); SLCC1; .NET CLR 2.0.50727; InfoPath.2; OfficeLiveConnector.1.3; OfficeLivePatch.0.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618; 66760635803; runtime 11.00294; 876906799603; 97880703; 669602703; 9778063903; 877905603; 89670803; 96690803; 8878091903; 7879040603; 999608065603; 799808803; 6666059903; 669602102803; 888809342903; 696901603; 788907703; 887806555703; 97690214703; 66760903; 968909903; 796802422703; 8868026703; 889803611803; 898706903; 977806408603; 976900799903; 9897086903; 88780803; 798802301603; 9966008603; 66760703; 97890452603; 9789064803; 96990759803; 99960107703; 8868087903; 889801155603; 78890703; 8898070603; 89970603; 89970539603; 89970488703; 8789007603; 87890903; 877904603; 9887077703; 798804903; 97890264603; 967901703; 87890703; 97690420803; 79980706603; 9867086703; 996602846703; 87690803; 6989010903; 977809603; 666601903; 876905337803; 89670603; 89970200903; 786903603; 696901911703; 788905703; 896709803; 96890703; 998601903; 88980703; 666604769703; 978806603; 7988020803; 996608803; 788903297903; 98770043603; 899708803; 66960371603; 9669088903; 69990703; 99660519903; 97780603; 888801803; 9867071703; 79780803; 9779087603; 899708603; 66960456803; 898706824603; 78890299903; 99660703; 9768079803; 977901591603; 89670605603; 787903608603; 998607934903; 799808573903; 878909603; 979808146703; 9996088603; 797803154903; 69790603; 99660565603; 7869028603; 896707703; 97980965603; 976907191703; 88680703; 888809803; 69690903; 889805523703; 899707703; 997605035603; 89970029803; 9699094903; 877906803; 899707002703; 786905857603; 69890803; 97980051903; 997603978803; 9897097903; 66960141703; 7968077603; 977804603; 88980603; 989700803; 999607887803; 78690772803; 96990560903; 98970961603; 9996032903; 9699098703; 69890655603; 978903803; 698905066803; 977806903; 9789061703; 967903747703; 976900550903; 88980934703; 8878075803; 8977028703; 97980903; 9769006603; 786900803; 98770682703; 78790903; 878906967903; 87690399603; 99860976703; 796805703; 87990603; 968906803; 967904724603; 999606603; 988705903; 989702842603; 96790603; 99760703; 88980166703; 9799038903; 98670903; 697905248603; 7968043603; 66860703; 66860127903; 9779048903; 89670123903; 78890397703; 97890603; 87890803; 8789030603; 69990603; 88880763703; 9769000603; 96990203903; 978900405903; 7869022803; 699905422903; 97890703; 87990903; 878908703; 7998093903; 898702507603; 97780637603; 966907903; 896702603; 9769004803; 7869007903; 99660158803; 7899099603; 8977055803; 99660603; 7889080903; 66660981603; 997604603; 6969089803; 899701903; 9769072703; 666603903; 99860803; 997608803; 69790903; 88680756703; 979805677903; 9986047703; 89970803; 66660603; 96690903; 8997051603; 789901209803; 8977098903; 968900326803; 87790703; 98770024803; 697901794603; 69990803; 887805925803; 968908903; 97880603; 897709148703; 877909476903; 66760197703; 977908603; 698902703; 988706504803; 977802026603; 88680964703; 8878068703; 987705107903; 978902878703; 8898069803; 9768031703; 79680803; 79980803; 669609328703; 89870238703; 99960593903; 969904218703; 78890603; 9788000703; 69690630903; 889800982903; 988709748803; 7968052803; 99960007803; 969900800803; 668604817603; 66960903; 78790734603; 8868007703; 79780034903; 8878085903; 976907603; 89670830803; 877900903; 969904889703; 7978033903; 8987043903; 99860703; 979805903; 667603803; 976805348603; 999604127603; 97790701603; 78990342903; 98770672903; 87990253903; 9877027703; 97790803; 877901895603; 8789076903; 896708595603; 997601903; 799806903; 97690603; 87790371703; 667605603; 99760303703; 97680283803; 788902750803; 787909803; 79780603; 79880866903; 9986050903; 87890543903; 979800803; 97690179703; 876901603; 699909903; 96990192603; 878904903; 877904734903; 796801446903; 977904803; 9887044803; 797805565603; 98870789703; 7869093903; 87790727703; 797801232803; 666604803; 9778071903; 9799086703; 6969000903; 89670903; 8799075903; 897708903; 88680903; 97980362603; 97980503903; 889803256703; 88980388703; 789909376803; 69690703; 6969025903; 89970309903; 96690703; 877901847803; 968901903; 96690603; 88680607603; 7889001703; 789904761803; 976807703; 976902903; 878907889703; 9897014903; 896707046603; 696909903; 666603998903; 969902703; 79680421803; 9769075603; 798800192703; 97990903; 9689024903; 668604803; 969908671903; 9996094703; 69990642703; 97890895903; 977805619903; 79980859903; 88980443803; 98970649603; 997602703; 888802169903; 699907803; 667602028803; 786903283903; 997607703; 969909803; 798809925903; 9976045603; 97790903; 9789001903; 966903603; 9789069603; 968906603; 6989091803; 896701603; 6979059803; 978803903; 997606362603; 88980803; 98970803; 88880921703; 8997065703; 899700703; 698908703; 797801027903; 7889050903; 87890603; 78690703; 99660069703; 97980309903; 976800603; 666606803; 898707703; 79880019803; 66960250803; 7978049803; 88780602603; 79680903; 88880792703; 96990903; 667608603; 87790730903; 98970903; 9699032903; 8987004803; 88880703; 89770046603; 978800803; 969908903; 9798022603; 696901903; 799803703; 989703703; 668605903; 79780903; 998601371703; 796803339703; 87890922603; 898708903; 9966061903; 66960891903; 96790903; 8779050803; 98870858803; 976909298603; 9887029903; 669608703; 979806903; 878903803; 99960703; 9789086703; 979801803; 66960008703; 979806830803; 99760212703; 786906603; 797807603; 789907297703; 96990703; 786901603; 796807766603; 896702651603; 789902585603; 66660925903; 9986085703; 66960302703; 69890703; 789900703; 89970903; 9679060703; 9789002903; 979908821603; 986708140803; 976809828703; 7988082803; 79680997903; 99960803; 9788081903; 979805703; 787908603; 66960602803; 9887098703; 978803237703; 888806804603; 999604703; 977904703; 966904635703; 97680291703; 977809345603; 8878046703; 988709803; 976900773603; 989703903; 88780198603; 87790603; 986708703; 78890604703; 87790544803; 976809850903; 887806703; 987707527603; 79880803; 9897059603; 897709820603; 97880804803; 66960026703; 9789062803; 9867090803; 669600603; 8967087703; 78890903; 89770903; 97980703; 976802687603; 66860400803; 979901288603; 96990160903; 99860228903; 966900703; 66760603; 9689035703; 9779064703; 7968023603; 87890791903; 98770870603; 9798005803; 6969087903; 9779097903; 6979065703; 699903252603; 79780989703; 87690901803; 978905763903; 977809703; 97790369703; 899703269603; 8878012703; 78790803; 87690395603; 8888042803; 667607689903; 8977041803; 6666085603; 6999080703; 69990797803; 88680721603; 99660519803; 889807603; 87890146703; 699906325903; 89770603; 669608615903; 9779028803; 88880603; 97790703; 79780703; 97680355603; 6696024803; 78790784703; 97880329903; 9699077703; 89870803; 79680227903; 976905852703; 8997098903; 896704796703; 66860598803; 9897036703; 66960703; 9699094703; 9699008703; 97780485903; 999603179903; 89770834803; 96790445603; 79680460903; 9867009603; 89870328703; 799801035803; 989702903; 66960758903; 66860150803; 6686088603; 9877092803; 96990603; 99860603; 987703663603; 98870903; 699903325603; 87790803; 97680703; 8868030703; 9799030803; 89870703; 97680803; 9669054803; 6979097603; 987708046603; 999608603; 878904803; 998607408903; 968903903; 696900703; 977907491703; 6686033803; 669601803; 99960290603; 887809169903; 979803703; 69890903; 699901447903; 8987064903; 799800603; 98770903; 8997068703; 967903603; 66760146803; 978805087903; 697908138603; 799801603; 88780964903; 989708339903; 8967048603; 88880981603; 789909703; 796806603; 977905977603; 989700603; 97780703; 9669062603; 88980714603; 897709545903; 988701916703; 667604694903; 786905664603; 877900803; 886805490903; 89970559903; 99960531803; 7998033903; 98770803; 78890418703; 669600872803; 996605216603; 78690962703; 667604903; 996600903; 999608903; 9699083803; 787901803; 97780707603; 787905312703; 977805803; 8977033703; 97890708703; 989705521903; 978800703; 698905703; 78890376903; 878907703; 999602903; 986705903; 668602719603; 979901803; 997606903; 66760393903; 987703603; 78790338903; 96890803; 97680596803; 666601603; 977902178803; 877902803; 78790038603; 8868075703; 99960060603)'; From b6bddd8c0912cb0b59462a05e324d16fca724fcd Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Thu, 17 Feb 2022 11:39:01 -0800 Subject: [PATCH 044/104] pr feedback --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 5f8a265f5..5a59d5ce6 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -388,7 +388,7 @@ /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, - /\b(nexus 6p|lya-l0c|yale?\-a?l\d{2}[ad]?|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i + /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi From f02a431000c3de85b2e6ea8c6a06ecb2c0fadf4d Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Thu, 17 Feb 2022 12:01:10 -0800 Subject: [PATCH 045/104] v100 tests --- test/browser-test.json | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/browser-test.json b/test/browser-test.json index bce9f2280..fd413b991 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -189,6 +189,16 @@ "major" : "20" } }, + { + "desc" : "Chrome", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4758.102 Safari/537.36", + "expect" : + { + "name" : "Chrome", + "version" : "100.0.4758.102", + "major" : "100" + } + }, { "desc" : "Chrome Headless", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome Safari/537.36", @@ -409,6 +419,16 @@ "major" : "15" } }, + { + "desc" : "Firefox", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0", + "expect" : + { + "name" : "Firefox", + "version" : "100.0", + "major" : "100" + } + }, { "desc" : "Firefox Reality", "ua" : "Mozilla/5.0 (Android 7.1.2; Mobile VR; rv:65.0) Gecko/65.0 Firefox/65.0", @@ -1258,6 +1278,16 @@ "major" : "18" } }, + { + "desc" : "Microsoft Edge 100", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.1108.55 Safari/537.36 Edg/100.0.1108.55", + "expect" : + { + "name" : "Edge", + "version" : "100.0.1108.55", + "major" : "100" + } + }, { "desc" : "Microsoft Edge on iOS", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 EdgiOS/42.1.1.0 Mobile/15F79 Safari/605.1.15", From fe963b58e5a00d453f8c288c54b15055700a81db Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 15 Mar 2022 14:07:03 -0700 Subject: [PATCH 046/104] Add support for HuaweiBrowser --- src/ua-parser.js | 2 ++ test/browser-test.json | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index 55c3c8d20..40c37490e 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -211,6 +211,8 @@ ], [VERSION, [NAME, 'Chrome']], [ /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge ], [VERSION, [NAME, 'Edge']], [ + /HuaweiBrowser\/([\w\.]+)/i // HuaweiBrowser + ], [VERSION, [NAME, 'HuaweiBrowser']], [ // Presto based /(opera mini)\/([-\w\.]+)/i, // Opera Mini diff --git a/test/browser-test.json b/test/browser-test.json index fd413b991..560c94772 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -498,6 +498,46 @@ "major" : "1" } }, + { + "desc" : "HuaweiBrowser", + "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00;HMSCore/4.0.0 GMS/10.4 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36", + "expect" : + { + "name" : "HuaweiBrowser", + "version" : "10.0.3.102", + "major" : "10" + } + }, + { + "desc" : "HuaweiBrowser", + "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00;HMSCore/4.0.0 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36", + "expect" : + { + "name" : "HuaweiBrowser", + "version" : "10.0.3.102", + "major" : "10" + } + }, + { + "desc" : "HuaweiBrowser", + "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00;GMS/10.4 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36", + "expect" : + { + "name" : "HuaweiBrowser", + "version" : "10.0.3.102", + "major" : "10" + } + }, + { + "desc" : "HuaweiBrowser", + "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36", + "expect" : + { + "name" : "HuaweiBrowser", + "version" : "10.0.3.102", + "major" : "10" + } + }, { "desc" : "IceApe", "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.19) Gecko/20110817 Iceape/2.0.14", From 534d577355f05dc51284f9cabe4d9d0d33f97c92 Mon Sep 17 00:00:00 2001 From: Paris Morgan Date: Tue, 15 Mar 2022 14:10:22 -0700 Subject: [PATCH 047/104] update readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 456d1105c..144997372 100644 --- a/readme.md +++ b/readme.md @@ -39,7 +39,7 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, -Firefox [Reality], Flock, Flow, GSA, GoBrowser, ICE Browser, IE, IEMobile, IceApe, +Firefox [Reality], Flock, Flow, GSA, GoBrowser, HuaweiBrowser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, From 18a4e5ade240ffa1c1b41a513d2826aa5438658c Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Thu, 24 Mar 2022 08:07:30 +0200 Subject: [PATCH 048/104] package.json: specify the folders to include --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index d442c5765..9c673849d 100644 --- a/package.json +++ b/package.json @@ -141,6 +141,10 @@ "Zach Bjornson " ], "main": "src/ua-parser.js", + "files": [ + "dist", + "src" + ], "scripts": { "build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments '/^ UA/' && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments '/^ UA/' --compress --mangle", "test": "jshint src/ua-parser.js && mocha -R nyan test/test.js", From 779b5dc1e578cff44c96c60678f8449bd9018fd7 Mon Sep 17 00:00:00 2001 From: KnifeLemon Date: Tue, 12 Apr 2022 12:57:28 +0900 Subject: [PATCH 049/104] add KakaoTalk App, KakaoStory App regex --- src/ua-parser.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 55c3c8d20..e34036772 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -57,7 +57,8 @@ SONY = 'Sony', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', - FACEBOOK = 'Facebook'; + FACEBOOK = 'Facebook', + KAKAO = 'Kakao'; /////////// // Helper @@ -287,6 +288,11 @@ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ + / wv\).+(chrome)\/([\w\.]+).+(kakaotalk)/i // KakaoTalk App + ], [[NAME, KAKAO+'Talk'], VERSION], [ + / wv\).+(chrome)\/([\w\.]+).+(kakaostory)/i // KakaoStory App + ], [[NAME, KAKAO+'Story'], VERSION], [ + /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME+' Headless']], [ From 0b423078c8966442fdb617b72a2e0195d5aefb40 Mon Sep 17 00:00:00 2001 From: KnifeLemon Date: Tue, 12 Apr 2022 14:17:48 +0900 Subject: [PATCH 050/104] Add Kakao App, Naver App --- src/ua-parser.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index e34036772..3127a9b28 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -58,7 +58,8 @@ XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', FACEBOOK = 'Facebook', - KAKAO = 'Kakao'; + KAKAO = 'Kakao', + NAVER = 'Naver'; /////////// // Helper @@ -223,6 +224,9 @@ /\bopr\/([\w\.]+)/i // Opera Webkit ], [VERSION, [NAME, OPERA]], [ + /whale\/([-\w\.]+).+NAVER\((.*)\)/i // Naver InApp + ], [VERSION,[NAME, /(.+);\s+(.+);\s+(.+);\s+(.+)/i, NAVER+' $1 $2']], [ + // Mixed /(kindle)\/([\w\.]+)/i, // Kindle /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer @@ -288,10 +292,8 @@ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ - / wv\).+(chrome)\/([\w\.]+).+(kakaotalk)/i // KakaoTalk App - ], [[NAME, KAKAO+'Talk'], VERSION], [ - / wv\).+(chrome)\/([\w\.]+).+(kakaostory)/i // KakaoStory App - ], [[NAME, KAKAO+'Story'], VERSION], [ + / wv\).+chrome\/([\w\.]+).+kakao(.+)\//i // Kakao App + ], [VERSION, [NAME, /(.+)/i, KAKAO+'$1']], [ /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME+' Headless']], [ From 534ba7dd7c7648ac27447b0de7bfad33e733bf4e Mon Sep 17 00:00:00 2001 From: KnifeLemon Date: Tue, 12 Apr 2022 16:21:31 +0900 Subject: [PATCH 051/104] Add iOS Naver, Kakao regex --- src/ua-parser.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 3127a9b28..cdf88eac2 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -224,8 +224,9 @@ /\bopr\/([\w\.]+)/i // Opera Webkit ], [VERSION, [NAME, OPERA]], [ - /whale\/([-\w\.]+).+NAVER\((.*)\)/i // Naver InApp - ], [VERSION,[NAME, /(.+);\s+(.+);\s+(.+);\s+(.+)/i, NAVER+' $1 $2']], [ + /Safari\/([-\w\.]+).+NAVER\((.*)\)/i, // Naver InApp for iOS + /whale\/([-\w\.]+).+NAVER\((.*)\)/i // Naver InApp Android + ], [VERSION,[NAME, /(.+); (.+); [0-9]+;.+/i, NAVER+' $1 $2']], [ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle @@ -292,7 +293,8 @@ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ - / wv\).+chrome\/([\w\.]+).+kakao(.+)\//i // Kakao App + /AppleWebKit\/([\w\.]+).+kakao(.*)\s+/i, // Kakao App for iOS + / wv\).+chrome\/([\w\.]+).+kakao(.+)\//i // Kakao App for Android ], [VERSION, [NAME, /(.+)/i, KAKAO+'$1']], [ /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless From cd25bc186673a8bf4fe674676ed6595a7db89375 Mon Sep 17 00:00:00 2001 From: Dante Date: Tue, 3 May 2022 15:46:27 +0800 Subject: [PATCH 052/104] fix browser-test typo --- test/browser-test.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/browser-test.json b/test/browser-test.json index fd413b991..36944317e 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1209,7 +1209,7 @@ } }, { - "desc": "WeChat on Android", + "desc": "WeiBo on Android", "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16A366 Weibo (iPhone8,2__weibo__8.9.3__iphone__os12.0)", "expect": { From 4f77fbb441168b209a2e12103a88e967587d45e1 Mon Sep 17 00:00:00 2001 From: JBYoshi <12983479+JBYoshi@users.noreply.github.com> Date: Tue, 24 May 2022 23:02:01 -0500 Subject: [PATCH 053/104] Add LinkedIn app. --- src/ua-parser.js | 3 ++- test/browser-test.json | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 55c3c8d20..db8e2b7cf 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -274,7 +274,8 @@ /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [ /(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser - /(lbbrowser)/i // LieBao Browser + /(lbbrowser)/i, // LieBao Browser + /\[(linkedin)app\]/i // LinkedIn App for iOS & Android ], [NAME], [ // WebView diff --git a/test/browser-test.json b/test/browser-test.json index fd413b991..e0f949ac8 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1503,5 +1503,13 @@ "version" : "11.0", "major" : "11" } + }, + { + "desc" : "LinkedIn", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [LinkedInApp]", + "expect" : + { + "name" : "LinkedIn" + } } ] From 180846b80a4716b5a9ed662fe253955b33d12890 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 30 Jun 2022 23:36:29 +0700 Subject: [PATCH 054/104] Rename 'HuaweiBrowser' to 'Huawei Browser' --- readme.md | 16 ++++++++-------- src/ua-parser.js | 6 ++---- test/browser-test.json | 8 ++++---- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/readme.md b/readme.md index 144997372..18278e630 100644 --- a/readme.md +++ b/readme.md @@ -39,14 +39,14 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, -Firefox [Reality], Flock, Flow, GSA, GoBrowser, HuaweiBrowser, ICE Browser, IE, IEMobile, IceApe, -IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, -Kindle, Klar, Konqueror, LBBROWSER, Line, Links, Lunascape, Lynx, MIUI Browser, -Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, -Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Obigo, Oculus Browser, -OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, -Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, -Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, +Firefox [Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, ICE Browser, IE, +IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, +K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, LinkedIn, Links, Lunascape, Lynx, +MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, +Mosaic, Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Obigo, +Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, +Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, +Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, UP.Browser, Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... diff --git a/src/ua-parser.js b/src/ua-parser.js index a7cf6e266..7fdf0fd8d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -211,8 +211,6 @@ ], [VERSION, [NAME, 'Chrome']], [ /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge ], [VERSION, [NAME, 'Edge']], [ - /HuaweiBrowser\/([\w\.]+)/i // HuaweiBrowser - ], [VERSION, [NAME, 'HuaweiBrowser']], [ // Presto based /(opera mini)\/([-\w\.]+)/i, // Opera Mini @@ -267,8 +265,8 @@ ], [VERSION, [NAME, FIREFOX]], [ /\bqihu|(qi?ho?o?|360)browser/i // 360 ], [[NAME, '360 '+BROWSER]], [ - /(oculus|samsung|sailfish)browser\/([\w\.]+)/i - ], [[NAME, /(.+)/, '$1 '+BROWSER], VERSION], [ // Oculus/Samsung/Sailfish Browser + /(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i + ], [[NAME, /(.+)/, '$1 '+BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, ' '], VERSION], [ /(electron)\/([\w\.]+) safari/i, // Electron-based App diff --git a/test/browser-test.json b/test/browser-test.json index 0336800a3..75a30e95c 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -503,7 +503,7 @@ "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00;HMSCore/4.0.0 GMS/10.4 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36", "expect" : { - "name" : "HuaweiBrowser", + "name" : "Huawei Browser", "version" : "10.0.3.102", "major" : "10" } @@ -513,7 +513,7 @@ "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00;HMSCore/4.0.0 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36", "expect" : { - "name" : "HuaweiBrowser", + "name" : "Huawei Browser", "version" : "10.0.3.102", "major" : "10" } @@ -523,7 +523,7 @@ "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00;GMS/10.4 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36", "expect" : { - "name" : "HuaweiBrowser", + "name" : "Huawei Browser", "version" : "10.0.3.102", "major" : "10" } @@ -533,7 +533,7 @@ "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36", "expect" : { - "name" : "HuaweiBrowser", + "name" : "Huawei Browser", "version" : "10.0.3.102", "major" : "10" } From a5cdc2975b2587a275e4ee96c607a7c81b490558 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 30 Jun 2022 23:46:42 +0700 Subject: [PATCH 055/104] Fix #565 - Add new OS: HarmonyOS --- readme.md | 11 ++++++----- src/ua-parser.js | 2 +- test/os-test.json | 9 +++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 18278e630..09ee85bcf 100644 --- a/readme.md +++ b/readme.md @@ -88,11 +88,12 @@ NetSurf, Presto, Tasman, Trident, w3m, WebKit # Possible 'os.name' AIX, Amiga OS, Android[-x86], Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, Deepin, DragonFly, elementary OS, -Fuchsia, Gentoo, GhostBSD, GNU, Haiku, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linspire, -Linux, Mac OS, Maemo, Mageia, Mandriva, Manjaro, MeeGo, Minix, Mint, Morph OS, NetBSD, -Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, -Raspbian, RedHat, RIM Tablet OS, RISC OS, Sabayon, Sailfish, Series40, Slackware, Solaris, -SUSE, Symbian, Tizen, Ubuntu, Unix, VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... +Fuchsia, Gentoo, GhostBSD, GNU, Haiku, HarmonyOS, HP-UX, Hurd, iOS, Joli, KaiOS, +Linpus, Linspire,Linux, Mac OS, Maemo, Mageia, Mandriva, Manjaro, MeeGo, Minix, +Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, PCLinuxOS, +Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, RISC OS, Sabayon, +Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, +VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 7fdf0fd8d..c19d6b371 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -701,7 +701,7 @@ ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ // Mobile OSes - /droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86 + /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry diff --git a/test/os-test.json b/test/os-test.json index a0eb41269..57a4d8a95 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -206,6 +206,15 @@ "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", From 1e82d7d265934a51fb6ab534c415dffe79162a94 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 1 Jul 2022 00:27:57 +0700 Subject: [PATCH 056/104] Fix #558 - WeGame mistakenly identified as WeChat --- src/ua-parser.js | 3 ++- test/browser-test.json | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index c19d6b371..93deb1f16 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -237,7 +237,8 @@ ], [NAME, VERSION], [ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser ], [VERSION, [NAME, 'UC'+BROWSER]], [ - /\bqbcore\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser + /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser + /\bqbcore\/([\w\.]+).+microm/i ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ /micromessenger\/([\w\.]+)/i // WeChat ], [VERSION, [NAME, 'WeChat']], [ diff --git a/test/browser-test.json b/test/browser-test.json index 75a30e95c..d6e1342ec 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1448,6 +1448,16 @@ "major" : "4" } }, + { + "desc" : "Supposed not to be detected as WeChat", + "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.124 Safari/537.36 qblink wegame.exe WeGame/5.1.1.11100 QBCore/3.70.107.400 QQBrowser/9.0.2524.400", + "expect" : + { + "name" : "QQBrowser", + "version" : "9.0.2524.400", + "major" : "9" + } + }, { "desc" : "GSA on iOS", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) GSA/30.1.161623614 Mobile/14F89 Safari/602.1", From 30ac448a0c277624432a8e3d3da4ade82eaf9f55 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 1 Jul 2022 00:39:36 +0700 Subject: [PATCH 057/104] Increase UA_MAX_LENGTH to 350 --- src/ua-parser.js | 2 +- test/test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 93deb1f16..91ba874e5 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -37,7 +37,7 @@ SMARTTV = 'smarttv', WEARABLE = 'wearable', EMBEDDED = 'embedded', - UA_MAX_LENGTH = 275; + UA_MAX_LENGTH = 350; var AMAZON = 'Amazon', APPLE = 'Apple', diff --git a/test/test.js b/test/test.js index fc7ebc537..e1fd175d2 100644 --- a/test/test.js +++ b/test/test.js @@ -109,7 +109,7 @@ describe('Extending Regex', function () { }); describe('User-agent length', function () { - var UA_MAX_LENGTH = 275; + var UA_MAX_LENGTH = 350; // Real data from https://stackoverflow.com/questions/654921/how-big-can-a-user-agent-string-get#answer-6595973 var uaString = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; (R1 1.6); SLCC1; .NET CLR 2.0.50727; InfoPath.2; OfficeLiveConnector.1.3; OfficeLivePatch.0.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618; 66760635803; runtime 11.00294; 876906799603; 97880703; 669602703; 9778063903; 877905603; 89670803; 96690803; 8878091903; 7879040603; 999608065603; 799808803; 6666059903; 669602102803; 888809342903; 696901603; 788907703; 887806555703; 97690214703; 66760903; 968909903; 796802422703; 8868026703; 889803611803; 898706903; 977806408603; 976900799903; 9897086903; 88780803; 798802301603; 9966008603; 66760703; 97890452603; 9789064803; 96990759803; 99960107703; 8868087903; 889801155603; 78890703; 8898070603; 89970603; 89970539603; 89970488703; 8789007603; 87890903; 877904603; 9887077703; 798804903; 97890264603; 967901703; 87890703; 97690420803; 79980706603; 9867086703; 996602846703; 87690803; 6989010903; 977809603; 666601903; 876905337803; 89670603; 89970200903; 786903603; 696901911703; 788905703; 896709803; 96890703; 998601903; 88980703; 666604769703; 978806603; 7988020803; 996608803; 788903297903; 98770043603; 899708803; 66960371603; 9669088903; 69990703; 99660519903; 97780603; 888801803; 9867071703; 79780803; 9779087603; 899708603; 66960456803; 898706824603; 78890299903; 99660703; 9768079803; 977901591603; 89670605603; 787903608603; 998607934903; 799808573903; 878909603; 979808146703; 9996088603; 797803154903; 69790603; 99660565603; 7869028603; 896707703; 97980965603; 976907191703; 88680703; 888809803; 69690903; 889805523703; 899707703; 997605035603; 89970029803; 9699094903; 877906803; 899707002703; 786905857603; 69890803; 97980051903; 997603978803; 9897097903; 66960141703; 7968077603; 977804603; 88980603; 989700803; 999607887803; 78690772803; 96990560903; 98970961603; 9996032903; 9699098703; 69890655603; 978903803; 698905066803; 977806903; 9789061703; 967903747703; 976900550903; 88980934703; 8878075803; 8977028703; 97980903; 9769006603; 786900803; 98770682703; 78790903; 878906967903; 87690399603; 99860976703; 796805703; 87990603; 968906803; 967904724603; 999606603; 988705903; 989702842603; 96790603; 99760703; 88980166703; 9799038903; 98670903; 697905248603; 7968043603; 66860703; 66860127903; 9779048903; 89670123903; 78890397703; 97890603; 87890803; 8789030603; 69990603; 88880763703; 9769000603; 96990203903; 978900405903; 7869022803; 699905422903; 97890703; 87990903; 878908703; 7998093903; 898702507603; 97780637603; 966907903; 896702603; 9769004803; 7869007903; 99660158803; 7899099603; 8977055803; 99660603; 7889080903; 66660981603; 997604603; 6969089803; 899701903; 9769072703; 666603903; 99860803; 997608803; 69790903; 88680756703; 979805677903; 9986047703; 89970803; 66660603; 96690903; 8997051603; 789901209803; 8977098903; 968900326803; 87790703; 98770024803; 697901794603; 69990803; 887805925803; 968908903; 97880603; 897709148703; 877909476903; 66760197703; 977908603; 698902703; 988706504803; 977802026603; 88680964703; 8878068703; 987705107903; 978902878703; 8898069803; 9768031703; 79680803; 79980803; 669609328703; 89870238703; 99960593903; 969904218703; 78890603; 9788000703; 69690630903; 889800982903; 988709748803; 7968052803; 99960007803; 969900800803; 668604817603; 66960903; 78790734603; 8868007703; 79780034903; 8878085903; 976907603; 89670830803; 877900903; 969904889703; 7978033903; 8987043903; 99860703; 979805903; 667603803; 976805348603; 999604127603; 97790701603; 78990342903; 98770672903; 87990253903; 9877027703; 97790803; 877901895603; 8789076903; 896708595603; 997601903; 799806903; 97690603; 87790371703; 667605603; 99760303703; 97680283803; 788902750803; 787909803; 79780603; 79880866903; 9986050903; 87890543903; 979800803; 97690179703; 876901603; 699909903; 96990192603; 878904903; 877904734903; 796801446903; 977904803; 9887044803; 797805565603; 98870789703; 7869093903; 87790727703; 797801232803; 666604803; 9778071903; 9799086703; 6969000903; 89670903; 8799075903; 897708903; 88680903; 97980362603; 97980503903; 889803256703; 88980388703; 789909376803; 69690703; 6969025903; 89970309903; 96690703; 877901847803; 968901903; 96690603; 88680607603; 7889001703; 789904761803; 976807703; 976902903; 878907889703; 9897014903; 896707046603; 696909903; 666603998903; 969902703; 79680421803; 9769075603; 798800192703; 97990903; 9689024903; 668604803; 969908671903; 9996094703; 69990642703; 97890895903; 977805619903; 79980859903; 88980443803; 98970649603; 997602703; 888802169903; 699907803; 667602028803; 786903283903; 997607703; 969909803; 798809925903; 9976045603; 97790903; 9789001903; 966903603; 9789069603; 968906603; 6989091803; 896701603; 6979059803; 978803903; 997606362603; 88980803; 98970803; 88880921703; 8997065703; 899700703; 698908703; 797801027903; 7889050903; 87890603; 78690703; 99660069703; 97980309903; 976800603; 666606803; 898707703; 79880019803; 66960250803; 7978049803; 88780602603; 79680903; 88880792703; 96990903; 667608603; 87790730903; 98970903; 9699032903; 8987004803; 88880703; 89770046603; 978800803; 969908903; 9798022603; 696901903; 799803703; 989703703; 668605903; 79780903; 998601371703; 796803339703; 87890922603; 898708903; 9966061903; 66960891903; 96790903; 8779050803; 98870858803; 976909298603; 9887029903; 669608703; 979806903; 878903803; 99960703; 9789086703; 979801803; 66960008703; 979806830803; 99760212703; 786906603; 797807603; 789907297703; 96990703; 786901603; 796807766603; 896702651603; 789902585603; 66660925903; 9986085703; 66960302703; 69890703; 789900703; 89970903; 9679060703; 9789002903; 979908821603; 986708140803; 976809828703; 7988082803; 79680997903; 99960803; 9788081903; 979805703; 787908603; 66960602803; 9887098703; 978803237703; 888806804603; 999604703; 977904703; 966904635703; 97680291703; 977809345603; 8878046703; 988709803; 976900773603; 989703903; 88780198603; 87790603; 986708703; 78890604703; 87790544803; 976809850903; 887806703; 987707527603; 79880803; 9897059603; 897709820603; 97880804803; 66960026703; 9789062803; 9867090803; 669600603; 8967087703; 78890903; 89770903; 97980703; 976802687603; 66860400803; 979901288603; 96990160903; 99860228903; 966900703; 66760603; 9689035703; 9779064703; 7968023603; 87890791903; 98770870603; 9798005803; 6969087903; 9779097903; 6979065703; 699903252603; 79780989703; 87690901803; 978905763903; 977809703; 97790369703; 899703269603; 8878012703; 78790803; 87690395603; 8888042803; 667607689903; 8977041803; 6666085603; 6999080703; 69990797803; 88680721603; 99660519803; 889807603; 87890146703; 699906325903; 89770603; 669608615903; 9779028803; 88880603; 97790703; 79780703; 97680355603; 6696024803; 78790784703; 97880329903; 9699077703; 89870803; 79680227903; 976905852703; 8997098903; 896704796703; 66860598803; 9897036703; 66960703; 9699094703; 9699008703; 97780485903; 999603179903; 89770834803; 96790445603; 79680460903; 9867009603; 89870328703; 799801035803; 989702903; 66960758903; 66860150803; 6686088603; 9877092803; 96990603; 99860603; 987703663603; 98870903; 699903325603; 87790803; 97680703; 8868030703; 9799030803; 89870703; 97680803; 9669054803; 6979097603; 987708046603; 999608603; 878904803; 998607408903; 968903903; 696900703; 977907491703; 6686033803; 669601803; 99960290603; 887809169903; 979803703; 69890903; 699901447903; 8987064903; 799800603; 98770903; 8997068703; 967903603; 66760146803; 978805087903; 697908138603; 799801603; 88780964903; 989708339903; 8967048603; 88880981603; 789909703; 796806603; 977905977603; 989700603; 97780703; 9669062603; 88980714603; 897709545903; 988701916703; 667604694903; 786905664603; 877900803; 886805490903; 89970559903; 99960531803; 7998033903; 98770803; 78890418703; 669600872803; 996605216603; 78690962703; 667604903; 996600903; 999608903; 9699083803; 787901803; 97780707603; 787905312703; 977805803; 8977033703; 97890708703; 989705521903; 978800703; 698905703; 78890376903; 878907703; 999602903; 986705903; 668602719603; 979901803; 997606903; 66760393903; 987703603; 78790338903; 96890803; 97680596803; 666601603; 977902178803; 877902803; 78790038603; 8868075703; 99960060603)'; From 21fe76742f59cb7e0957954c846a28cefc023a33 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 1 Jul 2022 01:14:03 +0700 Subject: [PATCH 058/104] Fix #532 - Detect Xiaomi Mi TV as smarttv --- src/ua-parser.js | 2 ++ test/device-test.json | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index 91ba874e5..ae1124b8c 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -620,6 +620,8 @@ ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ /(bravia[\w- ]+) bui/i // Sony ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ + /(mitv-\w{5}) bui/i // Xiaomi + ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ diff --git a/test/device-test.json b/test/device-test.json index 9b102dc39..a0449ed7b 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1458,6 +1458,15 @@ "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", From f54d3fadac6c57733db3ae2f49570703ce388192 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 2 Jul 2022 23:06:08 +0700 Subject: [PATCH 059/104] Fix #513 - Add new browser: DuckDuckGo --- readme.md | 23 ++++++++++++----------- src/ua-parser.js | 4 ++-- test/browser-test.json | 10 ++++++++++ test/device-test.json | 9 +++++++++ 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index 09ee85bcf..e2290c335 100644 --- a/readme.md +++ b/readme.md @@ -38,17 +38,18 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro 2345Explorer, 360 Browser, Amaya, Android Browser, Arora, Avant, Avast, AVG, BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, -Dolphin, Doris, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, -Firefox [Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, ICE Browser, IE, -IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, -K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, LinkedIn, Links, Lunascape, Lynx, -MIUI Browser, Maemo Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, -Mosaic, Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Obigo, -Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, -Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, -Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, -SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, UP.Browser, Vivaldi, -Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... +Dolphin, Doris, DuckDuckGo, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, +Firebird, Firefox [Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, +ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, +Iridium, Iron, Jasmine, K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, +LinkedIn, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, +MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, NetSurf, Netfront, +Netscape, NokiaBrowser, Obigo, Oculus Browser, OmniWeb, Opera Coast, +Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, Polaris, Puffin, QQ, +QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, Sailfish Browser, +Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, SlimBrowser, Swiftfox, +Tesla, Tizen Browser, UCBrowser, UP.Browser, Vivaldi, Waterfox, WeChat, Weibo, +Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index ae1124b8c..1cfded873 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -231,7 +231,7 @@ /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer // 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|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([-\w\.]+)/i, + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ @@ -658,7 +658,7 @@ ], [MODEL, [TYPE, TABLET]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet ], [[TYPE, TABLET]], [ - /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile + /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] diff --git a/test/browser-test.json b/test/browser-test.json index d6e1342ec..4895ba4d2 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -299,6 +299,16 @@ "major" : "1" } }, + { + "desc" : "DuckDuckGo", + "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" : + { + "name" : "DuckDuckGo", + "version" : "5", + "major" : "5" + } + }, { "desc" : "Epiphany", "ua" : "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7) Gecko/20040628 Epiphany/1.2.6", diff --git a/test/device-test.json b/test/device-test.json index a0449ed7b..381ace8cb 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -196,6 +196,15 @@ "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": "Essential PH-1", "ua": "Mozilla/5.0 (Linux; Android 9; PH-1 Build/PPR1.180905.036) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36", From ca417e25a9216ad5c2b6648961b8a723eacc3f28 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 5 Jul 2022 00:03:52 +0700 Subject: [PATCH 060/104] Fix #516 - Add Focus into list of possible browser.name --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index e2290c335..462bd1c57 100644 --- a/readme.md +++ b/readme.md @@ -39,7 +39,7 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, DuckDuckGo, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, -Firebird, Firefox [Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, +Firebird, Firefox [Focus/Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, LinkedIn, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, From dea39e1693e44b90b7c485dca0f2c9dda9377ff5 Mon Sep 17 00:00:00 2001 From: Varun Sharma Date: Mon, 11 Jul 2022 07:45:10 -0700 Subject: [PATCH 061/104] ci: add GitHub token permissions for workflow Signed-off-by: Varun Sharma --- .github/workflows/run-test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/run-test.yml b/.github/workflows/run-test.yml index ab126d2a6..203184294 100644 --- a/.github/workflows/run-test.yml +++ b/.github/workflows/run-test.yml @@ -2,6 +2,9 @@ name: ua-parser-js-run-test on: [push, pull_request] +permissions: + contents: read + jobs: run-test: runs-on: ubuntu-latest From ebb32d1ad96954cc2f255990df4e9f628cafc221 Mon Sep 17 00:00:00 2001 From: Jacky Choo Date: Wed, 27 Jul 2022 17:41:35 +0800 Subject: [PATCH 062/104] fixed sony bravia smart tv, added sharp AQUOS TV --- src/ua-parser.js | 9 ++++++--- test/device-test.json | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 1cfded873..39410a4da 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -54,6 +54,7 @@ MOTOROLA = 'Motorola', OPERA = 'Opera', SAMSUNG = 'Samsung', + SHARP = 'Sharp', SONY = 'Sony', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', @@ -504,7 +505,7 @@ // Sharp /\b(sh-?[altvz]?\d\d[a-ekm]?)/i - ], [MODEL, [VENDOR, 'Sharp'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ // MIXED /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i, @@ -617,8 +618,10 @@ /droid.+aft(\w)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i // Sharp - ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ - /(bravia[\w- ]+) bui/i // Sony + ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]], [ + /(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 ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ diff --git a/test/device-test.json b/test/device-test.json index 381ace8cb..dcc0498fa 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1710,6 +1710,15 @@ "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", @@ -1890,6 +1899,24 @@ "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" : "Tesla", "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", From 75e58525fe5bda8bef1b284c2c89ebf781da578f Mon Sep 17 00:00:00 2001 From: nabetama Date: Thu, 15 Sep 2022 23:10:12 +0900 Subject: [PATCH 063/104] Safari and Mobile Safari began to include commas in the minor version numbers. --- src/ua-parser.js | 4 ++-- test/browser-test.json | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 1cfded873..5294de38d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -301,9 +301,9 @@ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ - /version\/([\w\.]+) .*mobile\/\w+ (safari)/i // Mobile Safari + /version\/([\w(\.|\,)]+) .*mobile\/\w+ (safari)/i // Mobile Safari ], [VERSION, [NAME, 'Mobile Safari']], [ - /version\/([\w\.]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile + /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 ], [NAME, [VERSION, strMapper, oldSafariMap]], [ diff --git a/test/browser-test.json b/test/browser-test.json index 4895ba4d2..bf8163a1f 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1571,5 +1571,25 @@ { "name" : "LinkedIn" } + }, + { + "desc" : "Safari including comma in minor version number", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6,2 Safari/605.1.15", + "expect" : + { + "name" : "Safari", + "version" : "15.6,2", + "major" : "15" + } + }, + { + "desc" : "Mobile Safari including comma in minor version number", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 15_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6,2 Mobile/15E148 Safari/604.1", + "expect" : + { + "name" : "Mobile Safari", + "version" : "15.6,2", + "major" : "15" + } } ] From 25fff625409a27a3e9cda4cbe2f23f7ad7e5bab8 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 18 Sep 2022 16:11:36 +0700 Subject: [PATCH 064/104] Fix #502 #580 : Add notice for desktop device type --- readme.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/readme.md b/readme.md index e2290c335..f1f4817ad 100644 --- a/readme.md +++ b/readme.md @@ -61,6 +61,13 @@ Yandex, baidu, iCab, w3m, Whale Browser... # Possible 'device.type': console, mobile, tablet, smarttv, wearable, embedded +########## +# NOTE: 'desktop' is not a possible device type. +# UAParser only reports info directly available from the UA string, which is not the case for 'desktop' device type. +# If you wish to detect desktop devices, you must handle the needed logic yourself. +# You can read more about it in this issue: https://github.com/faisalman/ua-parser-js/issues/182 +########## + # Possible 'device.vendor': Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, Essential, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, From 8483ac09b3076e5395e1e3bf64b34a62bf7a7b28 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 18 Sep 2022 16:37:13 +0700 Subject: [PATCH 065/104] Refine small redundancy --- src/ua-parser.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index e9121229a..67e4db862 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -302,7 +302,7 @@ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [ - /version\/([\w(\.|\,)]+) .*mobile\/\w+ (safari)/i // Mobile Safari + /version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i // Mobile Safari ], [VERSION, [NAME, 'Mobile Safari']], [ /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [ @@ -617,8 +617,7 @@ ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ /droid.+aft(\w)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ - /\(dtv[\);].+(aquos)/i // Sharp - ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]], [ + /\(dtv[\);].+(aquos)/i, /(aquos-tv[\w ]+)\)/i // Sharp ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[ /(bravia[\w ]+)( bui|\))/i // Sony From 55b5b40c7dd5f2e44e645022ec8990efcad7e907 Mon Sep 17 00:00:00 2001 From: kNoAPP Date: Tue, 20 Sep 2022 11:56:24 -0700 Subject: [PATCH 066/104] Fix #596 - Detect Galaxy Tab S8 as tablet --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 67e4db862..b61c16121 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -373,7 +373,7 @@ ///////////////////////// // Samsung - /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i + /\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, /samsung[- ]([-\w]+)/i, From 48d930f0f1295b3a59efc8ee52854a9948d29eab Mon Sep 17 00:00:00 2001 From: kNoAPP Date: Tue, 20 Sep 2022 12:01:17 -0700 Subject: [PATCH 067/104] Add test case --- test/device-test.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/device-test.json b/test/device-test.json index dcc0498fa..bad1e50af 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1638,6 +1638,15 @@ "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", From b2d685dd9c90edb112963569e2e9bb5d604f0ad6 Mon Sep 17 00:00:00 2001 From: Mok Date: Sun, 9 Oct 2022 15:09:25 +0300 Subject: [PATCH 068/104] improved documentation --- readme.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index e2290c335..185a2f9c4 100644 --- a/readme.md +++ b/readme.md @@ -19,17 +19,60 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro * Source : https://github.com/faisalman/ua-parser-js # Documentation +### UAParser([user-agent][,extensions]) +typeof `user-agent` "string". + +typeof `extensions` "array". + +In The Browser environment you dont need to pass the user-agent string to the function, you can just call the funtion and it should automatically get the string from the `window.navigator.userAgent`, but that is not the case in nodejs. The user-agent string must be passed in nodejs for the function to work. +Usually you can find the user agent in: +`request.headers["user-agent"]`. -## Constructor +## Constructor +When you call `UAParser` with the `new` keyword `UAParser` will return a new instance with an empty result object, you have to call one of the available methods to get the information from the user-agent string. +Like so: * `new UAParser([uastring][,extensions])` - * returns new instance +```js +let parser = new UAParser("user-agent"); // you need to pass the user-agent for nodejs +console.log(parser); // {} +let parserResults = parser.getResults(); +console.log(parserResults); +/** { + "ua": "", + "browser": {}, + "engine": {}, + "os": {}, + "device": {}, + "cpu": {} +} */ +``` +When you call UAParser without the `new` keyword, it will automatically call `getResults()` function and return the parsed results. * `UAParser([uastring][,extensions])` * returns result object `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` ## Methods +#### Methods table +The methods are self explanatory, here's a small overview on all the available methods: +* `getResult()` - returns all function object calls, user-agent string, browser info, cpu, device, engine, os: +`{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`. + + * `getBrowser()` - returns the browser name and version. + * `getDevice()` - returns the device model, type, vendor. + * `getEngine()` - returns the current browser engine name and version. + * `getOS()` - returns the running operating system name and version. + * `getCPU()` - returns CPU architectural design name. + * `getUA()` - returns the user-agent string. + * `setUA(user-agent)` - set a custom user-agent to be parsed. + + +--- + +* `getResult()` + * returns `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` + * `getBrowser()` * returns `{ name: '', version: '' }` @@ -39,7 +82,7 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, Dolphin, Doris, DuckDuckGo, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, -Firebird, Firefox [Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, +Firebird, Firefox [Focus/Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, Iridium, Iron, Jasmine, K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, LinkedIn, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, @@ -61,6 +104,13 @@ Yandex, baidu, iCab, w3m, Whale Browser... # Possible 'device.type': console, mobile, tablet, smarttv, wearable, embedded +########## +# NOTE: 'desktop' is not a possible device type. +# UAParser only reports info directly available from the UA string, which is not the case for 'desktop' device type. +# If you wish to detect desktop devices, you must handle the needed logic yourself. +# You can read more about it in this issue: https://github.com/faisalman/ua-parser-js/issues/182 +########## + # Possible 'device.vendor': Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, Essential, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, @@ -107,9 +157,6 @@ VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... 68k, amd64, arm[64/hf], avr, ia[32/64], irix[64], mips[64], pa-risc, ppc, sparc[64] ``` -* `getResult()` - * returns `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` - * `getUA()` * returns UA string of current instance @@ -193,6 +240,8 @@ VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... ## Using node.js +Note: Device information is not available in the NodeJS environment. + ```sh $ npm install ua-parser-js ``` From d11fc47dc9b6acc0f89fc10c120cea08e10cd31a Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 15 Oct 2022 16:15:14 +0700 Subject: [PATCH 069/104] Bump version 0.7.32 --- bower.json | 2 +- dist/ua-parser.min.js | 2 +- dist/ua-parser.pack.js | 2 +- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bower.json b/bower.json index 618bac584..a4a06b220 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.31", + "version": "0.7.32", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 08dc9d5e3..d5869863f 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ /* UAParser.js v0.7.31 Copyright © 2012-2021 Faisal Salman MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.31",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",EMBEDDED="embedded",UA_MAX_LENGTH=255;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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="0.7.31",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",EMBEDDED="embedded",UA_MAX_LENGTH=350;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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.pack.js b/dist/ua-parser.pack.js index da1bb2678..18c0cdcd6 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ /* UAParser.js v0.7.31 Copyright © 2012-2021 Faisal Salman MIT License */ -!function(r,d){"use strict";function i(i){for(var e={},o=0;o (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index b61c16121..b47ad2364 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v0.7.31 +/* UAParser.js v0.7.32 Copyright © 2012-2021 Faisal Salman MIT License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.7.31', + var LIBVERSION = '0.7.32', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 8d3c2d327cf540ff2c050f1cc67bca8c6f8e4458 Mon Sep 17 00:00:00 2001 From: Oscar Becerra Date: Mon, 17 Oct 2022 14:03:53 -0700 Subject: [PATCH 070/104] Add new browser: Cobalt --- src/ua-parser.js | 5 ++++- test/browser-test.json | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index b47ad2364..e2c326364 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -330,7 +330,10 @@ /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser /(links) \(([\w\.]+)/i // Links - ], [NAME, VERSION] + ], [NAME, VERSION], [ + + /(cobalt)\/([\w\.]+)/i // Cobalt + ], [NAME, [VERSION, /master.|lts./, ""]] ], cpu : [[ diff --git a/test/browser-test.json b/test/browser-test.json index bf8163a1f..2be58c21b 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1591,5 +1591,41 @@ "version" : "15.6,2", "major" : "15" } + }, + { + "desc" : "Cobalt 23 Master", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) Cobalt/23.master.0.0-devel (unlike Gecko) v8/8.8.278.8-jit gles Starboard/15", + "expect" : { + "name" : "Cobalt", + "version": "23.0.0", + "major" : "23" + } + }, + { + "desc" : "Cobalt 23 LTS", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) Cobalt/23.lts.1.0-qa (unlike Gecko) v8/8.8.278.8-jit gles Starboard/15", + "expect" : { + "name" : "Cobalt", + "version": "23.1.0", + "major" : "23" + } + }, + { + "desc" : "Cobalt 11", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) Cobalt/11.0-qa (unlike Gecko) Starboard/6", + "expect" : { + "name" : "Cobalt", + "version": "11.0", + "major" : "11" + } + }, + { + "desc" : "Cobalt 9", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) Cobalt/9.0-qa (unlike Gecko) Starboard/4", + "expect" : { + "name" : "Cobalt", + "version": "9.0", + "major" : "9" + } } ] From 7f71024161399b7aa5d5cd10dba9e059f0218262 Mon Sep 17 00:00:00 2001 From: Riley Shaw Date: Wed, 26 Oct 2022 13:17:33 -0400 Subject: [PATCH 071/104] Fix documentation `readme.md` refers to a `parser.getResults` function, which does not exist. This PR corrects the function name to `getResult`. --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 185a2f9c4..71bb1879d 100644 --- a/readme.md +++ b/readme.md @@ -36,7 +36,7 @@ Like so: ```js let parser = new UAParser("user-agent"); // you need to pass the user-agent for nodejs console.log(parser); // {} -let parserResults = parser.getResults(); +let parserResults = parser.getResult(); console.log(parserResults); /** { "ua": "", @@ -48,7 +48,7 @@ console.log(parserResults); } */ ``` -When you call UAParser without the `new` keyword, it will automatically call `getResults()` function and return the parsed results. +When you call UAParser without the `new` keyword, it will automatically call `getResult()` function and return the parsed results. * `UAParser([uastring][,extensions])` * returns result object `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }` From 6fde0d92d60752821f214394f337259589b3187e Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Tue, 8 Nov 2022 15:08:50 +0100 Subject: [PATCH 072/104] Support Panasonic Viera Smart TVs --- src/ua-parser.js | 68 ++++++++++++++++++++++++------------------ test/browser-test.json | 10 +++++++ test/device-test.json | 9 ++++++ test/os-test.json | 9 ++++++ 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index b47ad2364..5faa66c67 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -53,9 +53,11 @@ MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', OPERA = 'Opera', + PANASONIC = 'Panasonic', SAMSUNG = 'Samsung', SHARP = 'Sharp', SONY = 'Sony', + VIERA = 'Viera', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', FACEBOOK = 'Facebook'; @@ -295,6 +297,8 @@ / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, CHROME+' WebView'], VERSION], [ + /Panasonic;(VIERA)/i // Panasonic Viera + ], [[NAME, VIERA]], [ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser ], [VERSION, [NAME, 'Android '+BROWSER]], [ @@ -367,6 +371,35 @@ device : [[ + /////////////////// + // SMARTTVS + /////////////////// + + /smart-tv.+(samsung)/i // Samsung + ], [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 + ], [[VENDOR, LG], [TYPE, SMARTTV]], [ + /(apple) ?tv/i // Apple TV + ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ + /crkey/i // Google Chromecast + ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ + /droid.+aft(\w)( bui|\))/i // Fire TV + ], [MODEL, [VENDOR, AMAZON], [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 + ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ + /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku + /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices + ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ + /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors + ], [[TYPE, SMARTTV]], [ + ////////////////////////// // MOBILES & TABLETS // Ordered by popularity @@ -601,35 +634,6 @@ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [ - /////////////////// - // SMARTTVS - /////////////////// - - /smart-tv.+(samsung)/i // Samsung - ], [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 - ], [[VENDOR, LG], [TYPE, SMARTTV]], [ - /(apple) ?tv/i // Apple TV - ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ - /crkey/i // Google Chromecast - ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ - /droid.+aft(\w)( bui|\))/i // Fire TV - ], [MODEL, [VENDOR, AMAZON], [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 - ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ - /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku - /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices - ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors - ], [[TYPE, SMARTTV]], [ - /////////////////// // WEARABLES /////////////////// @@ -729,10 +733,16 @@ /(cros) [\w]+ ([\w\.]+\w)/i // Chromium OS ], [[NAME, 'Chromium OS'], VERSION],[ + // Smart TVs + /Panasonic;VIERA/i // Panasonic Viera + ], [[NAME, VIERA]], [ + + // Console /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) + // Other /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm /(mint)[\/\(\) ]?(\w*)/i, // Mint diff --git a/test/browser-test.json b/test/browser-test.json index bf8163a1f..4db45f058 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1278,6 +1278,16 @@ "major" : "1" } }, + { + "desc" : "Viera", + "ua" : "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", + "expect" : + { + "name" : "Viera", + "version" : "undefined", + "major" : "undefined" + } + }, { "desc" : "Yandex", "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.5 (KHTML, like Gecko) YaBrowser/1.0.1084.5402 Chrome/19.0.1084.5402 Safari/536.5", diff --git a/test/device-test.json b/test/device-test.json index bad1e50af..235b0e605 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1431,6 +1431,15 @@ "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": "Philips SmartTV", "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", diff --git a/test/os-test.json b/test/os-test.json index 57a4d8a95..b7b78fec5 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -1043,6 +1043,15 @@ "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" : "HP-UX", "ua" : "Mozilla/5.0 (X11; U; HP-UX 9000/785; es-ES; rv:1.0.1) Gecko/20020827 Netscape/7.0", From 5fd47ee00d4aa01838da870b6fcf965812622291 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Tue, 8 Nov 2022 15:26:12 +0100 Subject: [PATCH 073/104] Support Panasonic 2018+ smart tvs --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 5faa66c67..f825fafff 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -395,7 +395,7 @@ /(mitv-\w{5}) bui/i // Xiaomi ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku - /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices + /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 ], [[TYPE, SMARTTV]], [ diff --git a/test/device-test.json b/test/device-test.json index 235b0e605..d6525f20a 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1440,6 +1440,15 @@ "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": "Philips SmartTV", "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", From 98096f14548d12befbb49555447aae953b65d074 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Tue, 8 Nov 2022 15:28:14 +0100 Subject: [PATCH 074/104] Add test for panasonic 2020 smart tv --- test/device-test.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/device-test.json b/test/device-test.json index d6525f20a..154b20e91 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1449,6 +1449,15 @@ "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": "Philips SmartTV", "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", From 8ffdf232f488a6f59733241ba177538882c8189f Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Tue, 8 Nov 2022 15:30:54 +0100 Subject: [PATCH 075/104] Add test for panasonic SAT receiver --- test/device-test.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/device-test.json b/test/device-test.json index 154b20e91..69323c332 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1458,6 +1458,15 @@ "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", From db5567d61487a9940aeceb25eba68bacc1286df4 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Tue, 8 Nov 2022 15:56:40 +0100 Subject: [PATCH 076/104] Support Loewe Smart TVs --- src/ua-parser.js | 5 ++++- test/device-test.json | 9 +++++++++ test/os-test.json | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index f825fafff..c9d8655bf 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -52,6 +52,7 @@ LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', + NETRANGE= 'Netrange', OPERA = 'Opera', PANASONIC = 'Panasonic', SAMSUNG = 'Samsung', @@ -734,8 +735,10 @@ ], [[NAME, 'Chromium OS'], VERSION],[ // Smart TVs - /Panasonic;VIERA/i // Panasonic Viera + /Panasonic;VIERA/i // Panasonic Viera ], [[NAME, VIERA]], [ + /NETRANGEMMH/i // Netrange + ], [[NAME, NETRANGE]], [ // Console diff --git a/test/device-test.json b/test/device-test.json index 69323c332..f4e4c5b03 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -970,6 +970,15 @@ "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", diff --git a/test/os-test.json b/test/os-test.json index b7b78fec5..006504cbf 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -1052,6 +1052,15 @@ "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" : "HP-UX", "ua" : "Mozilla/5.0 (X11; U; HP-UX 9000/785; es-ES; rv:1.0.1) Gecko/20020827 Netscape/7.0", From a8a4e71345b22f7ba0fce024426d046a5da3183c Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Tue, 8 Nov 2022 16:17:57 +0100 Subject: [PATCH 077/104] Add tests for JVC smart tvs --- test/device-test.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/device-test.json b/test/device-test.json index f4e4c5b03..dd2111a49 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -790,6 +790,24 @@ "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": "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", From 528e7aea1cd1a300043e00f0a7299edc348e3afc Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Wed, 9 Nov 2022 11:03:13 +0100 Subject: [PATCH 078/104] Support philips smart tvs --- src/ua-parser.js | 3 +++ test/device-test.json | 27 +++++++++++++++++++++++++++ test/os-test.json | 9 +++++++++ 3 files changed, 39 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index c9d8655bf..d8068a0b2 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -53,6 +53,7 @@ MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', NETRANGE= 'Netrange', + NETTV = 'NetTV', OPERA = 'Opera', PANASONIC = 'Panasonic', SAMSUNG = 'Samsung', @@ -739,6 +740,8 @@ ], [[NAME, VIERA]], [ /NETRANGEMMH/i // Netrange ], [[NAME, NETRANGE]], [ + /nettv\/(\d\.\d.\d)/i // NetTV + ], [VERSION, [NAME, NETTV]], [ // Console diff --git a/test/device-test.json b/test/device-test.json index dd2111a49..136b61e0f 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1503,6 +1503,33 @@ "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": "Roku", "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", diff --git a/test/os-test.json b/test/os-test.json index 006504cbf..e5b13c27f 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -1061,6 +1061,15 @@ "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", From e5942dc505ac219872e0da384dd8e4fbe6a738b6 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Thu, 10 Nov 2022 09:07:08 +0100 Subject: [PATCH 079/104] Add samsung testcases --- test/device-test.json | 9 +++++++++ test/os-test.json | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/test/device-test.json b/test/device-test.json index 136b61e0f..fbdc9f4bf 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1809,6 +1809,15 @@ "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", diff --git a/test/os-test.json b/test/os-test.json index e5b13c27f..3408ddd9d 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -197,6 +197,15 @@ "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)", From df7551c9b69d067cb2a14c91849f0c8715c0af86 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Thu, 10 Nov 2022 11:20:31 +0100 Subject: [PATCH 080/104] Add support for TechniSAT TVs and SATs --- src/ua-parser.js | 2 ++ test/device-test.json | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index d8068a0b2..d3895e064 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -396,6 +396,8 @@ ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ /(mitv-\w{5}) 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]], [ diff --git a/test/device-test.json b/test/device-test.json index fbdc9f4bf..fbcc5441f 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -2045,6 +2045,26 @@ "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": "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", From a88660493568d6144a551424a8139d6c876635f6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 6 Dec 2022 09:53:54 +0700 Subject: [PATCH 081/104] Fix #605 - Identify Macintosh as Apple device --- src/ua-parser.js | 2 ++ test/device-test.json | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index e2c326364..b050833e7 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -390,6 +390,8 @@ /applecoremedia\/[\w\.]+ \((ipad)/i, /\b(ipad)\d\d?,\d\d?[;\]].+ios/i ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ + /(macintosh);/i + ], [MODEL, [VENDOR, APPLE]], [ // Huawei /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i diff --git a/test/device-test.json b/test/device-test.json index bad1e50af..33bfd1717 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -754,6 +754,15 @@ "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": "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", From a6140a17dd0300a35cfc9cff999545f267889411 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 20 Jan 2023 15:03:31 +0700 Subject: [PATCH 082/104] Remove unsafe regex in trim() function `trim()` function contains a regular expression that is vulnerable to ReDoS but was uncaught by `safe-regex` module. --- src/ua-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index b050833e7..9e3c71518 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -93,7 +93,7 @@ }, trim = function (str, len) { if (typeof(str) === STR_TYPE) { - str = str.replace(/^\s\s*/, EMPTY).replace(/\s\s*$/, EMPTY); + str = str.replace(/^\s\s*/, EMPTY); return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); } }; From f2d0db001d87da15de7b9b1df7be9f2eacefd8c5 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 22 Jan 2023 22:26:12 +0700 Subject: [PATCH 083/104] Bump version 0.7.33 --- bower.json | 2 +- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index a4a06b220..c59773a0e 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.32", + "version": "0.7.33", "authors": [ "Faisal Salman " ], diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index d5869863f..9c3f2682a 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.31 +/* UAParser.js v0.7.33 Copyright © 2012-2021 Faisal Salman MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.31",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",EMBEDDED="embedded",UA_MAX_LENGTH=350;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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="0.7.33",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",EMBEDDED="embedded",UA_MAX_LENGTH=350;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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.pack.js b/dist/ua-parser.pack.js index 18c0cdcd6..015018ae2 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.31 +/* UAParser.js v0.7.33 Copyright © 2012-2021 Faisal Salman MIT License */ -!function(r,d){"use strict";function i(i){for(var e={},o=0;o (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index 9e3c71518..8e3de1c2e 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v0.7.32 +/* UAParser.js v0.7.33 Copyright © 2012-2021 Faisal Salman MIT License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.7.32', + var LIBVERSION = '0.7.33', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From cf093222e5a2dbdff1855539144e457c9c47a9d1 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 24 Jan 2023 00:42:40 +0700 Subject: [PATCH 084/104] Fix #557 #612 #629 - Update the changelog --- changelog.md | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 05fc6b90b..addaff4d3 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,49 @@ # UAParser.js Changelog -## Version 0.8.0 \ No newline at end of file +# Version 0.7 / 1.0 + +Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://github.com/faisalman/ua-parser-js/issues/536) for the reason behind this confusion. + +## Version 0.7.30 / 1.0.1 + +- Add new browser : Obigo, UP.Browser, Klar +- Add new device : Oculus, Roku +- Add new OS: Maemo, HP-UX, Android-x86, Deepin, elementary OS, GhostBSD, Linspire, Manjaro, Sabayon +- Improve detection for Sony Xperia 1ii, LG Android TV, and some more devices +- Improve detection for ARM64 CPU +- Improve detection for Windows Mobile, Netscape, Mac on PowerPC +- Categorize PDA as mobile +- Fix Sharp devices misjudged as Huawei +- Fix trailing comma for ES3 compatibility +- Some code refactor + +## Version 0.7.31 / 1.0.2 + +- Fix OPPO Reno A5 incorrect detection +- Fix TypeError Bug +- Use AST to extract regexes and verify them with safe-regex + +## Version 0.7.32 / 1.0.32 + +- Add new browser : DuckDuckGo, Huawei Browser, LinkedIn +- Add new OS : HarmonyOS +- Add some Huawei models +- Add Sharp Aquos TV +- Improve detection Xiaomi Mi CC9 +- Fix Sony Xperia 1 III misidentified as Acer tablet +- Fix Detect Sony BRAVIA as SmartTV +- Fix Detect Xiaomi Mi TV as SmartTV +- Fix Detect Galaxy Tab S8 as tablet +- Fix WeGame mistakenly identified as WeChat +- Fix included commas in Safari / Mobile Safari version +- Increase UA_MAX_LENGTH to 350 + +## Version 0.7.33 / 1.0.33 + +- Add new browser : Cobalt +- Identify Macintosh as an Apple device +- Fix ReDoS vulnerability + +# 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 From 5d4ca2b4c2fec8d07218726b0bbc97abfc6c6323 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 24 Jan 2023 23:28:03 +0700 Subject: [PATCH 085/104] Fix #621 - Detect Oculus Quest Pro --- src/ua-parser.js | 2 +- test/device-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 9e3c71518..31bc93ae1 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -645,7 +645,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ - /(quest( 2)?)/i // Oculus Quest + /(quest( 2| pro)?)/i // Oculus Quest ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ /////////////////// diff --git a/test/device-test.json b/test/device-test.json index 33bfd1717..bb2952866 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1206,6 +1206,15 @@ "type": "wearable" } }, + { + "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": "wearable" + } + }, { "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", From 1a521b867ff5b23d2a75eb5d62e10e22d78998ee Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 25 Jan 2023 01:05:50 +0700 Subject: [PATCH 086/104] Utilize navigator.userAgentData as a fallback #588 --- src/ua-parser.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index 31bc93ae1..1ea234401 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -775,6 +775,7 @@ } var _ua = ua || ((typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); + var _uach = (typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgentData) ? window.navigator.userAgentData : undefined; var _rgxmap = extensions ? extend(regexes, extensions) : regexes; this.getBrowser = function () { @@ -797,6 +798,9 @@ _device[MODEL] = undefined; _device[TYPE] = undefined; rgxMapper.call(_device, _ua, _rgxmap.device); + if (!_device[TYPE] && _uach && _uach.mobile) { + _device[TYPE] = MOBILE; + } return _device; }; this.getEngine = function () { @@ -811,6 +815,9 @@ _os[NAME] = undefined; _os[VERSION] = undefined; rgxMapper.call(_os, _ua, _rgxmap.os); + if (!_os[NAME] && _uach && _uach.platform != 'Unknown') { + _os[NAME] = _uach.platform.replace(/chrome/i, 'Chromium').replace(/mac/i, 'Mac '); + } return _os; }; this.getResult = function () { From ba0f25c19dcdc7fb41e49b271611536d9fa7b6cf Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 26 Jan 2023 09:35:54 +0700 Subject: [PATCH 087/104] Improve Kakao/Naver detection + add test --- src/ua-parser.js | 16 ++++----------- test/browser-test.json | 45 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 25afb6398..34cabc461 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -58,9 +58,7 @@ SONY = 'Sony', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', - FACEBOOK = 'Facebook', - KAKAO = 'Kakao', - NAVER = 'Naver'; + FACEBOOK = 'Facebook'; /////////// // Helper @@ -226,10 +224,6 @@ /\bopr\/([\w\.]+)/i // Opera Webkit ], [VERSION, [NAME, OPERA]], [ - /Safari\/([-\w\.]+).+NAVER\((.*)\)/i, // Naver InApp for iOS - /whale\/([-\w\.]+).+NAVER\((.*)\)/i // Naver InApp Android - ], [VERSION,[NAME, /(.+); (.+); [0-9]+;.+/i, NAVER+' $1 $2']], [ - // Mixed /(kindle)\/([\w\.]+)/i, // Kindle /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer @@ -239,7 +233,7 @@ /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer // 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|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ @@ -290,6 +284,8 @@ // WebView /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android ], [[NAME, FACEBOOK], VERSION], [ + /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App + /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram @@ -297,10 +293,6 @@ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ - /AppleWebKit\/([\w\.]+).+kakao(.*)\s+/i, // Kakao App for iOS - / wv\).+chrome\/([\w\.]+).+kakao(.+)\//i // Kakao App for Android - ], [VERSION, [NAME, /(.+)/i, KAKAO+'$1']], [ - /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME+' Headless']], [ diff --git a/test/browser-test.json b/test/browser-test.json index 2be58c21b..08f8489c0 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1627,5 +1627,50 @@ "version": "9.0", "major" : "9" } + }, + { + "desc" : "KakaoTalk App Android", + "ua" : "Mozilla/5.0 (Linux; Android 12; SM-G988N Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.79 Mobile Safari/537.36;KAKAOTALK 2409760", + "expect" : { + "name" : "KAKAOTALK", + "version": "2409760", + "major" : "2409760" + } + }, + { + "desc" : "KakaoStory App Android", + "ua" : "Mozilla/5.0 (Linux; Android 12; SM-G988N Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.79 Mobile Safari/537.36 KAKAOSTORY/6.8.3_21046", + "expect" : { + "name" : "KAKAOSTORY", + "version": "6.8.3_21046", + "major" : "6" + } + }, + { + "desc" : "KakaoTalk App iOS", + "ua" : "Mozilla/5.0 (iPhone; CPU; iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 BizWebView KAKAOTALK 9.7.6", + "expect" : { + "name" : "KAKAOTALK", + "version": "9.7.6", + "major" : "9" + } + }, + { + "desc" : "Naver App Android", + "ua" : "Mozilla/5.0 (Linux; Android 12; SM-G988N Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/90.0.4430.232 Whale/1.0.0.0 Crosswalk/26.90.3.21 Mobile Safari/537.36 NAVER(inapp; search; 1010; 11.11.2)", + "expect" : { + "name" : "NAVER", + "version": "11.11.2", + "major" : "11" + } + }, + { + "desc" : "Naver App iOS", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/605.1 NAVER(inapp; search; 720; 10.25.0; 11PRO)", + "expect" : { + "name" : "NAVER", + "version": "10.25.0", + "major" : "10" + } } ] From 0b0c7ff6171249f94cafbac4153ae9b9ea704e1f Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 26 Jan 2023 10:26:38 +0700 Subject: [PATCH 088/104] Fix #619 - Move Sharp up to be checked before Huawei --- src/ua-parser.js | 9 ++++----- test/device-test.json | 9 +++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 34cabc461..99f75077a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -375,7 +375,6 @@ ////////////////////////// // MOBILES & TABLETS - // Ordered by popularity ///////////////////////// // Samsung @@ -396,6 +395,10 @@ /(macintosh);/i ], [MODEL, [VENDOR, APPLE]], [ + // Sharp + /\b(sh-?[altvz]?\d\d[a-ekm]?)/i + ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ + // Huawei /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ @@ -511,10 +514,6 @@ /\bmz-([-\w]{2,})/i ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ - // Sharp - /\b(sh-?[altvz]?\d\d[a-ekm]?)/i - ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ - // MIXED /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron diff --git a/test/device-test.json b/test/device-test.json index bb2952866..08874210a 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1764,6 +1764,15 @@ "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", From 0cbeb7a82966aac71e7cadb4794669dabd339868 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 26 Jan 2023 14:03:48 +0700 Subject: [PATCH 089/104] Rearrange the recently added smarttv detection --- readme.md | 36 +++++++++--------- src/ua-parser.js | 83 +++++++++++++++++++----------------------- test/browser-test.json | 2 +- test/device-test.json | 9 +++++ test/os-test.json | 6 +-- 5 files changed, 68 insertions(+), 68 deletions(-) diff --git a/readme.md b/readme.md index 71bb1879d..436f038ea 100644 --- a/readme.md +++ b/readme.md @@ -80,19 +80,19 @@ The methods are self explanatory, here's a small overview on all the available m # Possible 'browser.name': 2345Explorer, 360 Browser, Amaya, Android Browser, Arora, Avant, Avast, AVG, BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, -Chrome Headless, Chrome WebView, Chrome, Chromium, Comodo Dragon, Dillo, +Chrome Headless, Chrome WebView, Chrome, Chromium, Cobalt, Comodo Dragon, Dillo, Dolphin, Doris, DuckDuckGo, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, Firebird, Firefox [Focus/Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, -Iridium, Iron, Jasmine, K-Meleon, Kindle, Klar, Konqueror, LBBROWSER, Line, -LinkedIn, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, Maemo, Maxthon, -MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, NetSurf, Netfront, -Netscape, NokiaBrowser, Obigo, Oculus Browser, OmniWeb, Opera Coast, -Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, Polaris, Puffin, QQ, -QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, Sailfish Browser, -Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, SlimBrowser, Swiftfox, -Tesla, Tizen Browser, UCBrowser, UP.Browser, Vivaldi, Waterfox, WeChat, Weibo, -Yandex, baidu, iCab, w3m, Whale Browser... +Iridium, Iron, Jasmine, Kakao[Story/Talk], K-Meleon, Kindle, Klar, Konqueror, +LBBROWSER, Line, LinkedIn, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, +Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, +NetSurf, Netfront, Netscape, NokiaBrowser, Obigo, Oculus Browser, OmniWeb, +Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, Polaris, +Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, +Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, +SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, UP.Browser, Viera, +Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically ``` @@ -113,10 +113,10 @@ console, mobile, tablet, smarttv, wearable, embedded # Possible 'device.vendor': Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, -Essential, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Lenovo, LG, -Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, OPPO, Ouya, -Palm, Panasonic, Pebble, Polytron, Realme, RIM, Roku, Samsung, Sharp, Siemens, -Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... +Essential, Facebook, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, +Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, +OPPO, Ouya, Palm, Panasonic, Pebble, Polytron, Realme, RIM, Roku, Samsung, Sharp, +Siemens, Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... # 'device.model' determined dynamically ``` @@ -141,10 +141,10 @@ AIX, Amiga OS, Android[-x86], Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS, Contiki, Fedora, Firefox OS, FreeBSD, Debian, Deepin, DragonFly, elementary OS, Fuchsia, Gentoo, GhostBSD, GNU, Haiku, HarmonyOS, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linspire,Linux, Mac OS, Maemo, Mageia, Mandriva, Manjaro, MeeGo, Minix, -Mint, Morph OS, NetBSD, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, PCLinuxOS, -Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, RISC OS, Sabayon, -Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, Ubuntu, Unix, -VectorLinux, WebOS, Windows [Phone/Mobile], Zenwalk, ... +Mint, Morph OS, NetBSD, NetRange, NetTV, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, +PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, +RISC OS, Sabayon, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, +Ubuntu, Unix, VectorLinux, Viera, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 45ebee3fc..ec23bc94d 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -52,10 +52,7 @@ LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', - NETRANGE= 'Netrange', - NETTV = 'NetTV', OPERA = 'Opera', - PANASONIC = 'Panasonic', SAMSUNG = 'Samsung', SHARP = 'Sharp', SONY = 'Sony', @@ -302,8 +299,6 @@ / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, CHROME+' WebView'], VERSION], [ - /Panasonic;(VIERA)/i // Panasonic Viera - ], [[NAME, VIERA]], [ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser ], [VERSION, [NAME, 'Android '+BROWSER]], [ @@ -338,7 +333,8 @@ // Other /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser - /(links) \(([\w\.]+)/i // Links + /(links) \(([\w\.]+)/i, // Links + /panasonic;(viera)/i // Panasonic Viera ], [NAME, VERSION], [ /(cobalt)\/([\w\.]+)/i // Cobalt @@ -379,37 +375,6 @@ device : [[ - /////////////////// - // SMARTTVS - /////////////////// - - /smart-tv.+(samsung)/i // Samsung - ], [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 - ], [[VENDOR, LG], [TYPE, SMARTTV]], [ - /(apple) ?tv/i // Apple TV - ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ - /crkey/i // Google Chromecast - ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ - /droid.+aft(\w)( bui|\))/i // Fire TV - ], [MODEL, [VENDOR, AMAZON], [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 - ], [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 - ], [[TYPE, SMARTTV]], [ - ////////////////////////// // MOBILES & TABLETS ///////////////////////// @@ -539,7 +504,7 @@ // ZTE /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, - /(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony + /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ // Acer @@ -631,6 +596,37 @@ /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [ + /////////////////// + // SMARTTVS + /////////////////// + + /smart-tv.+(samsung)/i // Samsung + ], [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 + ], [[VENDOR, LG], [TYPE, SMARTTV]], [ + /(apple) ?tv/i // Apple TV + ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ + /crkey/i // Google Chromecast + ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ + /droid.+aft(\w)( bui|\))/i // Fire TV + ], [MODEL, [VENDOR, AMAZON], [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 + ], [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 + ], [[TYPE, SMARTTV]], [ + /////////////////// // CONSOLES /////////////////// @@ -745,19 +741,14 @@ ], [[NAME, 'Chromium OS'], VERSION],[ // Smart TVs - /Panasonic;VIERA/i // Panasonic Viera - ], [[NAME, VIERA]], [ - /NETRANGEMMH/i // Netrange - ], [[NAME, NETRANGE]], [ - /nettv\/(\d\.\d.\d)/i // NetTV - ], [VERSION, [NAME, NETTV]], [ - + /panasonic;(viera)/i, // Panasonic Viera + /(netrange)mmh/i, // Netrange + /(nettv)\/(\d+\.[\w\.]+)/i, // NetTV // Console /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) - // Other /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm /(mint)[\/\(\) ]?(\w*)/i, // Mint diff --git a/test/browser-test.json b/test/browser-test.json index 440e4d4a7..ef0cb34f2 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1283,7 +1283,7 @@ "ua" : "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", "expect" : { - "name" : "Viera", + "name" : "VIERA", "version" : "undefined", "major" : "undefined" } diff --git a/test/device-test.json b/test/device-test.json index 8dcb4d0cc..4f44e84b4 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1476,6 +1476,15 @@ "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;)", diff --git a/test/os-test.json b/test/os-test.json index 3408ddd9d..e18d80861 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -1057,7 +1057,7 @@ "ua" : "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", "expect" : { - "name" : "Viera", + "name" : "VIERA", "version" : "undefined" } }, @@ -1066,7 +1066,7 @@ "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", + "name" : "NETRANGE", "version" : "undefined" } }, @@ -1075,7 +1075,7 @@ "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", + "name" : "NETTV", "version" : "3.2.1" } }, From f815ca6e9cabce4099103b21423d7a9c4531c57a Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Thu, 26 Jan 2023 14:58:53 +0700 Subject: [PATCH 090/104] Fix #620 - Add new Device: Kobo --- readme.md | 2 +- src/ua-parser.js | 1 + test/device-test.json | 20 +++++++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 436f038ea..a45e17e89 100644 --- a/readme.md +++ b/readme.md @@ -113,7 +113,7 @@ console, mobile, tablet, smarttv, wearable, embedded # Possible 'device.vendor': Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell, -Essential, Facebook, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, +Essential, Facebook, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Kobo, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus, OPPO, Ouya, Palm, Panasonic, Pebble, Polytron, Realme, RIM, Roku, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ... diff --git a/src/ua-parser.js b/src/ua-parser.js index ec23bc94d..4a22f671c 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -527,6 +527,7 @@ /(oppo) ?([\w ]+) bui/i // OPPO ], [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 diff --git a/test/device-test.json b/test/device-test.json index 4f44e84b4..f042a17db 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -817,6 +817,24 @@ "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", @@ -826,7 +844,7 @@ "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": { From f8e5a1fb4fbe55b781a48d7d141fdc41ba93fa38 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Tue, 31 Jan 2023 15:09:14 +0700 Subject: [PATCH 091/104] Fix #601 - Detect Chrome OS without version --- src/ua-parser.js | 2 +- test/os-test.json | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 031faa362..ac7cbd3cb 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -738,7 +738,7 @@ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast ], [VERSION, [NAME, CHROME+'cast']], [ - /(cros) [\w]+ ([\w\.]+\w)/i // Chromium OS + /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS ], [[NAME, 'Chromium OS'], VERSION],[ // Smart TVs diff --git a/test/os-test.json b/test/os-test.json index e18d80861..20670158d 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -665,6 +665,15 @@ "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" : "Chromium 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", From 73c25771dcd152d415bedb5c0569bc06f6ff65f2 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 22 Feb 2023 20:52:27 +0700 Subject: [PATCH 092/104] Fix #498 - Detect Brave Browser by checking navigator.brave https://github.com/brave/brave-browser/issues/10165#issuecomment-641128278 (cherry picked from commit 03b0a5afa60d472dfff160185c493cb94f1e0298) --- src/ua-parser.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index ac7cbd3cb..d2c3da29a 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -786,8 +786,9 @@ return new UAParser(ua, extensions).getResult(); } - var _ua = ua || ((typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); - var _uach = (typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgentData) ? window.navigator.userAgentData : undefined; + var _navigator = (typeof window !== UNDEF_TYPE && window.navigator) ? window.navigator : undefined; + var _ua = ua || ((_navigator && _navigator.userAgent) ? _navigator.userAgent : EMPTY); + var _uach = (_navigator && _navigator.userAgentData) ? _navigator.userAgentData : undefined; var _rgxmap = extensions ? extend(regexes, extensions) : regexes; this.getBrowser = function () { @@ -795,7 +796,11 @@ _browser[NAME] = undefined; _browser[VERSION] = undefined; rgxMapper.call(_browser, _ua, _rgxmap.browser); - _browser.major = majorize(_browser.version); + _browser[MAJOR] = majorize(_browser[VERSION]); + // Brave-specific detection + if (_navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) { + _browser[NAME] = 'Brave'; + } return _browser; }; this.getCPU = function () { From 097f736c4d6913312880810d8452b775ec2fa020 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 24 Feb 2023 14:25:30 +0700 Subject: [PATCH 093/104] Fix #387 #554 - Detect iPadOS 13 https://stackoverflow.com/questions/9038625/detect-if-device-is-ios (cherry picked from commit 5ea9f0ec16fcbe53f59e5d3a95d237e179a0539c) --- src/ua-parser.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index d2c3da29a..66bf103f4 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -59,7 +59,9 @@ VIERA = 'Viera', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', - FACEBOOK = 'Facebook'; + FACEBOOK = 'Facebook', + CHROMIUM_OS = 'Chromium OS', + MAC_OS = 'Mac OS'; /////////// // Helper @@ -715,7 +717,7 @@ ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ /(mac os x) ?([\w\. ]*)/i, /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS - ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ + ], [[NAME, MAC_OS], [VERSION, /_/g, '.']], [ // Mobile OSes /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS @@ -739,7 +741,7 @@ /crkey\/([\d\.]+)/i // Google Chromecast ], [VERSION, [NAME, CHROME+'cast']], [ /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS - ], [[NAME, 'Chromium OS'], VERSION],[ + ], [[NAME, CHROMIUM_OS], VERSION],[ // Smart TVs /panasonic;(viera)/i, // Panasonic Viera @@ -818,6 +820,11 @@ if (!_device[TYPE] && _uach && _uach.mobile) { _device[TYPE] = MOBILE; } + // iPadOS-specific detection: identified as Mac, but has some iOS-only properties + if (_device[MODEL] == 'Macintosh' && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) { + _device[MODEL] = 'iPad'; + _device[TYPE] = TABLET; + } return _device; }; this.getEngine = function () { @@ -833,7 +840,9 @@ _os[VERSION] = undefined; rgxMapper.call(_os, _ua, _rgxmap.os); if (!_os[NAME] && _uach && _uach.platform != 'Unknown') { - _os[NAME] = _uach.platform.replace(/chrome/i, 'Chromium').replace(/mac/i, 'Mac '); + _os[NAME] = _uach.platform + .replace(/chrome os/i, CHROMIUM_OS) + .replace(/macos/i, MAC_OS); // backward compatibility } return _os; }; From 551ad8847403b82f06c8a834d946d7c6ade6e9ad Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 25 Feb 2023 11:41:19 +0700 Subject: [PATCH 094/104] Add new device: Apple Watch, new os: watchOS (cherry picked from commit 18730452f2b40099710613ecbe188d98f4bfad19) --- readme.md | 2 +- src/ua-parser.js | 4 ++++ test/device-test.json | 9 +++++++++ test/os-test.json | 27 +++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index a45e17e89..a9b770598 100644 --- a/readme.md +++ b/readme.md @@ -144,7 +144,7 @@ Linpus, Linspire,Linux, Mac OS, Maemo, Mageia, Mandriva, Manjaro, MeeGo, Minix, Mint, Morph OS, NetBSD, NetRange, NetTV, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, RISC OS, Sabayon, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, -Ubuntu, Unix, VectorLinux, Viera, WebOS, Windows [Phone/Mobile], Zenwalk, ... +Ubuntu, Unix, VectorLinux, Viera, watchOS, WebOS, Windows [Phone/Mobile], Zenwalk, ... # 'os.version' determined dynamically ``` diff --git a/src/ua-parser.js b/src/ua-parser.js index 66bf103f4..4db19e98c 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -650,6 +650,8 @@ /((pebble))app/i // Pebble ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ + /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch + ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [ /droid.+; (glass) \d/i // Google Glass ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i @@ -736,6 +738,8 @@ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS ], [VERSION, [NAME, 'webOS']], [ + /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS + ], [VERSION, [NAME, 'watchOS']], [ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast diff --git a/test/device-test.json b/test/device-test.json index f042a17db..c40361f13 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -763,6 +763,15 @@ "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", diff --git a/test/os-test.json b/test/os-test.json index 20670158d..d97c7ffce 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -764,6 +764,33 @@ "version" : "undefined" } }, + { + "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)", From 3218051f0739a4a7990b06210983917a11da7904 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 5 Mar 2023 20:46:16 +0700 Subject: [PATCH 095/104] Bump version 0.7.34 --- bower.json | 2 +- changelog.md | 50 +++++++++++++++++++++++++----------------- dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- images/51degrees.svg | 19 ++++++++++++++++ package.js | 2 +- package.json | 2 +- readme.md | 29 ++++++++++++++++++++++-- src/ua-parser.js | 4 ++-- 9 files changed, 85 insertions(+), 31 deletions(-) create mode 100644 images/51degrees.svg diff --git a/bower.json b/bower.json index c59773a0e..c1e6aa9ab 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.33", + "version": "0.7.34", "authors": [ "Faisal Salman " ], diff --git a/changelog.md b/changelog.md index addaff4d3..c3120648c 100644 --- a/changelog.md +++ b/changelog.md @@ -4,24 +4,21 @@ Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://github.com/faisalman/ua-parser-js/issues/536) for the reason behind this confusion. -## Version 0.7.30 / 1.0.1 +## Version 0.7.34 / 1.0.34 +- Fix Sharp Mobile detected as Huawei Tablet +- Fix IE8 bug +- Add new devices : Kobo e-Reader, Apple Watch, and some new SmartTV devices +- Add new OS : watchOS +- Improve browser detection : Kakao, Naver, Brave +- Improve device detection : Oculus, iPad +- Improve OS detection : Chrome OS +- Using navigator.userAgentData as fallback for device.type & os.name -- Add new browser : Obigo, UP.Browser, Klar -- Add new device : Oculus, Roku -- Add new OS: Maemo, HP-UX, Android-x86, Deepin, elementary OS, GhostBSD, Linspire, Manjaro, Sabayon -- Improve detection for Sony Xperia 1ii, LG Android TV, and some more devices -- Improve detection for ARM64 CPU -- Improve detection for Windows Mobile, Netscape, Mac on PowerPC -- Categorize PDA as mobile -- Fix Sharp devices misjudged as Huawei -- Fix trailing comma for ES3 compatibility -- Some code refactor - -## Version 0.7.31 / 1.0.2 +## Version 0.7.33 / 1.0.33 -- Fix OPPO Reno A5 incorrect detection -- Fix TypeError Bug -- Use AST to extract regexes and verify them with safe-regex +- Add new browser : Cobalt +- Identify Macintosh as an Apple device +- Fix ReDoS vulnerability ## Version 0.7.32 / 1.0.32 @@ -38,11 +35,24 @@ Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://g - Fix included commas in Safari / Mobile Safari version - Increase UA_MAX_LENGTH to 350 -## Version 0.7.33 / 1.0.33 +## Version 0.7.31 / 1.0.2 -- Add new browser : Cobalt -- Identify Macintosh as an Apple device -- Fix ReDoS vulnerability +- Fix OPPO Reno A5 incorrect detection +- Fix TypeError Bug +- Use AST to extract regexes and verify them with safe-regex + +## Version 0.7.30 / 1.0.1 + +- Add new browser : Obigo, UP.Browser, Klar +- Add new device : Oculus, Roku +- Add new OS: Maemo, HP-UX, Android-x86, Deepin, elementary OS, GhostBSD, Linspire, Manjaro, Sabayon +- Improve detection for Sony Xperia 1ii, LG Android TV, and some more devices +- Improve detection for ARM64 CPU +- Improve detection for Windows Mobile, Netscape, Mac on PowerPC +- Categorize PDA as mobile +- Fix Sharp devices misjudged as Huawei +- Fix trailing comma for ES3 compatibility +- Some code refactor # Version 0.8 diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index 9c3f2682a..ea16c1355 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.33 +/* UAParser.js v0.7.34 Copyright © 2012-2021 Faisal Salman MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.33",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",EMBEDDED="embedded",UA_MAX_LENGTH=350;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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;jUA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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="0.7.34",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",EMBEDDED="embedded",UA_MAX_LENGTH=350;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",VIERA="Viera",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook",CHROMIUM_OS="Chromium OS",MAC_OS="Mac OS";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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){_device[MODEL]="iPad";_device[TYPE]=TABLET}return _device};this.getEngine=function(){var _engine={};_engine[NAME]=undefined;_engine[VERSION]=undefined;rgxMapper.call(_engine,_ua,_rgxmap.engine);return _engine};this.getOS=function(){var _os={};_os[NAME]=undefined;_os[VERSION]=undefined;rgxMapper.call(_os,_ua,_rgxmap.os);if(!_os[NAME]&&_uach&&_uach.platform!="Unknown"){_os[NAME]=_uach.platform.replace(/chrome os/i,CHROMIUM_OS).replace(/macos/i,MAC_OS)}return _os};this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS(),device:this.getDevice(),cpu:this.getCPU()}};this.getUA=function(){return _ua};this.setUA=function(ua){_ua=typeof ua===STR_TYPE&&ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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.pack.js b/dist/ua-parser.pack.js index 015018ae2..d9ee7e6d9 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.33 +/* UAParser.js v0.7.34 Copyright © 2012-2021 Faisal Salman MIT License */ -!function(r,d){"use strict";function i(i){for(var e={},o=0;o + + + + + + + + + + diff --git a/package.js b/package.js index a3bcdb348..9f125b4aa 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'faisalman:ua-parser-js', - version: '0.7.33', + version: '0.7.34', summary: 'Lightweight JavaScript-based user-agent string parser', git: 'https://github.com/faisalman/ua-parser-js.git', documentation: 'readme.md' diff --git a/package.json b/package.json index 7d9877589..2ab201d2a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js", "name": "ua-parser-js", - "version": "0.7.33", + "version": "0.7.34", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/readme.md b/readme.md index a9b770598..29ec887e1 100644 --- a/readme.md +++ b/readme.md @@ -18,6 +18,30 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro * Demo : https://faisalman.github.io/ua-parser-js * Source : https://github.com/faisalman/ua-parser-js +*** + +### From Our Sponsors: + + + + + + + + + + + + + + + +
51degrees↗ @51degrees/ua-parser-js

UAParser.js has been upgraded to detect comprehensive device data based on the User-Agent and User-Agent Client Hints.

This package supports all device types including Apple and Android devices and can be used either in a browser (client-side) or Node.js environment (server-side).

Visit ↗ 51Degrees UAParser to get started.

+
+

On 6 March, we’ll be hosting a demonstration of the 51Degrees UAParser. Register your place for the webinar ↗ here.

+ +--- + # Documentation ### UAParser([user-agent][,extensions]) typeof `user-agent` "string". @@ -312,9 +336,10 @@ console.log(myParser.setUA(myUA).getBrowser()); // {name: "MyBrowser", version: # Development -## Sponsors +## Backers & Sponsors - + + diff --git a/src/ua-parser.js b/src/ua-parser.js index 4db19e98c..7c007d043 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v0.7.33 +/* UAParser.js v0.7.34 Copyright © 2012-2021 Faisal Salman MIT License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.7.33', + var LIBVERSION = '0.7.34', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From ba067bd351040a57957a4f0965816897e0e3ddef Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sat, 18 Mar 2023 18:50:42 +0700 Subject: [PATCH 096/104] Backport - Fix #624 - Detect Amazon Echo (cherry picked from commit df1a1c7bb4f6f8742db4a8185622411e6cd13ad4) --- src/ua-parser.js | 4 +++- test/device-test.json | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 7c007d043..6ca1d13f0 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -480,7 +480,7 @@ // Amazon /(alexa)webm/i, - /(kf[a-z]{2}wi)( bui|\))/i, // Kindle Fire without Silk + /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [ /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone @@ -665,6 +665,8 @@ /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla ], [VENDOR, [TYPE, EMBEDDED]], [ + /(aeobc)\b/i // Echo Dot + ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) diff --git a/test/device-test.json b/test/device-test.json index c40361f13..d23aba1e0 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -1638,6 +1638,33 @@ "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 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", From d41404551f1a6d2ae789f2a2c26b89b3f1f71610 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Mon, 20 Mar 2023 23:36:51 +0700 Subject: [PATCH 097/104] Backport - Fix #519 #521 #616 - Improve iPhone & iOS detection (cherry picked from commit a1d816ae21e18c8debbe5f23657a0ce750290317) --- src/ua-parser.js | 3 ++- test/device-test.json | 11 +++++++++++ test/os-test.json | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 6ca1d13f0..85ab3fed3 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -390,7 +390,7 @@ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ // Apple - /\((ip(?:hone|od)[\w ]*);/i // iPod/iPhone + /(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i // iPod/iPhone ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ /\((ipad);[-\w\),; ]+apple/i, // iPad /applecoremedia\/[\w\.]+ \((ipad)/i, @@ -717,6 +717,7 @@ // iOS/macOS /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS + /ios;fbsv\/([\d\.]+)/i, /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ /(mac os x) ?([\w\. ]*)/i, diff --git a/test/device-test.json b/test/device-test.json index d23aba1e0..a7cb4b73f 100644 --- a/test/device-test.json +++ b/test/device-test.json @@ -3136,6 +3136,17 @@ "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" } }, diff --git a/test/os-test.json b/test/os-test.json index d97c7ffce..641e6f7b2 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -764,6 +764,15 @@ "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" : "watchOS", "ua" : "server-bag [Watch OS,8.4,19S546,Watch3,4]", From 1747707be680c70073bc0cb496ffaacda3314f2b Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 22 Mar 2023 11:18:52 +0700 Subject: [PATCH 098/104] Backport - Fix #678 - Improve Yandex detection (cherry picked from commit 33f02099d1bf2e074446c0608c4fbfcd22371475) --- src/ua-parser.js | 2 +- test/browser-test.json | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 85ab3fed3..97a9f3c35 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -251,7 +251,7 @@ ], [VERSION, [NAME, 'Konqueror']], [ /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11 ], [VERSION, [NAME, 'IE']], [ - /yabrowser\/([\w\.]+)/i // Yandex + /ya(?:search)?browser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, 'Yandex']], [ /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser ], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [ diff --git a/test/browser-test.json b/test/browser-test.json index ef0cb34f2..8e2f225ec 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1298,6 +1298,16 @@ "major" : "1" } }, + { + "desc" : "Yandex", + "ua" : "Mozilla/5.0 (Linux; arm_64; Android 11; M2101K7AG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.125 YaApp_Android/22.70 YaSearchBrowser/22.70 BroPP/1.0 SA/3 Mobile Safari/537.36", + "expect" : + { + "name" : "Yandex", + "version" : "22.70", + "major" : "22" + } + }, { "desc" : "Puffin", "ua" : "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo P2a42 Build/MMB29M; en-us) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Mobile Safari/537.36 Puffin/6.0.8.15804AP", From 3f8b5ba9cf03c2e82dcf96fd91a89c1b314dee3c Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 31 Mar 2023 15:44:08 +0700 Subject: [PATCH 099/104] Backport - Add new browser: Heytap Reference: Commit: 172f57ffea929a663dc26b5facdf3bd035251004 --- src/ua-parser.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 97a9f3c35..826da4a05 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -236,8 +236,9 @@ /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer // 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|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, + /(flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ + /(heytap|ovi)browser\/([\d\.]+)/i, // Heytap/Ovi /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser From bf9ac43328f1d5235cd6e029ac505824a39fc796 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 29 Mar 2023 04:52:26 +0700 Subject: [PATCH 100/104] Backport - Add new engine: LibWeb + Add new OS: SerenityOS (cherry picked from commit a6c85d0148836b3be8b6bb93e80d199d226d41df) --- src/ua-parser.js | 5 +++-- test/engine-test.json | 9 +++++++++ test/os-test.json | 9 +++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 826da4a05..d14fa70ba 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -697,7 +697,8 @@ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna /ekioh(flow)\/([\w\.]+)/i, // Flow /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links - /(icab)[\/ ]([23]\.[\d\.]+)/i // iCab + /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab + /\b(libweb)/i ], [NAME, VERSION], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko @@ -775,7 +776,7 @@ ], [[NAME, 'Solaris'], VERSION], [ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX - /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX + /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS /(unix) ?([\w\.]*)/i // UNIX ], [NAME, VERSION] ] diff --git a/test/engine-test.json b/test/engine-test.json index 6726d27d9..e75e539cc 100644 --- a/test/engine-test.json +++ b/test/engine-test.json @@ -53,6 +53,15 @@ "version" : "4.5.4" } }, + { + "desc" : "LibWeb", + "ua" : "Mozilla/4.0 (SerenityOS; x86) LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb", + "expect" : + { + "name" : "LibWeb", + "version" : "undefined" + } + }, { "desc" : "NetFront", "ua" : "Mozilla/4.0 (PDA; Windows CE/1.0.1) NetFront/3.0", diff --git a/test/os-test.json b/test/os-test.json index 641e6f7b2..7e1e157c8 100644 --- a/test/os-test.json +++ b/test/os-test.json @@ -1204,5 +1204,14 @@ "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" + } } ] From 2e06a34062c196322df7ad3c63fcc66e51c72420 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Wed, 29 Mar 2023 05:51:35 +0700 Subject: [PATCH 101/104] Backport - Add new browser: TikTok (cherry picked from commit 4af26c7a5e446c5f57353a7c22198210a97859e5) --- src/ua-parser.js | 2 ++ test/browser-test.json | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/ua-parser.js b/src/ua-parser.js index d14fa70ba..9a70962f9 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -296,6 +296,8 @@ ], [NAME, VERSION], [ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, 'GSA']], [ + /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok + ], [VERSION, [NAME, 'TikTok']], [ /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME+' Headless']], [ diff --git a/test/browser-test.json b/test/browser-test.json index 8e2f225ec..ff8d1e625 100644 --- a/test/browser-test.json +++ b/test/browser-test.json @@ -1692,5 +1692,32 @@ "version": "10.25.0", "major" : "10" } + }, + { + "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", + "expect" : { + "name" : "TikTok", + "version": "21.9.4", + "major" : "21" + } + }, + { + "desc" : "TikTok", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 14_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 musical_ly_21.1.0 JsSdk/2.0 NetType/4G Channel/App Store ByteLocale/ru Region/RU ByteFullLocale/ru-RU isDarkMode/1 WKWebView/1 BytedanceWebview/d8a21c6", + "expect" : { + "name" : "TikTok", + "version": "21.1.0", + "major" : "21" + } + }, + { + "desc" : "TikTok", + "ua" : "Mozilla/5.0 (Linux; Android 10; STK-LX1 Build/HONORSTK-LX1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/110.0.5481.153 Mobile Safari/537.36 musical_ly_2022803040 JsSdk/1.0 NetType/WIFI Channel/huaweiadsglobal_int AppName/musical_ly app_version/28.3.4 ByteLocale/en ByteFullLocale/en Region/IQ Spark/1.2.7-alpha.8 AppVersion/28.3.4 PIA/1.5.11 BytedanceWebview/d8a21c6", + "expect" : { + "name" : "TikTok", + "version": "28.3.4", + "major" : "28" + } } ] From 5b8adfef7b77494ae73199b7ee3e5dafba46e0a8 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 31 Mar 2023 15:54:22 +0700 Subject: [PATCH 102/104] Backport - Prevent altering the result when supplied user-agent is different from current user-agent Reference: Commit: b09878934fce1de9bcadace72cc3a6fd6c613e34 --- src/ua-parser.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ua-parser.js b/src/ua-parser.js index 9a70962f9..dbcc663e6 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -803,6 +803,7 @@ var _ua = ua || ((_navigator && _navigator.userAgent) ? _navigator.userAgent : EMPTY); var _uach = (_navigator && _navigator.userAgentData) ? _navigator.userAgentData : undefined; var _rgxmap = extensions ? extend(regexes, extensions) : regexes; + var _isSelfNav = _navigator && _navigator.userAgent == _ua; this.getBrowser = function () { var _browser = {}; @@ -811,7 +812,7 @@ rgxMapper.call(_browser, _ua, _rgxmap.browser); _browser[MAJOR] = majorize(_browser[VERSION]); // Brave-specific detection - if (_navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) { + if (_isSelfNav && _navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) { _browser[NAME] = 'Brave'; } return _browser; @@ -828,11 +829,11 @@ _device[MODEL] = undefined; _device[TYPE] = undefined; rgxMapper.call(_device, _ua, _rgxmap.device); - if (!_device[TYPE] && _uach && _uach.mobile) { + if (_isSelfNav && !_device[TYPE] && _uach && _uach.mobile) { _device[TYPE] = MOBILE; } // iPadOS-specific detection: identified as Mac, but has some iOS-only properties - if (_device[MODEL] == 'Macintosh' && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) { + if (_isSelfNav && _device[MODEL] == 'Macintosh' && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) { _device[MODEL] = 'iPad'; _device[TYPE] = TABLET; } @@ -850,7 +851,7 @@ _os[NAME] = undefined; _os[VERSION] = undefined; rgxMapper.call(_os, _ua, _rgxmap.os); - if (!_os[NAME] && _uach && _uach.platform != 'Unknown') { + if (_isSelfNav && !_os[NAME] && _uach && _uach.platform != 'Unknown') { _os[NAME] = _uach.platform .replace(/chrome os/i, CHROMIUM_OS) .replace(/macos/i, MAC_OS); // backward compatibility From 786d502b0140d94be0b2f47e77df6c19fc8fb4d6 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Fri, 31 Mar 2023 17:56:50 +0700 Subject: [PATCH 103/104] Bump version 0.7.35 --- bower.json | 2 +- changelog.md | 9 +++++++++ dist/ua-parser.min.js | 4 ++-- dist/ua-parser.pack.js | 4 ++-- package.js | 2 +- package.json | 2 +- src/ua-parser.js | 4 ++-- 7 files changed, 18 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index c1e6aa9ab..4048f158a 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ua-parser-js", - "version": "0.7.34", + "version": "0.7.35", "authors": [ "Faisal Salman " ], diff --git a/changelog.md b/changelog.md index c3120648c..98c9a10ab 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,15 @@ Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://github.com/faisalman/ua-parser-js/issues/536) for the reason behind this confusion. +## Version 0.7.35 / 1.0.35 +- Fix result from user-supplied user-agent being altered +- Add new browser: Heytap, TikTok +- Add new engine: LibWeb +- Add new OS: SerenityOS +- Improve browser detection: Yandex +- Improve device detection: iPhone, Amazon Echo +- Improve OS detection: iOS + ## Version 0.7.34 / 1.0.34 - Fix Sharp Mobile detected as Huawei Tablet - Fix IE8 bug diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index ea16c1355..f298d7959 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.34 +/* UAParser.js v0.7.35 Copyright © 2012-2021 Faisal Salman MIT License */ -(function(window,undefined){"use strict";var LIBVERSION="0.7.34",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",EMBEDDED="embedded",UA_MAX_LENGTH=350;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",VIERA="Viera",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook",CHROMIUM_OS="Chromium OS",MAC_OS="Mac OS";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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){_device[MODEL]="iPad";_device[TYPE]=TABLET}return _device};this.getEngine=function(){var _engine={};_engine[NAME]=undefined;_engine[VERSION]=undefined;rgxMapper.call(_engine,_ua,_rgxmap.engine);return _engine};this.getOS=function(){var _os={};_os[NAME]=undefined;_os[VERSION]=undefined;rgxMapper.call(_os,_ua,_rgxmap.os);if(!_os[NAME]&&_uach&&_uach.platform!="Unknown"){_os[NAME]=_uach.platform.replace(/chrome os/i,CHROMIUM_OS).replace(/macos/i,MAC_OS)}return _os};this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS(),device:this.getDevice(),cpu:this.getCPU()}};this.getUA=function(){return _ua};this.setUA=function(ua){_ua=typeof ua===STR_TYPE&&ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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="0.7.35",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",EMBEDDED="embedded",UA_MAX_LENGTH=350;var AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",BROWSER="Browser",CHROME="Chrome",EDGE="Edge",FIREFOX="Firefox",GOOGLE="Google",HUAWEI="Huawei",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",OPERA="Opera",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",VIERA="Viera",XIAOMI="Xiaomi",ZEBRA="Zebra",FACEBOOK="Facebook",CHROMIUM_OS="Chromium OS",MAC_OS="Mac OS";var extend=function(regexes,extensions){var mergedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){mergedRegexes[i]=extensions[i].concat(regexes[i])}else{mergedRegexes[i]=regexes[i]}}return mergedRegexes},enumerize=function(arr){var enums={};for(var i=0;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){_device[MODEL]="iPad";_device[TYPE]=TABLET}return _device};this.getEngine=function(){var _engine={};_engine[NAME]=undefined;_engine[VERSION]=undefined;rgxMapper.call(_engine,_ua,_rgxmap.engine);return _engine};this.getOS=function(){var _os={};_os[NAME]=undefined;_os[VERSION]=undefined;rgxMapper.call(_os,_ua,_rgxmap.os);if(_isSelfNav&&!_os[NAME]&&_uach&&_uach.platform!="Unknown"){_os[NAME]=_uach.platform.replace(/chrome os/i,CHROMIUM_OS).replace(/macos/i,MAC_OS)}return _os};this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS(),device:this.getDevice(),cpu:this.getCPU()}};this.getUA=function(){return _ua};this.setUA=function(ua){_ua=typeof ua===STR_TYPE&&ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this};this.setUA(_ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR]);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(typeof window!==UNDEF_TYPE){window.UAParser=UAParser}}var $=typeof window!==UNDEF_TYPE&&(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.pack.js b/dist/ua-parser.pack.js index d9ee7e6d9..a4c9351c6 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v0.7.34 +/* UAParser.js v0.7.35 Copyright © 2012-2021 Faisal Salman MIT License */ -!function(n,l){"use strict";function i(i){for(var e={},o=0;o (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment", "keywords": [ diff --git a/src/ua-parser.js b/src/ua-parser.js index dbcc663e6..081c4a8cb 100755 --- a/src/ua-parser.js +++ b/src/ua-parser.js @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v0.7.34 +/* UAParser.js v0.7.35 Copyright © 2012-2021 Faisal Salman MIT License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. @@ -17,7 +17,7 @@ ///////////// - var LIBVERSION = '0.7.34', + var LIBVERSION = '0.7.35', EMPTY = '', UNKNOWN = '?', FUNC_TYPE = 'function', From 32d326b35b9bdd5c64633a5b05b3573faa6a8dc3 Mon Sep 17 00:00:00 2001 From: Faisal Salman Date: Sun, 2 Apr 2023 06:03:31 +0700 Subject: [PATCH 104/104] Update readme --- readme.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index 29ec887e1..97f602de7 100644 --- a/readme.md +++ b/readme.md @@ -33,10 +33,6 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro

UAParser.js has been upgraded to detect comprehensive device data based on the User-Agent and User-Agent Client Hints.

This package supports all device types including Apple and Android devices and can be used either in a browser (client-side) or Node.js environment (server-side).

Visit ↗ 51Degrees UAParser to get started.

- - -

On 6 March, we’ll be hosting a demonstration of the 51Degrees UAParser. Register your place for the webinar ↗ here.

- @@ -106,16 +102,16 @@ The methods are self explanatory, here's a small overview on all the available m BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera, Chrome Headless, Chrome WebView, Chrome, Chromium, Cobalt, Comodo Dragon, Dillo, Dolphin, Doris, DuckDuckGo, Edge, Electron, Epiphany, Facebook, Falkon, Fennec, -Firebird, Firefox [Focus/Reality], Flock, Flow, GSA, GoBrowser, Huawei Browser, -ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, Instagram, -Iridium, Iron, Jasmine, Kakao[Story/Talk], K-Meleon, Kindle, Klar, Konqueror, -LBBROWSER, Line, LinkedIn, Links, Lunascape, Lynx, MIUI Browser, Maemo Browser, +Firebird, Firefox [Focus/Reality], Flock, Flow, GSA, GoBrowser, Heytap, +Huawei Browser, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon, Iceweasel, +Instagram, Iridium, Iron, Jasmine, Kakao[Story/Talk], K-Meleon, Kindle, Klar, +Konqueror, LBBROWSER, Line, LinkedIn, Links, Lunascape, Lynx, MIUI Browser, Maemo, Maxthon, MetaSr Midori, Minimo, Mobile Safari, Mosaic, Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Obigo, Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, Safari, Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim, -SlimBrowser, Swiftfox, Tesla, Tizen Browser, UCBrowser, UP.Browser, Viera, +SlimBrowser, Swiftfox, Tesla, TikTok, Tizen Browser, UCBrowser, UP.Browser, Viera, Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser... # 'browser.version' determined dynamically @@ -150,8 +146,8 @@ Siemens, Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE ```sh # Possible 'engine.name' -Amaya, Blink, EdgeHTML, Flow, Gecko, Goanna, iCab, KHTML, Links, Lynx, NetFront, -NetSurf, Presto, Tasman, Trident, w3m, WebKit +Amaya, Blink, EdgeHTML, Flow, Gecko, Goanna, iCab, KHTML, LibWeb, Links, Lynx, +NetFront, NetSurf, Presto, Tasman, Trident, w3m, WebKit # 'engine.version' determined dynamically ``` @@ -167,8 +163,9 @@ Fuchsia, Gentoo, GhostBSD, GNU, Haiku, HarmonyOS, HP-UX, Hurd, iOS, Joli, KaiOS, Linpus, Linspire,Linux, Mac OS, Maemo, Mageia, Mandriva, Manjaro, MeeGo, Minix, Mint, Morph OS, NetBSD, NetRange, NetTV, Nintendo, OpenBSD, OpenVMS, OS/2, Palm, PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS, -RISC OS, Sabayon, Sailfish, Series40, Slackware, Solaris, SUSE, Symbian, Tizen, -Ubuntu, Unix, VectorLinux, Viera, watchOS, WebOS, Windows [Phone/Mobile], Zenwalk, ... +RISC OS, Sabayon, Sailfish, SerenityOS, Series40, Slackware, Solaris, SUSE, Symbian, +Tizen, Ubuntu, Unix, VectorLinux, Viera, watchOS, WebOS, Windows [Phone/Mobile], +Zenwalk, ... # 'os.version' determined dynamically ```