diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f1a3b8d..c658b18 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ # Prerequisites -- [ ] I have read and follow the contributing guidelines +- [ ] I have read and follow the [contributing](https://github.com/faisalman/ua-parser-js/blob/master/CONTRIBUTING.md) guidelines - [ ] I have read and accept the [Contributor License Agreement (CLA)](https://gist.github.com/faisalman/2ed16621ebb544157eba85a7f7381417) Document and I hereby sign the CLA # Type of Change diff --git a/.github/workflows/test-ci.yml b/.github/workflows/test-ci.yml index 5c02b3d..f1e262b 100644 --- a/.github/workflows/test-ci.yml +++ b/.github/workflows/test-ci.yml @@ -10,14 +10,19 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - arch: [amd64, ppc64le] + arch: [amd64] + node-version: ['22.13', 'lts/*'] + include: + - arch: ppc64le + node-version: 20 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: 'lts/*' + node-version: ${{ matrix.node-version }} - name: Run the test run: | + echo "Running on ubuntu-latest-${{ matrix.arch }} with node version set as ${{ matrix.node-version }}" npm ci - npx playwright install + npx playwright install --with-deps npm test diff --git a/CHANGELOG.md b/CHANGELOG.md index 0be492a..9f2fa9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,59 @@ --- +## Version 2.0.3 + +- Add new browser: Dooble, Ecosia, LG Browser, Otter, qutebrowser, Surf +- Add new device: BLU, Facebook Portal TV +- Improve device detection: Archos, LG, Meta Quest +- Remove jazzer.js fuzz test +- Improve `withClientHints()`: + - Browser naming adjustments: + - `HuaweiBrowser` => `Huawei Browser` + - `Miui Browser` => `MIUI Browser` + - `OperaMobile` => `Opera Mobi` + - `YaBrowser` => `Yandex` +- `extensions` submodule: + - Add new Crawler: AdIdxBot, Linespider, LinkedInBot, OpenAI Image Downloader, SemrushBot, Yahoo! Slurp + - Add new Fetcher: Better Uptime Bot, Google-PageRenderer, GoogleImageProxy, MicrosoftPreview, Snap URL Preview, SkypeUriPreview, TelegramBot + - Add new Vehicles: BMW, Jeep + - Add OS detection of WhatsApp user-agent + +## Version 2.0.2 + +- Fix TypeScript dependency issue + +## Version 2.0.1 + +- Add new browser: Ladybird, Daum +- Add new device: Apple HomePod +- Add new device vendor: HMD +- Add new OS: Ubuntu Touch, Windows IoT +- Improve CPU detection: ARM, x86 +- Improve device detection: Lenovo, Nokia, Nvidia, Xiaomi + - Tablet: Google, Honor, Huawei, Infinix, Nokia, OnePlus, Xiaomi + - Wearable: Asus, Google, LG, Motorola, OnePlus, Oppo, Samsung, Sony + - Smart-TV: Xiaomi, unidentified vendors + - Improve detection for unknown VR devices + - Improve device model detection for Generic devices +- Improve OS detection: Linux, Symbian +- Improve TypeScript definitions for Headers +- Improve `withClientHints()`: + - `engine.version` also get updated + - Infer `device.vendor` & `device.type` by guessing from `device.model` + - Browser naming adjustments: + - `Google Chrome` => `Chrome` + - `Microsoft Edge` => `Edge` + - `Android WebView` => `Chrome WebView` + - `HeadlessChrome` => `Chrome Headless` +- `enums` submodule: + - Add TypeScript definitions +- `extensions` submodule: + - Add new list: + - `Vehicles`: BYD, Rivian, Volvo + - Add new Fetcher: Bluesky + - Add new Library: Apache-HttpClient, go-http-client, got, GuzzleHttp, Java-http-client, libwww-perl, lua-resty-http, Needle, OkHttp, node-fetch, PHP-SOAP, PostmanRuntime, superagent + ## Version 2.0.0 - `ua-parser-js/extensions` submodule: @@ -166,6 +219,23 @@ --- +## Version 0.7.40 / 1.0.40 +- Add new browser: 115, LibreWolf, Slimboat, Slimjet +- Add new device: Advan, Cat, Energizer, IMO, Micromax, Smartfren +- Add new engine: ArkWeb, Servo +- Add new os: OpenHarmony +- Improve browser detection: 2345, 360, Dragon, Iron, Maxthon +- Recognize Honor as a separate device vendor from Huawei +- Fix Python Request mistakenly identified as Meta Quest + +## Version 0.7.39 / 1.0.39 +- Add new feature: executable command using `npx ua-parser-js "[INSERT-UA-HERE]"` +- Add new browser: Helio, Pico Browser, Wolvic +- Add new device vendor: itel, Nothing, TCL +- Improve browser detection: ICEBrowser, Klar, QQBrowser, Quark, Rekonq, Sleipnir +- Improve device detection: Xiaomi Pro, Amazon Echo Show, Samsung Galaxy Watch +- Removed from browser: Viera + ## Version 0.7.38 / 1.0.38 - Fix error on getOS() when userAgentData.platform is undefined - Add new browser: Opera GX, Twitter @@ -251,4 +321,4 @@ Version 1.0.x is basically the equivalent of version 0.7.x (mirror/duplicate). S ## Version 0.8 -Version 0.8 was created by accident. This version is now deprecated and no longer maintained, please update to version 0.7 / 1.0. \ No newline at end of file +Version 0.8 was created by accident. This version is now deprecated and no longer maintained, please update to version 0.7 / 1.0. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7ac0d6..0bb377b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,4 +4,4 @@ * Make some changes as required * Write unit test to showcase its functionality under `/test` * Run the test suites to make sure it's not breaking anything `$ npm run build+test` -* Submit a pull request under `develop` branch & check the CLA in the submission form \ No newline at end of file +* Submit a pull request & check the CLA in the submission form \ No newline at end of file diff --git a/README.md b/README.md index e02a7c5..5f95380 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ If you have not yet purchased a license, you may do so at https://store.faisalma npm install @ua-parser-js/pro-business ``` + # Documentation https://docs.uaparser.dev @@ -26,4 +27,4 @@ import { UAParser } from '@ua-parser-js/pro-business'; UAParser.js PRO Business -Copyright (c) 2023-2024 Faisal Salman <> \ No newline at end of file +Copyright (c) 2023-2024 Faisal Salman <> diff --git a/dist/ua-parser.min.js b/dist/ua-parser.min.js index a1ddfeb..d28c171 100644 --- a/dist/ua-parser.min.js +++ b/dist/ua-parser.min.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.0 - Copyright © 2012-2023 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman UAParser.js PRO Business License */ -(function(window,undefined){"use strict";var LIBVERSION="2.0.0",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",USER_AGENT="user-agent",UA_MAX_LENGTH=500,BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",CHROME="Chrome",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(defaultRgx,extensions){var mergedRgx={};var extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i in extensions){for(var j in extensions[i]){extraRgx[j]=extensions[i][j].concat(extraRgx[j]?extraRgx[j]:[])}}}for(var k in defaultRgx){mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k]}return mergedRgx},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1:false},isExtensions=function(obj,deep){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):false)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;var i=0,j,k,p,q,matches,match;while(i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length===3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length===4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i in brands){var brandName=strip(/(Google|Microsoft) /,brands[i].brand||brands[i]),brandVersion=brands[i].version;if(!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&!/chromi/i.test(brandName))){this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL])}if(uaCH[MODEL]=="Xbox"){this.set(TYPE,CONSOLE).set(VENDOR,MICROSOFT)}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}if(this.get(NAME)==WINDOWS&&uaCH[MODEL]=="Xbox"){this.set(NAME,"Xbox").set(VERSION,undefined)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua,true)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions,true)){headers=extensions;extensions=undefined}if(headers&&typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[k]=v});headers=kv}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(isString(ua))userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);return this}UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else if(isWindow){window.UAParser=UAParser}}var $=isWindow&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(ua){parser.setUA(ua);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file +(function(window,undefined){"use strict";var LIBVERSION="2.0.3",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(defaultRgx,extensions){var mergedRgx={};var extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i in extensions){for(var j in extensions[i]){extraRgx[j]=extensions[i][j].concat(extraRgx[j]?extraRgx[j]:[])}}}for(var k in defaultRgx){mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k]}return mergedRgx},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1:false},isExtensions=function(obj,deep){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):false)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;var i=0,j,k,p,q,matches,match;while(i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length===3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length===4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:case UA_ENGINE:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}if(this.get(NAME)==WINDOWS&&uaCH[MODEL]=="Xbox"){this.set(NAME,"Xbox").set(VERSION,undefined)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua,true)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions,true)){headers=extensions;extensions=undefined}if(headers&&typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[k]=v});headers=kv}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(isString(ua))userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);return this}UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else if(isWindow){window.UAParser=UAParser}}var $=isWindow&&(window.jQuery||window.Zepto);if($&&!$.ua){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(ua){parser.setUA(ua);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this); \ No newline at end of file diff --git a/dist/ua-parser.min.mjs b/dist/ua-parser.min.mjs new file mode 100644 index 0000000..14ac4fe --- /dev/null +++ b/dist/ua-parser.min.mjs @@ -0,0 +1,4 @@ +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman + UAParser.js PRO Business License */ +var LIBVERSION="2.0.3",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows";var isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:undefined,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:undefined;var extend=function(defaultRgx,extensions){var mergedRgx={};var extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i in extensions){for(var j in extensions[i]){extraRgx[j]=extensions[i][j].concat(extraRgx[j]?extraRgx[j]:[])}}}for(var k in defaultRgx){mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k]}return mergedRgx},enumerize=function(arr){var enums={};for(var i=0;i0){for(var i in str1){if(lowerize(str1[i])==lowerize(str2))return true}return false}return isString(str1)?lowerize(str2).indexOf(lowerize(str1))!==-1:false},isExtensions=function(obj,deep){for(var prop in obj){return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):false)}},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(!header)return undefined;var arr=[];var tokens=strip(/\\?\"/g,header).split(",");for(var i=0;i-1){var token=trim(tokens[i]).split(";v=");arr[i]={brand:token[0],version:token[1]}}else{arr[i]=trim(tokens[i])}}return arr},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:undefined},setProps=function(arr){for(var i in arr){var propName=arr[i];if(typeof propName==OBJ_TYPE&&propName.length==2){this[propName[0]]=propName[1]}else{this[propName]=undefined}}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str)){str=strip(/^\s\s*/,str);return typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)}};var rgxMapper=function(ua,arrays){if(!ua||!arrays)return;var i=0,j,k,p,q,matches,match;while(i0){if(q.length===2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length===3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length===4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},strMapper=function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j2){this.set(MODEL,"iPad").set(TYPE,TABLET)}break;case UA_OS:if(!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]){this.set(NAME,NAVIGATOR_UADATA[PLATFORM])}break;case UA_RESULT:var data=this.data;var detect=function(itemType){return data[itemType].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}}return this};this.parseUA=function(){if(this.itemType!=UA_RESULT){rgxMapper.call(this.data,this.ua,this.rgxMap)}if(this.itemType==UA_BROWSER){this.set(MAJOR,majorize(this.get(VERSION)))}return this};this.parseCH=function(){var uaCH=this.uaCH,rgxMap=this.rgxMap;switch(this.itemType){case UA_BROWSER:case UA_ENGINE:var brands=uaCH[FULLVERLIST]||uaCH[BRANDS],prevName;if(brands){for(var i in brands){var brandName=brands[i].brand||brands[i],brandVersion=brands[i].version;if(this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/chrom/i.test(prevName)&&brandName!=CHROMIUM)){brandName=strMapper(brandName,{Chrome:"Google Chrome",Edge:"Microsoft Edge","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"});this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion));prevName=brandName}if(this.itemType==UA_ENGINE&&brandName==CHROMIUM){this.set(VERSION,brandVersion)}}}break;case UA_CPU:var archName=uaCH[ARCHITECTURE];if(archName){if(archName&&uaCH[BITNESS]=="64")archName+="64";rgxMapper.call(this.data,archName+";",rgxMap)}break;case UA_DEVICE:if(uaCH[MOBILE]){this.set(TYPE,MOBILE)}if(uaCH[MODEL]){this.set(MODEL,uaCH[MODEL]);if(!this.get(TYPE)||!this.get(VENDOR)){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH[MODEL]+")",rgxMap);if(!this.get(TYPE)&&!!reParse.type){this.set(TYPE,reParse.type)}if(!this.get(VENDOR)&&!!reParse.vendor){this.set(VENDOR,reParse.vendor)}}}if(uaCH[FORMFACTORS]){var ff;if(typeof uaCH[FORMFACTORS]!=="string"){var idx=0;while(!ff&&idx=13?"11":"10";this.set(NAME,osName).set(VERSION,osVersion)}if(this.get(NAME)==WINDOWS&&uaCH[MODEL]=="Xbox"){this.set(NAME,"Xbox").set(VERSION,undefined)}break;case UA_RESULT:var data=this.data;var parse=function(itemType){return data[itemType].getItem().setCH(uaCH).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this};setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]);return this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE){if(isExtensions(ua,true)){if(typeof extensions===OBJ_TYPE){headers=extensions}extensions=ua}else{headers=ua;extensions=undefined}ua=undefined}else if(typeof ua===STR_TYPE&&!isExtensions(extensions,true)){headers=extensions;extensions=undefined}if(headers&&typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[k]=v});headers=kv}if(!(this instanceof UAParser)){return new UAParser(ua,extensions,headers).getResult()}var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,true),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){if(itemType==UA_RESULT){return function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}}else{return function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}}};setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua){if(isString(ua))userAgent=ua.length>UA_MAX_LENGTH?trim(ua,UA_MAX_LENGTH):ua;return this}]]).setUA(userAgent);return this}UAParser.VERSION=LIBVERSION;UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]);UAParser.CPU=enumerize([ARCHITECTURE]);UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]);UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);export{UAParser}; \ No newline at end of file diff --git a/dist/ua-parser.pack.js b/dist/ua-parser.pack.js index 7179d2d..b409027 100644 --- a/dist/ua-parser.pack.js +++ b/dist/ua-parser.pack.js @@ -1,4 +1,4 @@ -/* UAParser.js v2.0.0 - Copyright © 2012-2023 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman UAParser.js PRO Business License */ -!function(i,d){"use strict";function e(i){for(var e={},t=0;tC?Ci(i,C):i),this}]]).setUA(r),this}Ui.VERSION="2.0.0",Ui.BROWSER=e([m,v,p,f]),Ui.CPU=e([k]),Ui.DEVICE=e([h,g,f,x,y,t,r,o,s]),Ui.ENGINE=Ui.OS=e([m,v]),typeof exports!==b?(typeof module!==b&&module.exports&&(exports=module.exports=Ui),exports.UAParser=Ui):typeof define===u&&define.amd?define(function(){return Ui}):li&&(i.UAParser=Ui);var ji,Ei=li&&(i.jQuery||i.Zepto);Ei&&!Ei.ua&&(ji=new Ui,Ei.ua=ji.getResult(),Ei.ua.get=function(){return ji.getUA()},Ei.ua.set=function(i){ji.setUA(i);var e,t=ji.getResult();for(e in t)Ei.ua[e]=t[e]})}("object"==typeof window?window:this); \ No newline at end of file +((i,l)=>{function U(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(t in i)o[t]=r[t]&&r[t].length%2==0?r[t].concat(i[t]):i[t];return o})(Ii,e):Ii,j.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Bi(i,r,s,a).set("ua",r).set(u,this.getBrowser()).set(h,this.getCPU()).set(p,this.getDevice()).set(m,this.getEngine()).set(f,this.getOS()).get()}:function(){return new Bi(i,r,s[i],a).parseUA().get()}})(u)],["getCPU",n(h)],["getDevice",n(p)],["getEngine",n(m)],["getOS",n(f)],["getResult",n(g)],["getUA",function(){return r}],["setUA",function(i){return H(i)&&(r=i.length>E?Hi(i,E):i),this}]]).setUA(r),this):new I(i,e,t).getResult()}I.VERSION="2.0.3",I.BROWSER=U([v,y,L,k]),I.CPU=U([C]),I.DEVICE=U([T,x,k,G,S,e,r,t,D]),I.ENGINE=I.OS=U([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=I:exports).UAParser=I:typeof define===R&&define.amd?define(function(){return I}):Ti&&(i.UAParser=I);var Ri,Vi=Ti&&(i.jQuery||i.Zepto);Vi&&!Vi.ua&&(Ri=new I,Vi.ua=Ri.getResult(),Vi.ua.get=function(){return Ri.getUA()},Vi.ua.set=function(i){Ri.setUA(i);var e,t=Ri.getResult();for(e in t)Vi.ua[e]=t[e]})})("object"==typeof window?window:this); \ No newline at end of file diff --git a/dist/ua-parser.pack.mjs b/dist/ua-parser.pack.mjs new file mode 100644 index 0000000..06c44b9 --- /dev/null +++ b/dist/ua-parser.pack.mjs @@ -0,0 +1,4 @@ +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman + UAParser.js PRO Business License */ +function E(i){for(var e={},o=0;o{var o,t={},r=e;if(!_i(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(o in i)t[o]=r[o]&&r[o].length%2==0?r[o].concat(i[o]):i[o];return t})(Ii,e):Ii,M.call(this,[["getBrowser",(n=function(i){return i==f?function(){return new Pi(i,r,s,a).set("ua",r).set(c,this.getBrowser()).set(u,this.getCPU()).set(h,this.getDevice()).set(p,this.getEngine()).set(m,this.getOS()).get()}:function(){return new Pi(i,r,s[i],a).parseUA().get()}})(c)],["getCPU",n(u)],["getDevice",n(h)],["getEngine",n(p)],["getOS",n(m)],["getResult",n(f)],["getUA",function(){return r}],["setUA",function(i){return A(i)&&(r=i.length>B?Ai(i,B):i),this}]]).setUA(r),this):new j(i,e,o).getResult()}j.VERSION="2.0.3",j.BROWSER=E([g,x,C,v]),j.CPU=E([y]),j.DEVICE=E([T,k,v,L,S,i,r,e,F]),j.ENGINE=j.OS=E([g,x]);export{j as UAParser}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7c400f2..4fc93b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ua-parser-js/pro-business", - "version": "2.0.0", + "version": "2.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ua-parser-js/pro-business", - "version": "2.0.0", + "version": "2.0.3", "funding": [ { "type": "opencollective", @@ -23,8 +23,10 @@ ], "license": "SEE LICENSE IN LICENSE.md", "dependencies": { + "@types/node-fetch": "^2.6.12", "detect-europe-js": "^0.1.2", "is-standalone-pwa": "^0.1.1", + "node-fetch": "^2.7.0", "ua-is-frozen": "^0.1.2" }, "bin": { @@ -33,84 +35,56 @@ "devDependencies": { "@babel/parser": "7.15.8", "@babel/traverse": "7.23.2", - "@jazzer.js/core": "^1.4.0", - "@playwright/test": "~1.32.2", + "@playwright/test": "^1.49.0", "jshint": "~2.13.6", "mocha": "~8.2.0", "requirejs": "2.3.2", "safe-regex": "^2.1.1", "tsd": "^0.29.0", - "uglify-js": "~3.12.0" + "uglify-js": "~3.19.3" }, "engines": { "node": "*" } }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/code-frame": { - "version": "7.22.13", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.21.4", + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.21.4", - "dev": true, - "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/@babel/parser": { - "version": "7.21.4", + "node_modules/@babel/generator/node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -118,174 +92,78 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/generator": { - "version": "7.23.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.23.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.21.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -294,22 +172,27 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template/node_modules/@babel/parser": { - "version": "7.23.0", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -319,8 +202,9 @@ }, "node_modules/@babel/traverse": { "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.23.0", @@ -338,9 +222,13 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/parser": { - "version": "7.23.0", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -349,235 +237,23 @@ } }, "node_modules/@babel/types": { - "version": "7.23.0", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core": { - "version": "1.4.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jazzer.js/hooking": "*", - "@jazzer.js/instrumentor": "*", - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-reports": "^3.1.5", - "tmp": "^0.2.1", - "yargs": "^17.7.1" - }, - "bin": { - "jazzer": "dist/cli.js" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, - "node_modules/@jazzer.js/core/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jazzer.js/core/node_modules/cliui": { - "version": "8.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jazzer.js/core/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jazzer.js/core/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@jazzer.js/core/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@jazzer.js/core/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jazzer.js/core/node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@jazzer.js/core/node_modules/y18n": { - "version": "5.0.8", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/@jazzer.js/core/node_modules/yargs": { - "version": "17.7.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jazzer.js/core/node_modules/yargs-parser": { - "version": "21.1.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/@jazzer.js/fuzzer": { - "version": "1.4.0", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "bindings": "^1.5.0", - "cmake-js": "^7.2.1", - "node-addon-api": "^6.0.0", - "prebuild-install": "^7.1.1" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, - "node_modules/@jazzer.js/hooking": { - "version": "1.4.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@babel/core": "^7.21.0" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, - "node_modules/@jazzer.js/instrumentor": { - "version": "1.4.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@babel/core": "^7.21.0", - "@babel/generator": "^7.21.1", - "@jazzer.js/fuzzer": "*", - "@jazzer.js/hooking": "*", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^5.2.1", - "proper-lockfile": "^4.1.2", - "source-map-support": "^0.5.21" - }, - "engines": { - "node": ">= 14.0.0", - "npm": ">= 7.0.0" - } - }, "node_modules/@jest/schemas": { "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, - "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -586,57 +262,58 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true, - "license": "MIT" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true, - "license": "MIT" - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -647,16 +324,18 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -666,87 +345,106 @@ } }, "node_modules/@playwright/test": { - "version": "1.32.3", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz", + "integrity": "sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@types/node": "*", - "playwright-core": "1.32.3" + "playwright": "1.49.0" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=14" - }, - "optionalDependencies": { - "fsevents": "2.3.2" + "node": ">=18" } }, "node_modules/@sinclair/typebox": { "version": "0.27.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, "node_modules/@tsd/typescript": { "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-VtjHPAKJqLJoHHKBDNofzvQB2+ZVxjXU/Gw6INAS9aINLQYVsxfzrQ2s84huCeYWZRTtrr7R0J7XgpZHjNwBCw==", "dev": true, - "license": "MIT", "engines": { "node": ">=14.17" } }, "node_modules/@types/eslint": { "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/estree": { - "version": "1.0.2", - "dev": true, - "license": "MIT" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.13", - "dev": true, - "license": "MIT" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "node_modules/@types/minimist": { - "version": "1.2.3", - "dev": true, - "license": "MIT" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true }, "node_modules/@types/node": { - "version": "18.15.11", - "dev": true, - "license": "MIT" + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", + "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } }, "node_modules/@types/normalize-package-data": { - "version": "2.4.2", - "dev": true, - "license": "MIT" + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true }, "node_modules/ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -757,40 +455,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { - "version": "3.0.1", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "3.2.1", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -799,180 +492,73 @@ "node": ">= 8" } }, - "node_modules/append-transform": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/are-we-there-yet": { - "version": "3.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/arrify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/asynckit": { "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/binary-extensions": { - "version": "2.2.0", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bl/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { - "version": "3.0.2", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -980,76 +566,24 @@ }, "node_modules/browser-stdout": { "version": "1.3.1", - "dev": true, - "license": "ISC" - }, - "node_modules/browserslist": { - "version": "4.21.5", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, "node_modules/camelcase": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase-keys": { "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, - "license": "MIT", "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", @@ -1062,42 +596,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001481", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, "node_modules/chalk": { - "version": "2.4.2", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chokidar": { "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, - "license": "MIT", "dependencies": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -1114,18 +633,11 @@ "fsevents": "~2.1.2" } }, - "node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/cli": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha512-41U72MB56TfUMGndAKK8vJ78eooOD4Z5NOL4xEfjc0c23s+6EYKXlXsmACBVclLP1yOfWCgEganVzddVrSNoTg==", "dev": true, - "license": "MIT", "dependencies": { "exit": "0.1.2", "glob": "^7.1.1" @@ -1134,113 +646,11 @@ "node": ">=0.2.5" } }, - "node_modules/cliui": { - "version": "5.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cmake-js": { - "version": "7.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "axios": "^1.3.2", - "debug": "^4", - "fs-extra": "^10.1.0", - "lodash.isplainobject": "^4.0.6", - "memory-stream": "^1.0.0", - "node-api-headers": "^0.0.2", - "npmlog": "^6.0.2", - "rc": "^1.2.7", - "semver": "^7.3.8", - "tar": "^6.1.11", - "url-join": "^4.0.1", - "which": "^2.0.2", - "yargs": "^17.6.0" - }, - "bin": { - "cmake-js": "bin/cmake-js" - }, - "engines": { - "node": ">= 14.15.0" - } - }, - "node_modules/cmake-js/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cmake-js/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cmake-js/node_modules/cliui": { - "version": "8.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cmake-js/node_modules/color-convert": { + "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -1248,152 +658,16 @@ "node": ">=7.0.0" } }, - "node_modules/cmake-js/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/cmake-js/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/cmake-js/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cmake-js/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cmake-js/node_modules/semver": { - "version": "7.5.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cmake-js/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cmake-js/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cmake-js/node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/cmake-js/node_modules/y18n": { - "version": "5.0.8", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/cmake-js/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/cmake-js/node_modules/yargs": { - "version": "17.7.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cmake-js/node_modules/yargs-parser": { - "version": "21.1.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, "node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/color-support": { - "version": "1.1.3", - "dev": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", - "dev": true, - "license": "MIT", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1403,41 +677,38 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/console-browserify": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha512-duS7VP5pvfsNLDvL1O4VOEbw37AI3A4ZUQYemvDlnpGrNu9tprR7BYWpDYwC0Xia0Zxz5ZupdiIrUp0GH1aXfg==", "dev": true, "dependencies": { "date-now": "^0.1.4" } }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "dev": true, - "license": "ISC" - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "dev": true, - "license": "MIT" - }, "node_modules/core-util-is": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true }, "node_modules/date-now": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha512-AsElvov3LoNB7tf5k37H2jYSB+ZZPMT5sG2QjJCcdlV5chIv6htBUBUui2IKRjgtKAKtCBN7Zbwa+MtwLjSeNw==", "dev": true }, "node_modules/debug": { - "version": "4.3.4", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1450,16 +721,18 @@ }, "node_modules/decamelize": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decamelize-keys": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, - "license": "MIT", "dependencies": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" @@ -1473,63 +746,25 @@ }, "node_modules/decamelize-keys/node_modules/map-obj": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/default-require-extensions": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", - "dev": true, - "license": "MIT", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/detect-europe-js": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/detect-europe-js/-/detect-europe-js-0.1.2.tgz", + "integrity": "sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow==", "funding": [ { "type": "github", @@ -1543,37 +778,31 @@ "type": "paypal", "url": "https://paypal.me/faisalman" } - ], - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } + ] }, "node_modules/diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/diff-sequences": { "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, - "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -1583,8 +812,9 @@ }, "node_modules/dom-serializer": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "dev": true, - "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "entities": "^2.0.0" @@ -1592,30 +822,35 @@ }, "node_modules/dom-serializer/node_modules/domelementtype": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } - ], - "license": "BSD-2-Clause" + ] }, "node_modules/dom-serializer/node_modules/entities": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true, - "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/domelementtype": { "version": "1.3.1", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true }, "node_modules/domhandler": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==", "dev": true, "dependencies": { "domelementtype": "1" @@ -1623,63 +858,52 @@ }, "node_modules/domutils": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", "dev": true, "dependencies": { "dom-serializer": "0", "domelementtype": "1" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.374", - "dev": true, - "license": "ISC" - }, "node_modules/emoji-regex": { - "version": "7.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/entities": { "version": "1.0.0", - "dev": true, - "license": "BSD-like" + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", + "dev": true }, "node_modules/error-ex": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, - "node_modules/escalade": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/escape-string-regexp": { - "version": "1.0.5", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint-formatter-pretty": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-4.1.0.tgz", + "integrity": "sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/eslint": "^7.2.13", "ansi-escapes": "^4.2.1", @@ -1697,124 +921,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-formatter-pretty/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-formatter-pretty/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-formatter-pretty/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-formatter-pretty/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/eslint-rule-docs": { "version": "1.1.235", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz", + "integrity": "sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==", + "dev": true }, "node_modules/esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -1825,23 +942,18 @@ }, "node_modules/exit": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { "node": ">= 0.8.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "dev": true, - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/fast-glob": { - "version": "3.3.1", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1854,22 +966,19 @@ } }, "node_modules/fastq": { - "version": "1.15.0", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/fill-range": { - "version": "7.0.1", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1879,8 +988,9 @@ }, "node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -1894,35 +1004,17 @@ }, "node_modules/flat": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/form-data": { - "version": "4.0.0", - "dev": true, - "license": "MIT", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1932,157 +1024,36 @@ "node": ">= 6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, "node_modules/fs.realpath": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/function-bind": { - "version": "1.1.1", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "license": "MIT" - }, - "node_modules/gauge": { - "version": "4.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/wide-align": { - "version": "1.1.5", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2100,8 +1071,9 @@ }, "node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2111,8 +1083,9 @@ }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2122,16 +1095,18 @@ }, "node_modules/globals": { "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -2147,63 +1122,59 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "license": "ISC" - }, "node_modules/growl": { "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4.x" } }, "node_modules/hard-rejection": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/has": { - "version": "1.0.3", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, - "license": "MIT", "dependencies": { - "function-bind": "^1.1.1" + "function-bind": "^1.1.2" }, "engines": { - "node": ">= 0.4.0" + "node": ">= 0.4" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "dev": true, - "license": "ISC" - }, "node_modules/he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/hosted-git-info": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2213,8 +1184,9 @@ }, "node_modules/hosted-git-info/node_modules/lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -2224,18 +1196,15 @@ }, "node_modules/hosted-git-info/node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/htmlparser2": { "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==", "dev": true, - "license": "MIT", "dependencies": { "domelementtype": "1", "domhandler": "2.3", @@ -2244,45 +1213,30 @@ "readable-stream": "1.1" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { - "version": "5.2.4", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/indent-string": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -2290,31 +1244,30 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/irregular-plurals": { "version": "3.5.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", + "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-arrayish": { "version": "0.2.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -2323,11 +1276,15 @@ } }, "node_modules/is-core-module": { - "version": "2.13.0", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, - "license": "MIT", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2335,24 +1292,27 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -2362,22 +1322,26 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-obj": { - "version": "2.1.0", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/is-standalone-pwa": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-standalone-pwa/-/is-standalone-pwa-0.1.1.tgz", + "integrity": "sha512-9Cbovsa52vNQCjdXOzeQq5CnCbAcRk05aU62K20WO372NrTv0NxibLFCK6lQ4/iZEFdEA3p3t2VNOn8AJ53F5g==", "funding": [ { "type": "github", @@ -2391,101 +1355,25 @@ "type": "paypal", "url": "https://paypal.me/faisalman" } - ], - "license": "MIT" + ] }, "node_modules/isarray": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/jest-diff": { "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", @@ -2496,87 +1384,26 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-get-type": { "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, - "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -2586,20 +1413,22 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, - "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/jshint": { "version": "2.13.6", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.6.tgz", + "integrity": "sha512-IVdB4G0NTTeQZrBoM8C5JFVLjV2KtZ9APgybDA1MK73xb09qFs0jCXyQLnCOp1cSZZZbvhq/6mfXHUTaDkffuQ==", "dev": true, - "license": "MIT", "dependencies": { "cli": "~1.0.0", "console-browserify": "1.1.x", @@ -2615,48 +1444,30 @@ }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "node_modules/kind-of": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -2669,18 +1480,15 @@ }, "node_modules/lodash": { "version": "4.17.21", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/log-symbols": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.0.0" }, @@ -2688,96 +1496,11 @@ "node": ">=10" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/map-obj": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -2785,39 +1508,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/memory-stream": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^3.4.0" - } - }, - "node_modules/memory-stream/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/memory-stream/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/meow": { "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", @@ -2841,8 +1536,9 @@ }, "node_modules/meow/node_modules/type-fest": { "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2852,26 +1548,29 @@ }, "node_modules/meow/node_modules/yargs-parser": { "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.5", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -2880,16 +1579,16 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "dev": true, - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "dev": true, - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { "mime-db": "1.52.0" }, @@ -2897,29 +1596,20 @@ "node": ">= 0.6" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/min-indent": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/minimatch": { "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2927,18 +1617,11 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minimist-options": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, - "license": "MIT", "dependencies": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", @@ -2948,70 +1631,11 @@ "node": ">= 6" } }, - "node_modules/minimist-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/minipass": { - "version": "4.2.8", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "dev": true, - "license": "MIT" - }, "node_modules/mocha": { "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", "dev": true, - "license": "MIT", "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", @@ -3051,10 +1675,59 @@ "url": "https://opencollective.com/mochajs" } }, + "node_modules/mocha/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/mocha/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/mocha/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, "node_modules/mocha/node_modules/debug": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -3067,21 +1740,18 @@ } } }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/mocha/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "node_modules/mocha/node_modules/glob": { "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3097,18 +1767,33 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", + "node_modules/mocha/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/mocha/node_modules/minimatch": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3116,21 +1801,79 @@ "node": "*" } }, - "node_modules/mocha/node_modules/nanoid": { - "version": "3.1.12", + "node_modules/mocha/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "p-try": "^2.0.0" }, "engines": { - "node": "^10 || ^12 || >=13.7" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/mocha/node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -3138,87 +1881,98 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/supports-color": { - "version": "7.2.0", + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, - "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/mocha/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/mocha/node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, - "node_modules/napi-build-utils": { - "version": "1.0.2", + "node_modules/nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", "dev": true, - "license": "MIT" - }, - "node_modules/node-abi": { - "version": "3.40.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.5.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { - "semver": "bin/semver.js" + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=10" + "node": "^10 || ^12 || >=13.7" } }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/node-addon-api": { - "version": "6.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/node-api-headers": { - "version": "0.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.10", - "dev": true, - "license": "MIT" + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } }, "node_modules/normalize-package-data": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", @@ -3229,24 +1983,11 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.5.4", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -3254,45 +1995,29 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, "node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/npmlog": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -3305,8 +2030,9 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -3319,16 +2045,18 @@ }, "node_modules/p-try": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -3344,42 +2072,48 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-parse": { "version": "1.0.7", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/picocolors": { - "version": "1.0.0", - "dev": true, - "license": "ISC" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -3387,21 +2121,41 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/playwright-core": { - "version": "1.32.3", + "node_modules/playwright": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz", + "integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==", "dev": true, - "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.49.0" + }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=14" + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz", + "integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" } }, "node_modules/plur": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", "dev": true, - "license": "MIT", "dependencies": { "irregular-plurals": "^3.2.0" }, @@ -3412,35 +2166,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/pretty-format": { "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, - "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -3452,8 +2182,9 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -3461,32 +2192,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/proper-lockfile": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -3501,56 +2210,37 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/quick-lru": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, - "node_modules/rc": { - "version": "1.2.8", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-is": { - "version": "18.2.0", - "dev": true, - "license": "MIT" + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true }, "node_modules/read-pkg": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, - "license": "MIT", "dependencies": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", @@ -3563,8 +2253,9 @@ }, "node_modules/read-pkg-up": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, - "license": "MIT", "dependencies": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", @@ -3579,8 +2270,9 @@ }, "node_modules/read-pkg-up/node_modules/find-up": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -3591,8 +2283,9 @@ }, "node_modules/read-pkg-up/node_modules/locate-path": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -3602,8 +2295,9 @@ }, "node_modules/read-pkg-up/node_modules/p-limit": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -3616,8 +2310,9 @@ }, "node_modules/read-pkg-up/node_modules/p-locate": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -3627,21 +2322,24 @@ }, "node_modules/read-pkg-up/node_modules/type-fest": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } }, "node_modules/read-pkg/node_modules/hosted-git-info": { "version": "2.8.9", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true }, "node_modules/read-pkg/node_modules/normalize-package-data": { "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -3651,24 +2349,27 @@ }, "node_modules/read-pkg/node_modules/semver": { "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/read-pkg/node_modules/type-fest": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } }, "node_modules/readable-stream": { "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, - "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -3678,8 +2379,9 @@ }, "node_modules/readdirp": { "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, - "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -3689,8 +2391,9 @@ }, "node_modules/redent": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, - "license": "MIT", "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" @@ -3700,30 +2403,34 @@ } }, "node_modules/regexp-tree": { - "version": "0.1.24", + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", "dev": true, - "license": "MIT", "bin": { "regexp-tree": "bin/regexp-tree" } }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-main-filename": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "node_modules/requirejs": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.2.tgz", + "integrity": "sha512-rGSBJSIWfUEkMTztpZlyGIpRIwuMau6gZYxQhxH1jCggR3ddWsI8+/aWh9yUscMB1O0pEgZrJiXy2hJerzMszA==", "dev": true, - "license": "MIT", "bin": { "r_js": "bin/r.js", "r.js": "bin/r.js" @@ -3733,9 +2440,10 @@ } }, "node_modules/resolve": { - "version": "1.22.6", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, - "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -3748,39 +2456,20 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/retry": { - "version": "0.12.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -3796,13 +2485,14 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -3817,184 +2507,116 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/safe-regex": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", "dev": true, - "license": "MIT", "dependencies": { "regexp-tree": "~0.1.1" } }, - "node_modules/semver": { - "version": "6.3.0", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/serialize-javascript": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/set-blocking": { "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, "node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/spdx-correct": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "license": "CC-BY-3.0" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.15", - "dev": true, - "license": "CC0-1.0" + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true }, "node_modules/sprintf-js": { "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "node_modules/string_decoder": { "version": "0.10.31", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true }, "node_modules/string-width": { - "version": "2.1.1", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "license": "MIT", "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-ansi": { - "version": "4.0.0", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "MIT", "dependencies": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/strip-indent": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "license": "MIT", "dependencies": { "min-indent": "^1.0.0" }, @@ -4004,8 +2626,9 @@ }, "node_modules/strip-json-comments": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha512-AOPG8EBc5wAikaG1/7uFCNFJwnKOuQwFTpYBdTW6OvWHeZBQBrAA/amefHGrEiOnCPcLFZK6FUPtWVKpQVIRgg==", "dev": true, - "license": "MIT", "bin": { "strip-json-comments": "cli.js" }, @@ -4014,20 +2637,22 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-hyperlinks": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -4036,29 +2661,11 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4066,102 +2673,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tar": { - "version": "6.1.13", - "dev": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tar-stream/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/tmp": { - "version": "0.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4169,18 +2685,25 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/trim-newlines": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/tsd": { "version": "0.29.0", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.29.0.tgz", + "integrity": "sha512-5B7jbTj+XLMg6rb9sXRBGwzv7h8KJlGOkTHxY63eWpZJiQ5vJbXEjL0u7JkIxwi5EsrRE1kRVUWmy6buK/ii8A==", "dev": true, - "license": "MIT", "dependencies": { "@tsd/typescript": "~5.2.2", "eslint-formatter-pretty": "^4.1.0", @@ -4197,19 +2720,22 @@ "node": ">=14.16" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ua-is-frozen": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ua-is-frozen/-/ua-is-frozen-0.1.2.tgz", + "integrity": "sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw==", "funding": [ { "type": "github", @@ -4223,13 +2749,13 @@ "type": "paypal", "url": "https://paypal.me/faisalman" } - ], - "license": "MIT" + ] }, "node_modules/uglify-js": { - "version": "3.12.8", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, - "license": "BSD-2-Clause", "bin": { "uglifyjs": "bin/uglifyjs" }, @@ -4237,66 +2763,40 @@ "node": ">=0.8.0" } }, - "node_modules/universalify": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.11", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/url-join": { - "version": "4.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "license": "MIT" + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4308,104 +2808,80 @@ } }, "node_modules/which-module": { - "version": "2.0.0", - "dev": true, - "license": "ISC" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true }, "node_modules/wide-align": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2" } }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/workerpool": { "version": "6.0.2", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/wrap-ansi": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true }, "node_modules/wrappy": { "version": "1.0.2", - "dev": true, - "license": "ISC" - }, - "node_modules/y18n": { - "version": "4.0.3", - "dev": true, - "license": "ISC" - }, - "node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "13.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/yargs-parser": { "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -4413,8 +2889,9 @@ }, "node_modules/yargs-unparser": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -4427,8 +2904,9 @@ }, "node_modules/yargs-unparser/node_modules/camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -4438,8 +2916,9 @@ }, "node_modules/yargs-unparser/node_modules/decamelize": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -4447,98 +2926,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "4.1.1", + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index a281447..7b89b05 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "UAParser.js PRO Business", "name": "@ua-parser-js/pro-business", - "version": "2.0.0", + "version": "2.0.3", "author": "Faisal Salman (http://faisalman.com)", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment", "keywords": [ @@ -25,14 +25,17 @@ "contributors": [ "Aamir Poonawalla ", "Admas ", + "Aiyush ", "algenon ", "Alvin Portillo ", "Amumu ", + "Andreas Kogler ", "Andrea Vaghi ", "Anton Zhiyanov ", "Arturo Mejia ", "Arun Rama Reddy ", "Austin Pray ", + "Beat YT <66485277+Beat-YT@users.noreply.github.com>", "Bendeguz ", "Benjamin Bertrand ", "Benjamin Urban ", @@ -44,6 +47,8 @@ "chenyuan-new <53860479+chenyuan-new@users.noreply.github.com>", "Christopher De Cairos ", "Cyrille David ", + "Dai Jie ", + "Danila Rodichkin ", "Dante ", "Dario Vladovic ", "David Annez ", @@ -73,11 +78,15 @@ "Grigory Dmitrenko ", "gulpin ", "Hans Ott ", + "Harald Reingruber <74898239+haraldreingruber-dedalus@users.noreply.github.com>", "Hendrik Helwich ", "Hermann Ebert ", "hr6r ", + "Hyewon Kang ", + "Hyunbin <47051820+hyunbinseo@users.noreply.github.com>", "Igor Topal ", "Ildar Kamalov ", + "Ilya Daraseliya ", "insanehong ", "jackpoll ", "Jacky Choo ", @@ -98,6 +107,7 @@ "Liam Quinn ", "Lithin ", "liujunlve ", + "lj0812 ", "ll-syber <670159357@qq.com>", "Loris Guignard ", "Lukas Drgon ", @@ -111,6 +121,7 @@ "Max Maurer ", "Max Nordlund ", "Michael Hess ", + "Mike ", "MimyyK ", "Mok ", "nabetama ", @@ -124,6 +135,7 @@ "o.drapeza ", "Oscar Becerra ", "otakuSiD ", + "Pablo Osés ", "Paris Morgan ", "patrick-nurt ", "Pavel Studeny ", @@ -202,31 +214,32 @@ "scripts": { "build": "./script/build-dist.sh && ./script/build-esm.js", "build+test": "npm run build && npm run test", - "fuzz": "jazzer ./test/jazzer-fuzz-test.js --sync", + "fuzz": "jazzer ./test/fuzz/redos.js --sync", "test": "./script/test-all.sh", - "test:dts-lint": "tsd --typings src/main/ua-parser.d.ts --files test/dts-test.ts", + "test:dts-lint": "tsd --typings src/main/ua-parser.d.ts --files test/static/dts-lint.ts", "test:eslint": "eslint src && eslint script", "test:jshint": "jshint src/main", "test:lockfile-lint": "npx lockfile-lint -p package-lock.json", - "test:mocha": "mocha test/mocha*js", - "test:playwright": "playwright test" + "test:mocha": "mocha test/unit", + "test:playwright": "npx playwright install && playwright test test/e2e --browser all" }, "dependencies": { "detect-europe-js": "^0.1.2", "is-standalone-pwa": "^0.1.1", - "ua-is-frozen": "^0.1.2" + "ua-is-frozen": "^0.1.2", + "node-fetch": "^2.7.0", + "@types/node-fetch": "^2.6.12" }, "devDependencies": { "@babel/parser": "7.15.8", "@babel/traverse": "7.23.2", - "@jazzer.js/core": "^1.4.0", - "@playwright/test": "~1.32.2", + "@playwright/test": "^1.49.0", "jshint": "~2.13.6", "mocha": "~8.2.0", "requirejs": "2.3.2", "safe-regex": "^2.1.1", "tsd": "^0.29.0", - "uglify-js": "~3.12.0" + "uglify-js": "~3.19.3" }, "repository": { "type": "git", diff --git a/script/build-dist.sh b/script/build-dist.sh index 884f4b4..0648a12 100755 --- a/script/build-dist.sh +++ b/script/build-dist.sh @@ -4,10 +4,20 @@ SRC_PATH="src/main/ua-parser.js" MIN_PATH="dist/ua-parser.min.js" PACK_PATH="dist/ua-parser.pack.js" +SRC_PATH_MJS="src/main/ua-parser.mjs" +MIN_PATH_MJS="dist/ua-parser.min.mjs" +PACK_PATH_MJS="dist/ua-parser.pack.mjs" + # minified echo "Generate ${MIN_PATH}" uglifyjs $SRC_PATH -o $MIN_PATH --comments "/^ UA/" +echo "Generate ${MIN_PATH_MJS}" +uglifyjs $SRC_PATH_MJS -o $MIN_PATH_MJS --comments "/^ UA/" --module + # packed echo "Generate ${PACK_PATH}" -uglifyjs $SRC_PATH -o $PACK_PATH --comments "/^ UA/" --compress --mangle \ No newline at end of file +uglifyjs $SRC_PATH -o $PACK_PATH --comments "/^ UA/" --compress --mangle + +echo "Generate ${PACK_PATH_MJS}" +uglifyjs $SRC_PATH_MJS -o $PACK_PATH_MJS --comments "/^ UA/" --compress --mangle --module \ No newline at end of file diff --git a/src/enums/ua-parser-enums.d.ts b/src/enums/ua-parser-enums.d.ts new file mode 100644 index 0000000..2fb0db5 --- /dev/null +++ b/src/enums/ua-parser-enums.d.ts @@ -0,0 +1,374 @@ +// Type definitions for Enums submodule of UAParser.js v2.0.3 +// Project: https://github.com/faisalman/ua-parser-js +// Definitions by: Faisal Salman + +export const Browser: Readonly<{ + '115': "115"; + '2345': "2345"; + '360': "360"; + ALIPAY: "Alipay"; + AMAYA: "Amaya"; + ANDROID: "Android Browser"; + ARORA: "Arora"; + AVANT: "Avant"; + AVAST: "Avast Secure Browser"; + AVG: "AVG Secure Browser"; + BAIDU: "Baidu Browser"; + BASILISK: "Basilisk"; + BLAZER: "Blazer"; + BLU: "BLU"; + BOLT: "Bolt"; + BOWSER: "Bowser"; + BRAVE: "Brave"; + CAMINO: "Camino"; + CHIMERA: "Chimera"; + CHROME: "Chrome"; + CHROME_HEADLESS: "Chrome Headless"; + CHROME_MOBILE: "Mobile Chrome"; + CHROME_WEBVIEW: "Chrome WebView"; + CHROMIUM: "Chromium"; + COBALT: "Cobalt"; + COC_COC: "Coc Coc"; + CONKEROR: "Conkeror"; + DAUM: "Daum"; + DILLO: "Dillo"; + DOLPHIN: "Dolphin"; + DOOBLE: 'Dooble', + DORIS: "Doris"; + DRAGON: "Dragon"; + DUCKDUCKGO: "DuckDuckGo"; + ECOSIA: "Ecosia"; + EDGE: "Edge"; + EPIPHANY: "Epiphany"; + FACEBOOK: "Facebook"; + FALKON: "Falkon"; + FIREBIRD: "Firebird"; + FIREFOX: "Firefox"; + FIREFOX_FOCUS: "Firefox Focus"; + FIREFOX_MOBILE: "Mobile Firefox"; + FIREFOX_REALITY: "Firefox Reality"; + FENNEC: "Fennec"; + FLOCK: "Flock"; + FLOW: "Flow"; + GO: "GoBrowser"; + GOOGLE_SEARCH: "GSA"; + HELIO: "Helio"; + HEYTAP: "HeyTap"; + HONOR: "Honor"; + HUAWEI: "Huawei Browser"; + ICAB: "iCab"; + ICE: "ICE Browser"; + ICEAPE: "IceApe"; + ICECAT: "IceCat"; + ICEDRAGON: "IceDragon"; + ICEWEASEL: "IceWeasel"; + IE: "IE"; + INSTAGRAM: "Instagram"; + IRIDIUM: "Iridium"; + IRON: "Iron"; + JASMINE: "Jasmine"; + KONQUEROR: "Konqueror"; + KAKAO: "KakaoTalk"; + KHTML: "KHTML"; + K_MELEON: "K-Meleon"; + KLAR: "Klar"; + KLARNA: "Klarna"; + KINDLE: "Kindle"; + LENOVO: "Smart Lenovo Browser"; + LADYBIRD: "Ladybird"; + LG: "LG Browser"; + LIBREWOLF: "LibreWolf"; + LIEBAO: "LBBROWSER"; + LINE: "Line"; + LINKEDIN: "LinkedIn"; + LINKS: "Links"; + LUNASCAPE: "Lunascape"; + LYNX: "Lynx"; + MAEMO: "Maemo Browser"; + MAXTHON: "Maxthon"; + MIDORI: "Midori"; + MINIMO: "Minimo"; + MIUI: "MIUI Browser"; + MOZILLA: "Mozilla"; + MOSAIC: "Mosaic"; + NAVER: "Naver"; + NETFRONT: "NetFront"; + NETSCAPE: "Netscape"; + NETSURF: "Netsurf"; + NOKIA: "Nokia Browser"; + OBIGO: "Obigo"; + OCULUS: "Oculus Browser"; + OMNIWEB: "OmniWeb"; + OPERA: "Opera"; + OPERA_COAST: "Opera Coast"; + OPERA_GX: "Opera GX", + OPERA_MINI: "Opera Mini"; + OPERA_MOBI: "Opera Mobi"; + OPERA_TABLET: "Opera Tablet"; + OPERA_TOUCH: "Opera Touch"; + OTTER: "Otter"; + OVI: "OviBrowser"; + PALEMOON: "PaleMoon"; + PHANTOMJS: "PhantomJS"; + PHOENIX: "Phoenix"; + PICOBROWSER: "Pico Browser"; + POLARIS: "Polaris"; + PUFFIN: "Puffin"; + QQ: "QQBrowser"; + QQ_LITE: "QQBrowserLite"; + QUARK: "Quark"; + QUPZILLA: "QupZilla"; + QUTEBROWSER: "qutebrowser"; + REKONQ: "rekonq"; + ROCKMELT: "Rockmelt"; + SAFARI: "Safari"; + SAFARI_MOBILE: "Mobile Safari"; + SAILFISH: "Sailfish Browser"; + SAMSUNG: "Samsung Internet"; + SEAMONKEY: "SeaMonkey"; + SILK: "Silk"; + SKYFIRE: "Skyfire"; + SLEIPNIR: "Sleipnir"; + SLIMBOAT: "SlimBoat"; + SLIMBROWSER: "SlimBrowser"; + SLIMJET: "Slimjet"; + SNAPCHAT: "Snapchat"; + SOGOU_EXPLORER: "Sogou Explorer"; + SOGOU_MOBILE: "Sogou Mobile"; + SURF: "Surf"; + SWIFTFOX: "Swiftfox"; + TESLA: "Tesla"; + TIKTOK: "TikTok"; + TIZEN: "Tizen Browser"; + TWITTER: "Twitter"; + UC: "UCBrowser"; + UP: "UP.Browser"; + VIVALDI: "Vivaldi"; + VIVO: "Vivo Browser"; + W3M: "w3m"; + WATERFOX: "Waterfox"; + WEBKIT: "WebKit"; + WECHAT: "WeChat"; + WEIBO: "Weibo"; + WHALE: "Whale"; + WOLVIC: "Wolvic"; + YANDEX: "Yandex"; +}>; +export const BrowserType: Readonly<{ + CRAWLER: "crawler"; + CLI: "cli"; + EMAIL: "email"; + FETCHER: "fetcher"; + INAPP: "inapp"; + MEDIAPLAYER: "mediaplayer"; + LIBRARY: "library"; +}>; +export const CPU: Readonly<{ + '68K': "68k"; + ARM: "arm"; + ARM_64: "arm64"; + ARM_HF: "armhf"; + AVR: "avr"; + AVR_32: "avr32"; + IA64: "ia64"; + IRIX: "irix"; + IRIX_64: "irix64"; + MIPS: "mips"; + MIPS_64: "mips64"; + PA_RISC: "pa-risc"; + PPC: "ppc"; + SPARC: "sparc"; + SPARC_64: "sparc64"; + X86: "ia32"; + X86_64: "amd64"; +}>; +export const Device: Readonly<{ + CONSOLE: "console"; + DESKTOP: "desktop"; + EMBEDDED: "embedded"; + MOBILE: "mobile"; + SMARTTV: "smarttv"; + TABLET: "tablet"; + WEARABLE: "wearable"; + XR: "xr"; +}>; +export const Vendor: Readonly<{ + ACER: "Acer"; + ADVAN: "Advan"; + ALCATEL: "Alcatel"; + APPLE: "Apple"; + AMAZON: "Amazon"; + ARCHOS: "Archos"; + ASUS: "ASUS"; + ATT: "AT&T"; + BENQ: "BenQ"; + BLACKBERRY: "BlackBerry"; + CAT: "Cat"; + DELL: "Dell"; + ENERGIZER: "Energizer"; + ESSENTIAL: "Essential"; + FACEBOOK: "Facebook"; + FAIRPHONE: "Fairphone"; + GEEKSPHONE: "GeeksPhone"; + GENERIC: "Generic"; + GOOGLE: "Google"; + HMD: "HMD"; + HP: "HP"; + HTC: "HTC"; + HUAWEI: "Huawei"; + IMO: "IMO"; + INFINIX: "Infinix"; + ITEL: "itel"; + JOLLA: "Jolla"; + KOBO: "Kobo"; + LENOVO: "Lenovo"; + LG: "LG"; + MEIZU: "Meizu"; + MICROMAX: "Micromax"; + MICROSOFT: "Microsoft"; + MOTOROLA: "Motorola"; + NEXIAN: "Nexian"; + NINTENDO: "Nintendo"; + NOKIA: "Nokia"; + NOTHING: "Nothing"; + NVIDIA: "Nvidia"; + ONEPLUS: "OnePlus"; + OPPO: "OPPO"; + OUYA: "Ouya"; + PALM: "Palm"; + PANASONIC: "Panasonic"; + PEBBLE: "Pebble"; + PICO: "Pico"; + POLYTRON: "Polytron"; + REALME: "Realme"; + RIM: "RIM"; + ROKU: "Roku"; + SAMSUNG: "Samsung"; + SHARP: "Sharp"; + SIEMENS: "Siemens"; + SMARTFREN: "Smartfren"; + SONY: "Sony"; + SPRINT: "Sprint"; + TCL: "TCL"; + TECHNISAT: "TechniSAT"; + TECNO: "Tecno"; + TESLA: "Tesla"; + ULEFONE: "Ulefone"; + VIVO: "Vivo"; + VODAFONE: "Vodafone"; + XBOX: "Xbox"; + XIAOMI: "Xiaomi"; + ZEBRA: "Zebra"; + ZTE: "ZTE"; +}>; +export const Engine: Readonly<{ + AMAYA: "Amaya"; + ARKWEB: "ArkWeb"; + BLINK: "Blink"; + EDGEHTML: "EdgeHTML"; + FLOW: "Flow"; + GECKO: "Gecko"; + GOANNA: "Goanna"; + ICAB: "iCab"; + KHTML: "KHTML"; + LIBWEB: "LibWeb"; + LINKS: "Links"; + LYNX: "Lynx"; + NETFRONT: "NetFront"; + NETSURF: "NetSurf"; + PRESTO: "Presto"; + SERVO: "Servo"; + TASMAN: "Tasman"; + TRIDENT: "Trident"; + W3M: "w3m"; + WEBKIT: "WebKit"; +}>; +export const OS: Readonly<{ + AIX: "AIX"; + AMIGA_OS: "Amiga OS"; + ANDROID: "Android"; + ANDROID_X86: "Android-x86"; + ARCH: "Arch"; + BADA: "Bada"; + BEOS: "BeOS"; + BLACKBERRY: "BlackBerry"; + CENTOS: "CentOS"; + CHROME_OS: "Chrome OS"; + CHROMECAST: "Chromecast"; + CHROMECAST_ANDROID: "Chromecast Android"; + CHROMECAST_FUCHSIA: "Chromecast Fuchsia"; + CHROMECAST_LINUX: "Chromecast Linux"; + CHROMECAST_SMARTSPEAKER: "Chromecast SmartSpeaker"; + CONTIKI: "Contiki"; + DEBIAN: "Debian"; + DEEPIN: "Deepin"; + DRAGONFLY: "DragonFly"; + ELEMENTARY_OS: "elementary OS"; + FEDORA: "Fedora"; + FIREFOX_OS: "Firefox OS"; + FREEBSD: "FreeBSD"; + FUCHSIA: "Fuchsia"; + GENTOO: "Gentoo"; + GHOSTBSD: "GhostBSD"; + GNU: "GNU"; + HAIKU: "Haiku"; + HARMONYOS: "HarmonyOS"; + HP_UX: "HP-UX"; + HURD: "Hurd"; + IOS: "iOS"; + JOLI: "Joli"; + KAIOS: "KaiOS"; + KUBUNTU: "Kubuntu"; + LINPUS: "Linpus"; + LINSPIRE: "Linspire"; + LINUX: "Linux"; + MACOS: "macOS"; + MAEMO: "Maemo"; + MAGEIA: "Mageia"; + MANDRIVA: "Mandriva"; + MANJARO: "Manjaro"; + MEEGO: "MeeGo"; + MINIX: "Minix"; + MINT: "Mint"; + MORPH_OS: "Morph OS"; + NETBSD: "NetBSD"; + NETRANGE: "NetRange"; + NETTV: "NetTV"; + NINTENDO: "Nintendo"; + OPENHARMONY: "OpenHarmony"; + OPENBSD: "OpenBSD"; + OPENVMS: "OpenVMS"; + OS2: "OS/2"; + PALM: "Palm"; + PC_BSD: "PC-BSD"; + PCLINUXOS: "PCLinuxOS"; + PICO: "Pico"; + PLAN9: "Plan9"; + PLAYSTATION: "PlayStation"; + QNX: "QNX"; + RASPBIAN: "Raspbian"; + REDHAT: "RedHat"; + RIM_TABLET_OS: "RIM Tablet OS"; + RISC_OS: "RISC OS"; + SABAYON: "Sabayon"; + SAILFISH: "Sailfish"; + SERENITYOS: "SerenityOS"; + SERIES40: "Series40"; + SLACKWARE: "Slackware"; + SOLARIS: "Solaris"; + SUSE: "SUSE"; + SYMBIAN: "Symbian"; + TIZEN: "Tizen"; + UBUNTU: "Ubuntu"; + UBUNTU_TOUCH: "Ubuntu Touch", + UNIX: "Unix"; + VECTORLINUX: "VectorLinux"; + WATCHOS: "watchOS"; + WEBOS: "WebOS"; + WINDOWS: "Windows"; + WINDOWS_IOT: "Windows IoT"; + WINDOWS_MOBILE: "Windows Mobile"; + WINDOWS_PHONE: "Windows Phone"; + XBOX: "Xbox"; + ZENWALK: "Zenwalk"; +}>; diff --git a/src/enums/ua-parser-enums.js b/src/enums/ua-parser-enums.js index 9403d72..47b73cc 100644 --- a/src/enums/ua-parser-enums.js +++ b/src/enums/ua-parser-enums.js @@ -1,5 +1,5 @@ /////////////////////////////////////////////// -/* Enums for UAParser.js v2.0.0 +/* Enums for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman UAParser.js PRO Business License */ @@ -21,6 +21,7 @@ const Browser = Object.freeze({ BAIDU: 'Baidu Browser', BASILISK: 'Basilisk', BLAZER: 'Blazer', + BLU: 'BLU', BOLT: 'Bolt', BOWSER: 'Bowser', BRAVE: 'Brave', @@ -34,11 +35,14 @@ const Browser = Object.freeze({ COBALT: 'Cobalt', COC_COC: 'Coc Coc', CONKEROR: 'Conkeror', + DAUM: 'Daum', DILLO: 'Dillo', DOLPHIN: 'Dolphin', + DOOBLE: 'Dooble', DORIS: 'Doris', DRAGON: 'Dragon', DUCKDUCKGO: 'DuckDuckGo', + ECOSIA: 'Ecosia', EDGE: 'Edge', EPIPHANY: 'Epiphany', FACEBOOK: 'Facebook', @@ -76,6 +80,8 @@ const Browser = Object.freeze({ KLARNA: 'Klarna', KINDLE: 'Kindle', LENOVO: 'Smart Lenovo Browser', + LADYBIRD: 'Ladybird', + LG: 'LG Browser', LIBREWOLF: 'LibreWolf', LIEBAO: 'LBBROWSER', LINE: 'Line', @@ -100,10 +106,12 @@ const Browser = Object.freeze({ OMNIWEB: 'OmniWeb', OPERA: 'Opera', OPERA_COAST: 'Opera Coast', + OPERA_GX: 'Opera GX', OPERA_MINI: 'Opera Mini', OPERA_MOBI: 'Opera Mobi', OPERA_TABLET: 'Opera Tablet', OPERA_TOUCH: 'Opera Touch', + OTTER: 'Otter', OVI: 'OviBrowser', PALEMOON: 'PaleMoon', PHANTOMJS: 'PhantomJS', @@ -115,6 +123,7 @@ const Browser = Object.freeze({ QQ_LITE: 'QQBrowserLite', QUARK: 'Quark', QUPZILLA: 'QupZilla', + QUTEBROWSER: 'qutebrowser', REKONQ: 'rekonq', ROCKMELT: 'Rockmelt', SAFARI: 'Safari', @@ -131,6 +140,7 @@ const Browser = Object.freeze({ SNAPCHAT: 'Snapchat', SOGOU_EXPLORER: 'Sogou Explorer', SOGOU_MOBILE: 'Sogou Mobile', + SURF: 'Surf', SWIFTFOX: 'Swiftfox', TESLA: 'Tesla', TIKTOK: 'TikTok', @@ -213,6 +223,7 @@ const Vendor = Object.freeze({ GEEKSPHONE: 'GeeksPhone', GENERIC: 'Generic', GOOGLE: 'Google', + HMD: 'HMD', HP: 'HP', HTC: 'HTC', HUAWEI: 'Huawei', @@ -322,6 +333,7 @@ const OS = Object.freeze({ IOS: 'iOS', JOLI: 'Joli', KAIOS: 'KaiOS', + KUBUNTU: 'Kubuntu', LINPUS: 'Linpus', LINSPIRE: 'Linspire', LINUX: 'Linux', @@ -363,11 +375,13 @@ const OS = Object.freeze({ SYMBIAN: 'Symbian', TIZEN: 'Tizen', UBUNTU: 'Ubuntu', + UBUNTU_TOUCH: 'Ubuntu Touch', UNIX: 'Unix', VECTORLINUX: 'VectorLinux', WATCHOS: 'watchOS', WEBOS: 'WebOS', WINDOWS: 'Windows', + WINDOWS_IOT: 'Windows IoT', WINDOWS_MOBILE: 'Windows Mobile', WINDOWS_PHONE: 'Windows Phone', XBOX: 'Xbox', diff --git a/src/enums/ua-parser-enums.mjs b/src/enums/ua-parser-enums.mjs index eda5e2b..6fcecc9 100644 --- a/src/enums/ua-parser-enums.mjs +++ b/src/enums/ua-parser-enums.mjs @@ -3,7 +3,7 @@ // Source: /src/enums/ua-parser-enums.js /////////////////////////////////////////////// -/* Enums for UAParser.js v2.0.0 +/* Enums for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman UAParser.js PRO Business License */ @@ -25,6 +25,7 @@ const Browser = Object.freeze({ BAIDU: 'Baidu Browser', BASILISK: 'Basilisk', BLAZER: 'Blazer', + BLU: 'BLU', BOLT: 'Bolt', BOWSER: 'Bowser', BRAVE: 'Brave', @@ -38,11 +39,14 @@ const Browser = Object.freeze({ COBALT: 'Cobalt', COC_COC: 'Coc Coc', CONKEROR: 'Conkeror', + DAUM: 'Daum', DILLO: 'Dillo', DOLPHIN: 'Dolphin', + DOOBLE: 'Dooble', DORIS: 'Doris', DRAGON: 'Dragon', DUCKDUCKGO: 'DuckDuckGo', + ECOSIA: 'Ecosia', EDGE: 'Edge', EPIPHANY: 'Epiphany', FACEBOOK: 'Facebook', @@ -80,6 +84,8 @@ const Browser = Object.freeze({ KLARNA: 'Klarna', KINDLE: 'Kindle', LENOVO: 'Smart Lenovo Browser', + LADYBIRD: 'Ladybird', + LG: 'LG Browser', LIBREWOLF: 'LibreWolf', LIEBAO: 'LBBROWSER', LINE: 'Line', @@ -104,10 +110,12 @@ const Browser = Object.freeze({ OMNIWEB: 'OmniWeb', OPERA: 'Opera', OPERA_COAST: 'Opera Coast', + OPERA_GX: 'Opera GX', OPERA_MINI: 'Opera Mini', OPERA_MOBI: 'Opera Mobi', OPERA_TABLET: 'Opera Tablet', OPERA_TOUCH: 'Opera Touch', + OTTER: 'Otter', OVI: 'OviBrowser', PALEMOON: 'PaleMoon', PHANTOMJS: 'PhantomJS', @@ -119,6 +127,7 @@ const Browser = Object.freeze({ QQ_LITE: 'QQBrowserLite', QUARK: 'Quark', QUPZILLA: 'QupZilla', + QUTEBROWSER: 'qutebrowser', REKONQ: 'rekonq', ROCKMELT: 'Rockmelt', SAFARI: 'Safari', @@ -135,6 +144,7 @@ const Browser = Object.freeze({ SNAPCHAT: 'Snapchat', SOGOU_EXPLORER: 'Sogou Explorer', SOGOU_MOBILE: 'Sogou Mobile', + SURF: 'Surf', SWIFTFOX: 'Swiftfox', TESLA: 'Tesla', TIKTOK: 'TikTok', @@ -217,6 +227,7 @@ const Vendor = Object.freeze({ GEEKSPHONE: 'GeeksPhone', GENERIC: 'Generic', GOOGLE: 'Google', + HMD: 'HMD', HP: 'HP', HTC: 'HTC', HUAWEI: 'Huawei', @@ -326,6 +337,7 @@ const OS = Object.freeze({ IOS: 'iOS', JOLI: 'Joli', KAIOS: 'KaiOS', + KUBUNTU: 'Kubuntu', LINPUS: 'Linpus', LINSPIRE: 'Linspire', LINUX: 'Linux', @@ -367,11 +379,13 @@ const OS = Object.freeze({ SYMBIAN: 'Symbian', TIZEN: 'Tizen', UBUNTU: 'Ubuntu', + UBUNTU_TOUCH: 'Ubuntu Touch', UNIX: 'Unix', VECTORLINUX: 'VectorLinux', WATCHOS: 'watchOS', WEBOS: 'WebOS', WINDOWS: 'Windows', + WINDOWS_IOT: 'Windows IoT', WINDOWS_MOBILE: 'Windows Mobile', WINDOWS_PHONE: 'Windows Phone', XBOX: 'Xbox', diff --git a/src/extensions/ua-parser-extensions.d.ts b/src/extensions/ua-parser-extensions.d.ts index d1d0a12..3b9b63a 100644 --- a/src/extensions/ua-parser-extensions.d.ts +++ b/src/extensions/ua-parser-extensions.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Helpers submodule of UAParser.js v2.0.0 +// Type definitions for Helpers submodule of UAParser.js v2.0.3 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman @@ -12,4 +12,5 @@ export const Emails: UAParserExt; export const Fetchers: UAParserExt; export const InApps: UAParserExt; export const Libraries: UAParserExt; -export const MediaPlayers: UAParserExt; \ No newline at end of file +export const MediaPlayers: UAParserExt; +export const Vehicles: UAParserExt; \ No newline at end of file diff --git a/src/extensions/ua-parser-extensions.js b/src/extensions/ua-parser-extensions.js index 7fda4c5..54d0ea7 100644 --- a/src/extensions/ua-parser-extensions.js +++ b/src/extensions/ua-parser-extensions.js @@ -1,5 +1,5 @@ /////////////////////////////////////////////// -/* Extensions for UAParser.js v2.0.0 +/* Extensions for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman UAParser.js PRO Business License */ @@ -42,25 +42,25 @@ const Crawlers = Object.freeze({ [ // AhrefsBot - https://ahrefs.com/robot // Amazonbot - https://developer.amazon.com/amazonbot - // Bingbot - http://www.bing.com/bingbot.htm + // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0 // CCBot - https://commoncrawl.org/faq // Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot // DuckDuckBot - http://duckduckgo.com/duckduckbot.html // FacebookBot - https://developers.facebook.com/docs/sharing/bot/ // GPTBot - https://platform.openai.com/docs/gptbot + // LinkedInBot - http://www.linkedin.com // MJ12bot - https://mj12bot.com/ // MojeekBot - https://www.mojeek.com/bot.html // OpenAI's SearchGPT - https://platform.openai.com/docs/bots // PerplexityBot - https://perplexity.ai/perplexitybot - // SemrushBot - http://www.semrush.com/bot.html // SeznamBot - http://napoveda.seznam.cz/seznambot-intro - /((?:ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, + /((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|linkedin|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, // Applebot - http://apple.com/go/applebot - /(applebot(?:-extended)?)\/([\w\.]+)/i, + /(applebot(?:-extended)?)\/?([\w\.]*)/i, // Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001 - /(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i, + /(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i, // ClaudeBot (Anthropic) /(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i, @@ -78,6 +78,9 @@ const Crawlers = Object.freeze({ // Internet Archive (archive.org) /(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i, + // SemrushBot - http://www.semrush.com/bot.html + /((?:semrush|splitsignal)bot[-abcfimostw]*)\/?([\w\.-]*)/i, + // Sogou Spider /(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i, @@ -90,8 +93,8 @@ const Crawlers = Object.freeze({ // Yeti (Naver) /(yeti)\/([\w\.]+)/i, - // aiHitBot / Diffbot / Magpie-Crawler / Omgilibot / Webzio-Extended / Screaming Frog SEO Spider / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot - /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|(?:magpie-|velenpublicweb)crawler|webzio-extended|(?:screaming frog seo |yisou)spider)\/?([\w\.]*)/i + // aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot + /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|webzio-extended|(?:screaming frog seo |line|yisou)spider)\/?([\w\.]*)/i ], [NAME, VERSION, [TYPE, CRAWLER]], @@ -108,7 +111,7 @@ const Crawlers = Object.freeze({ // Qihoo 360Spider // TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html // Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp - /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|(?=yahoo! )slurp)/i + /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i ], [NAME, [TYPE, CRAWLER]] ] @@ -161,7 +164,7 @@ const ExtraDevices = Object.freeze({ /\b(zur\d{3}) b/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /\b((zeki)?tb.*\b) b/i // Zeki Tablets + /^((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ /\b([yr]\d{2}) b/i, @@ -217,33 +220,35 @@ const Fetchers = Object.freeze({ // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // ChatGPT-User - https://platform.openai.com/docs/plugins/bot // DuckAssistBot - https://duckduckgo.com/duckassistbot/ - // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot - /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i, + // Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot + // Google Site Verifier / Meta / Yahoo! Japan + // Yandex Bots - https://yandex.com/bots + /(ahrefssiteaudit|(?:bing|microsoft)preview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, - // Google Site Verifier - /(google-site-verification)\/([\w\.]+)/i, + // Bluesky + /(bluesky) cardyb\/([\w\.]+)/i, - // Meta - /(meta-externalfetcher)\/([\w\.]+)/i, + // Skype + /(skypeuripreview) preview\/([\w\.]+)/i, // Slackbot - https://api.slack.com/robots /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i, // WhatsApp - /(whatsapp)\/([\w\.]+)[\/ ][ianw]/i, - - // Yahoo! Japan - /(y!?j-dlc)\/([\w\.]+)/i, - - // Yandex Bots - https://yandex.com/bots - /(yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, - /(yandex(?:sitelinks|userproxy))/i + /(whatsapp)\/([\w\.]+)/i ], [NAME, VERSION, [TYPE, FETCHER]], - // Google Bots / Cohere / Snapchat / Vercelbot - [/(cohere-ai|vercelbot|feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat)/i], + [ + // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots + /((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i + ], [NAME, [TYPE, FETCHER]], + ], + + os : [ + [/whatsapp\/[\d\.]+ (a|i)/i], + [[NAME, os => os == 'A' ? 'Android' : 'iOS' ]] ] }); @@ -254,10 +259,12 @@ const Fetchers = Object.freeze({ const InApps = Object.freeze({ browser : [ // Slack - [/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]], + [/(?:slack(?=.+electron|.+ios)|chatlyio)\/([\d\.]+)/i], + [VERSION, [NAME, 'Slack'], [TYPE, INAPP]], // Yahoo! Japan - [/jp\.co\.yahoo\.android\.yjtop\/([\d\.]+)/i], [VERSION, 'Yahoo! Japan', [TYPE, INAPP]] + [/jp\.co\.yahoo\.(?:android\.yjtop|ipn\.appli)\/([\d\.]+)/i], + [VERSION, [NAME, 'Yahoo! Japan'], [TYPE, INAPP]] ] }); @@ -267,104 +274,48 @@ const InApps = Object.freeze({ const MediaPlayers = Object.freeze({ browser : [[ - - /(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia - /(coremedia) v([\w\._]+)/i - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i, - // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC + /(apple(?:coremedia|tv))\/([\w\._]+)/i, // Generic Apple CoreMedia + /(coremedia) v([\w\._]+)/i, + // Ares/Nexplayer/OSSProxy + /(ares|clementine|music player daemon|nexplayer|ossproxy) ([\w\.-]+)/i, + // Aqualung/Lyssna/BSPlayer/Clementine/MPD + // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/GnomeMplayer/MoC // NSPlayer/PSP-InternetRadioPlayer/Videos - /(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD - /(lg player|nexplayer)\s([\d\.]+)/i, - /player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - /(nexplayer)\s([\w\.-]+)/i // Nexplayer + // Nero Home/Nero Scout/Nokia + // QuickTime/RealMedia/RadioApp/RadioClientApplication/ + // SoundTap/Totem/Stagefright/Streamium + // XBMC/gvfs/Xine/XMMS/irapp + /^(aqualung|audacious|audimusicstream|amarok|bass|bsplayer|core|gnomemplayer|gvfs|irapp|lyssna|music on console|nero (?:home|scout)|nokia\d+|nsplayer|psp-internetradioplayer|quicktime|rma|radioapp|radioclientapplication|soundtap|stagefright|streamium|totem|videos|xbmc|xine|xmms)\/([\w\.-]+)/i, + /(lg player|nexplayer) ([\d\.]+)/i, + /player\/(nexplayer|lg player) ([\w\.-]+)/i, // NexPlayer/LG Player + /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i, // Gstreamer + /(htc streaming player) [\w_]+ \/ ([\d\.]+)/i, // HTC Streaming Player + /(lavf)([\d\.]+)/i, // Lavf (FFMPEG) + // MPlayer SVN + /(mplayer)(?: |\/)(?:(?:sherpya-){0,1}svn)(?:-| )(r\d+(?:-\d+[\w\.-]+))/i, + / (songbird)\/([\w\.-]+)/i, // Songbird/Philips-Songbird + /(winamp)(?:3 version|mpeg| ) ([\w\.-]+)/i, // Winamp + /(vlc)(?:\/| media player - version )([\w\.-]+)/i, // VLC Videolan + /^(foobar2000|itunes|smp)\/([\d\.]+)/i, // Foobar2000/iTunes/SMP + /com\.(riseupradioalarm)\/([\d\.]*)/i, // RiseUP Radio Alarm + /(mplayer)(?:\s|\/| unknown-)([\w\.\-]+)/i, // MPlayer + // Windows Media Server + /(windows)\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ home media server/i ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ /(flrp)\/([\w\.-]+)/i // Flip Player ], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [ - - /(fstream|nativehost|queryseekspider)/i // FStream/NativeHost/QuerySeekSpider + // MPlayer (no other info)/Media Player Classic/Nero ShowTime + // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) + // inlight radio / YourMuze + /(fstream|media player classic|inlight radio|mplayer|nativehost|nero showtime|ocms-bot|queryseekspider|tapinradio|tunein radio|winamp|yourmuze)/i ], [NAME, [TYPE, MEDIAPLAYER]], [ - /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i - // Gstreamer - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ + /(htc_one_s|windows-media-player|wmplayer)\/([\w\.-]+)/i, // HTC One S / Windows Media Player + ], [[NAME, /[_-]/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - /(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player - /(lavf)([\d\.]+)/i // Lavf (FFMPEG) - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(htc_one_s)\/([\d\.]+)/i, // HTC One S - ], [[NAME, /_/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i, - // MPlayer SVN - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer - /(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)/i, // MPlayer (no other info) - /(yourmuze)/i, // YourMuze - /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime - ], [NAME, [TYPE, MEDIAPLAYER]], [ - - /(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(nokia\d+)\/([\w\.-]+)/i // Nokia - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(winamp)3 version ([\w\.-]+)/i, // Winamp - /(winamp)\s([\w\.-]+)/i, - /(winamp)mpeg\/([\w\.-]+)/i - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) - // inlight radio - ], [NAME, [TYPE, MEDIAPLAYER]], [ - - /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i - // QuickTime/RealMedia/RadioApp/RadioClientApplication/ - // SoundTap/Totem/Stagefright/Streamium - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(smp)([\d\.]+)/i // SMP - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(vlc) media player - version ([\w\.]+)/i, // VLC Videolan - /(vlc)\/([\w\.-]+)/i, - /(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp - /(foobar2000)\/([\d\.]+)/i, // Foobar2000 - /(itunes)\/([\d\.]+)/i // iTunes - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(wmplayer)\/([\w\.-]+)/i, // Windows Media Player - /(windows-media-player)\/([\w\.-]+)/i - ], [[NAME, /-/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - - /windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i, - // Windows Media Server - ], [VERSION, [NAME, 'Windows'], [TYPE, MEDIAPLAYER]], [ - - /(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(rad.io)\s([\d\.]+)/i, // Rad.io - /(radio.(?:de|at|fr))\s([\d\.]+)/i + /(rad.io|radio.(?:de|at|fr)) ([\d\.]+)/i // Rad.io ], [[NAME, 'rad.io'], VERSION, [TYPE, MEDIAPLAYER]] ] }); @@ -375,8 +326,34 @@ const MediaPlayers = Object.freeze({ const Libraries = Object.freeze({ browser : [ - // Axios/jsdom/Scrapy/Java/urllib/requests - [/\b(axios|jsdom|scrapy|java|python-urllib|python-requests)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, LIBRARY]] + // Apache-HttpClient/Axios/go-http-client/got/GuzzleHttp/Java[-HttpClient]/jsdom/libwww-perl/lua-resty-http/Needle/node-fetch/OkHttp/PHP-SOAP/PostmanRuntime/python-urllib/python-requests/Scrapy/superagent + [ + /^(apache-httpclient|axios|(?:go|java)-http-client|got|guzzlehttp|java|libwww-perl|lua-resty-http|needle|node-(?:fetch|superagent)|okhttp|php-soap|postmanruntime|python-(?:urllib|requests)|scrapy)\/([\w\.]+)/i, + /(jsdom|(?<=\()java)\/([\w\.]+)/i + ], [NAME, VERSION, [TYPE, LIBRARY]] + ] +}); + +///////////// +// VEHICLES +//////////// + +const Vehicles = Object.freeze({ + device : [ + [/aftlbt962e2/i], // BMW + [[VENDOR, 'BMW']], + + [/dilink.+(byd) auto/i], // BYD + [VENDOR], + + [/aftlft962x3/i], // Jeep + [[VENDOR, 'Jeep'], [MODEL, 'Wagooner']], + + [/(rivian) (r1t)/i], // Rivian + [VENDOR, MODEL], + + [/vcc.+netfront/i], // Volvo + [[VENDOR, 'Volvo']] ] }); @@ -390,6 +367,9 @@ const Bots = Object.freeze({ ...Crawlers.browser, ...Fetchers.browser, ...Libraries.browser + ], + os : [ + ...Fetchers.os ] }); @@ -402,5 +382,6 @@ module.exports = { Fetchers, InApps, Libraries, - MediaPlayers + MediaPlayers, + Vehicles }; \ No newline at end of file diff --git a/src/extensions/ua-parser-extensions.mjs b/src/extensions/ua-parser-extensions.mjs index a5eadff..fc35d6e 100644 --- a/src/extensions/ua-parser-extensions.mjs +++ b/src/extensions/ua-parser-extensions.mjs @@ -3,7 +3,7 @@ // Source: /src/extensions/ua-parser-extensions.js /////////////////////////////////////////////// -/* Extensions for UAParser.js v2.0.0 +/* Extensions for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman UAParser.js PRO Business License */ @@ -46,25 +46,25 @@ const Crawlers = Object.freeze({ [ // AhrefsBot - https://ahrefs.com/robot // Amazonbot - https://developer.amazon.com/amazonbot - // Bingbot - http://www.bing.com/bingbot.htm + // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0 // CCBot - https://commoncrawl.org/faq // Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot // DuckDuckBot - http://duckduckgo.com/duckduckbot.html // FacebookBot - https://developers.facebook.com/docs/sharing/bot/ // GPTBot - https://platform.openai.com/docs/gptbot + // LinkedInBot - http://www.linkedin.com // MJ12bot - https://mj12bot.com/ // MojeekBot - https://www.mojeek.com/bot.html // OpenAI's SearchGPT - https://platform.openai.com/docs/bots // PerplexityBot - https://perplexity.ai/perplexitybot - // SemrushBot - http://www.semrush.com/bot.html // SeznamBot - http://napoveda.seznam.cz/seznambot-intro - /((?:ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, + /((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|linkedin|mj12|mojeek|oai-search|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i, // Applebot - http://apple.com/go/applebot - /(applebot(?:-extended)?)\/([\w\.]+)/i, + /(applebot(?:-extended)?)\/?([\w\.]*)/i, // Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001 - /(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i, + /(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i, // ClaudeBot (Anthropic) /(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i, @@ -82,6 +82,9 @@ const Crawlers = Object.freeze({ // Internet Archive (archive.org) /(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i, + // SemrushBot - http://www.semrush.com/bot.html + /((?:semrush|splitsignal)bot[-abcfimostw]*)\/?([\w\.-]*)/i, + // Sogou Spider /(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i, @@ -94,8 +97,8 @@ const Crawlers = Object.freeze({ // Yeti (Naver) /(yeti)\/([\w\.]+)/i, - // aiHitBot / Diffbot / Magpie-Crawler / Omgilibot / Webzio-Extended / Screaming Frog SEO Spider / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot - /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|(?:magpie-|velenpublicweb)crawler|webzio-extended|(?:screaming frog seo |yisou)spider)\/?([\w\.]*)/i + // aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot + /((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|webzio-extended|(?:screaming frog seo |line|yisou)spider)\/?([\w\.]*)/i ], [NAME, VERSION, [TYPE, CRAWLER]], @@ -112,7 +115,7 @@ const Crawlers = Object.freeze({ // Qihoo 360Spider // TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html // Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp - /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|(?=yahoo! )slurp)/i + /\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i ], [NAME, [TYPE, CRAWLER]] ] @@ -165,7 +168,7 @@ const ExtraDevices = Object.freeze({ /\b(zur\d{3}) b/i // Swiss ZUR Tablet ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ - /\b((zeki)?tb.*\b) b/i // Zeki Tablets + /^((zeki)?tb.*\b) b/i // Zeki Tablets ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ /\b([yr]\d{2}) b/i, @@ -221,33 +224,35 @@ const Fetchers = Object.freeze({ // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // ChatGPT-User - https://platform.openai.com/docs/plugins/bot // DuckAssistBot - https://duckduckgo.com/duckassistbot/ - // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot - /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i, + // Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot + // Google Site Verifier / Meta / Yahoo! Japan + // Yandex Bots - https://yandex.com/bots + /(ahrefssiteaudit|(?:bing|microsoft)preview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, - // Google Site Verifier - /(google-site-verification)\/([\w\.]+)/i, + // Bluesky + /(bluesky) cardyb\/([\w\.]+)/i, - // Meta - /(meta-externalfetcher)\/([\w\.]+)/i, + // Skype + /(skypeuripreview) preview\/([\w\.]+)/i, // Slackbot - https://api.slack.com/robots /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i, // WhatsApp - /(whatsapp)\/([\w\.]+)[\/ ][ianw]/i, - - // Yahoo! Japan - /(y!?j-dlc)\/([\w\.]+)/i, - - // Yandex Bots - https://yandex.com/bots - /(yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i, - /(yandex(?:sitelinks|userproxy))/i + /(whatsapp)\/([\w\.]+)/i ], [NAME, VERSION, [TYPE, FETCHER]], - // Google Bots / Cohere / Snapchat / Vercelbot - [/(cohere-ai|vercelbot|feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat)/i], + [ + // Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots + /((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i + ], [NAME, [TYPE, FETCHER]], + ], + + os : [ + [/whatsapp\/[\d\.]+ (a|i)/i], + [[NAME, os => os == 'A' ? 'Android' : 'iOS' ]] ] }); @@ -258,10 +263,12 @@ const Fetchers = Object.freeze({ const InApps = Object.freeze({ browser : [ // Slack - [/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]], + [/(?:slack(?=.+electron|.+ios)|chatlyio)\/([\d\.]+)/i], + [VERSION, [NAME, 'Slack'], [TYPE, INAPP]], // Yahoo! Japan - [/jp\.co\.yahoo\.android\.yjtop\/([\d\.]+)/i], [VERSION, 'Yahoo! Japan', [TYPE, INAPP]] + [/jp\.co\.yahoo\.(?:android\.yjtop|ipn\.appli)\/([\d\.]+)/i], + [VERSION, [NAME, 'Yahoo! Japan'], [TYPE, INAPP]] ] }); @@ -271,104 +278,48 @@ const InApps = Object.freeze({ const MediaPlayers = Object.freeze({ browser : [[ - - /(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia - /(coremedia) v([\w\._]+)/i - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i, - // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC + /(apple(?:coremedia|tv))\/([\w\._]+)/i, // Generic Apple CoreMedia + /(coremedia) v([\w\._]+)/i, + // Ares/Nexplayer/OSSProxy + /(ares|clementine|music player daemon|nexplayer|ossproxy) ([\w\.-]+)/i, + // Aqualung/Lyssna/BSPlayer/Clementine/MPD + // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/GnomeMplayer/MoC // NSPlayer/PSP-InternetRadioPlayer/Videos - /(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD - /(lg player|nexplayer)\s([\d\.]+)/i, - /player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - /(nexplayer)\s([\w\.-]+)/i // Nexplayer + // Nero Home/Nero Scout/Nokia + // QuickTime/RealMedia/RadioApp/RadioClientApplication/ + // SoundTap/Totem/Stagefright/Streamium + // XBMC/gvfs/Xine/XMMS/irapp + /^(aqualung|audacious|audimusicstream|amarok|bass|bsplayer|core|gnomemplayer|gvfs|irapp|lyssna|music on console|nero (?:home|scout)|nokia\d+|nsplayer|psp-internetradioplayer|quicktime|rma|radioapp|radioclientapplication|soundtap|stagefright|streamium|totem|videos|xbmc|xine|xmms)\/([\w\.-]+)/i, + /(lg player|nexplayer) ([\d\.]+)/i, + /player\/(nexplayer|lg player) ([\w\.-]+)/i, // NexPlayer/LG Player + /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i, // Gstreamer + /(htc streaming player) [\w_]+ \/ ([\d\.]+)/i, // HTC Streaming Player + /(lavf)([\d\.]+)/i, // Lavf (FFMPEG) + // MPlayer SVN + /(mplayer)(?: |\/)(?:(?:sherpya-){0,1}svn)(?:-| )(r\d+(?:-\d+[\w\.-]+))/i, + / (songbird)\/([\w\.-]+)/i, // Songbird/Philips-Songbird + /(winamp)(?:3 version|mpeg| ) ([\w\.-]+)/i, // Winamp + /(vlc)(?:\/| media player - version )([\w\.-]+)/i, // VLC Videolan + /^(foobar2000|itunes|smp)\/([\d\.]+)/i, // Foobar2000/iTunes/SMP + /com\.(riseupradioalarm)\/([\d\.]*)/i, // RiseUP Radio Alarm + /(mplayer)(?:\s|\/| unknown-)([\w\.\-]+)/i, // MPlayer + // Windows Media Server + /(windows)\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ home media server/i ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ /(flrp)\/([\w\.-]+)/i // Flip Player ], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [ - - /(fstream|nativehost|queryseekspider)/i // FStream/NativeHost/QuerySeekSpider + // MPlayer (no other info)/Media Player Classic/Nero ShowTime + // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) + // inlight radio / YourMuze + /(fstream|media player classic|inlight radio|mplayer|nativehost|nero showtime|ocms-bot|queryseekspider|tapinradio|tunein radio|winamp|yourmuze)/i ], [NAME, [TYPE, MEDIAPLAYER]], [ - /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i - // Gstreamer - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ + /(htc_one_s|windows-media-player|wmplayer)\/([\w\.-]+)/i, // HTC One S / Windows Media Player + ], [[NAME, /[_-]/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - /(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player - /(lavf)([\d\.]+)/i // Lavf (FFMPEG) - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(htc_one_s)\/([\d\.]+)/i, // HTC One S - ], [[NAME, /_/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i, - // MPlayer SVN - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer - /(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(mplayer)/i, // MPlayer (no other info) - /(yourmuze)/i, // YourMuze - /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime - ], [NAME, [TYPE, MEDIAPLAYER]], [ - - /(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(nokia\d+)\/([\w\.-]+)/i // Nokia - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(winamp)3 version ([\w\.-]+)/i, // Winamp - /(winamp)\s([\w\.-]+)/i, - /(winamp)mpeg\/([\w\.-]+)/i - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) - // inlight radio - ], [NAME, [TYPE, MEDIAPLAYER]], [ - - /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i - // QuickTime/RealMedia/RadioApp/RadioClientApplication/ - // SoundTap/Totem/Stagefright/Streamium - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(smp)([\d\.]+)/i // SMP - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(vlc) media player - version ([\w\.]+)/i, // VLC Videolan - /(vlc)\/([\w\.-]+)/i, - /(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp - /(foobar2000)\/([\d\.]+)/i, // Foobar2000 - /(itunes)\/([\d\.]+)/i // iTunes - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(wmplayer)\/([\w\.-]+)/i, // Windows Media Player - /(windows-media-player)\/([\w\.-]+)/i - ], [[NAME, /-/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [ - - /windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i, - // Windows Media Server - ], [VERSION, [NAME, 'Windows'], [TYPE, MEDIAPLAYER]], [ - - /(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm - ], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [ - - /(rad.io)\s([\d\.]+)/i, // Rad.io - /(radio.(?:de|at|fr))\s([\d\.]+)/i + /(rad.io|radio.(?:de|at|fr)) ([\d\.]+)/i // Rad.io ], [[NAME, 'rad.io'], VERSION, [TYPE, MEDIAPLAYER]] ] }); @@ -379,8 +330,34 @@ const MediaPlayers = Object.freeze({ const Libraries = Object.freeze({ browser : [ - // Axios/jsdom/Scrapy/Java/urllib/requests - [/\b(axios|jsdom|scrapy|java|python-urllib|python-requests)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, LIBRARY]] + // Apache-HttpClient/Axios/go-http-client/got/GuzzleHttp/Java[-HttpClient]/jsdom/libwww-perl/lua-resty-http/Needle/node-fetch/OkHttp/PHP-SOAP/PostmanRuntime/python-urllib/python-requests/Scrapy/superagent + [ + /^(apache-httpclient|axios|(?:go|java)-http-client|got|guzzlehttp|java|libwww-perl|lua-resty-http|needle|node-(?:fetch|superagent)|okhttp|php-soap|postmanruntime|python-(?:urllib|requests)|scrapy)\/([\w\.]+)/i, + /(jsdom|(?<=\()java)\/([\w\.]+)/i + ], [NAME, VERSION, [TYPE, LIBRARY]] + ] +}); + +///////////// +// VEHICLES +//////////// + +const Vehicles = Object.freeze({ + device : [ + [/aftlbt962e2/i], // BMW + [[VENDOR, 'BMW']], + + [/dilink.+(byd) auto/i], // BYD + [VENDOR], + + [/aftlft962x3/i], // Jeep + [[VENDOR, 'Jeep'], [MODEL, 'Wagooner']], + + [/(rivian) (r1t)/i], // Rivian + [VENDOR, MODEL], + + [/vcc.+netfront/i], // Volvo + [[VENDOR, 'Volvo']] ] }); @@ -394,6 +371,9 @@ const Bots = Object.freeze({ ...Crawlers.browser, ...Fetchers.browser, ...Libraries.browser + ], + os : [ + ...Fetchers.os ] }); @@ -406,5 +386,6 @@ export { Fetchers, InApps, Libraries, - MediaPlayers + MediaPlayers, + Vehicles }; \ No newline at end of file diff --git a/src/helpers/ua-parser-helpers.d.ts b/src/helpers/ua-parser-helpers.d.ts index 30a2c81..4b6c808 100644 --- a/src/helpers/ua-parser-helpers.d.ts +++ b/src/helpers/ua-parser-helpers.d.ts @@ -1,8 +1,8 @@ -// Type definitions for Helpers submodule of UAParser.js v2.0.0 +// Type definitions for Helpers submodule of UAParser.js v2.0.3 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman -import { IResult } from "../main/ua-parser"; +import type { IResult } from "../main/ua-parser"; declare function getDeviceVendor(model: string): string | undefined; declare function isAppleSilicon(resultOrUA: IResult | string): boolean; diff --git a/src/helpers/ua-parser-helpers.js b/src/helpers/ua-parser-helpers.js index 773623f..2a42b34 100644 --- a/src/helpers/ua-parser-helpers.js +++ b/src/helpers/ua-parser-helpers.js @@ -1,5 +1,5 @@ /////////////////////////////////////////////// -/* Helpers for UAParser.js v2.0.0 +/* Helpers for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman UAParser.js PRO Personal License */ @@ -93,6 +93,9 @@ const isAIBot = (resultOrUA) => [ // Perplexity 'perplexitybot', + // Semrush + 'semrushbot-ocob', + // Timpi 'timpibot', diff --git a/src/helpers/ua-parser-helpers.mjs b/src/helpers/ua-parser-helpers.mjs index a6a0f2b..274cc70 100644 --- a/src/helpers/ua-parser-helpers.mjs +++ b/src/helpers/ua-parser-helpers.mjs @@ -3,7 +3,7 @@ // Source: /src/helpers/ua-parser-helpers.js /////////////////////////////////////////////// -/* Helpers for UAParser.js v2.0.0 +/* Helpers for UAParser.js v2.0.3 https://github.com/faisalman/ua-parser-js Author: Faisal Salman UAParser.js PRO Personal License */ @@ -97,6 +97,9 @@ const isAIBot = (resultOrUA) => [ // Perplexity 'perplexitybot', + // Semrush + 'semrushbot-ocob', + // Timpi 'timpibot', diff --git a/src/main/ua-parser.d.ts b/src/main/ua-parser.d.ts index 150d867..6c7c9f8 100644 --- a/src/main/ua-parser.d.ts +++ b/src/main/ua-parser.d.ts @@ -1,7 +1,10 @@ -// Type definitions for UAParser.js v2.0.0 +// Type definitions for UAParser.js v2.0.3 // Project: https://github.com/faisalman/ua-parser-js // Definitions by: Faisal Salman +import type { IncomingHttpHeaders } from 'http'; +import type { Headers as FetchAPIHeaders } from 'node-fetch'; + declare namespace UAParser { interface IData { @@ -50,11 +53,12 @@ declare namespace UAParser { type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[]; type UAParserProps = 'browser' | 'cpu' | 'device' | 'engine' | 'os'; type UAParserExt = Partial> | Partial>[]; + type UAParserHeaders = Record | IncomingHttpHeaders | FetchAPIHeaders; - export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: Record): IResult; - export function UAParser(uastring?: string, headers?: Record): IResult; - export function UAParser(extensions?: UAParserExt, headers?: Record): IResult; - export function UAParser(headers?: Record): IResult; + export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: UAParserHeaders): IResult; + export function UAParser(uastring?: string, headers?: UAParserHeaders): IResult; + export function UAParser(extensions?: UAParserExt, headers?: UAParserHeaders): IResult; + export function UAParser(headers?: UAParserHeaders): IResult; export class UAParser { diff --git a/src/main/ua-parser.js b/src/main/ua-parser.js index aaa9aa3..0b36777 100755 --- a/src/main/ua-parser.js +++ b/src/main/ua-parser.js @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v2.0.0 - Copyright © 2012-2023 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman UAParser.js PRO Business License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment. @@ -19,20 +19,35 @@ // Constants ///////////// - var LIBVERSION = '2.0.0', + var LIBVERSION = '2.0.3', + UA_MAX_LENGTH = 500, + USER_AGENT = 'user-agent', EMPTY = '', UNKNOWN = '?', + + // typeof FUNC_TYPE = 'function', UNDEF_TYPE = 'undefined', OBJ_TYPE = 'object', STR_TYPE = 'string', - MAJOR = 'major', - MODEL = 'model', + + // properties + UA_BROWSER = 'browser', + UA_CPU = 'cpu', + UA_DEVICE = 'device', + UA_ENGINE = 'engine', + UA_OS = 'os', + UA_RESULT = 'result', + NAME = 'name', TYPE = 'type', VENDOR = 'vendor', VERSION = 'version', ARCHITECTURE= 'architecture', + MAJOR = 'major', + MODEL = 'model', + + // device types CONSOLE = 'console', MOBILE = 'mobile', TABLET = 'tablet', @@ -40,9 +55,11 @@ WEARABLE = 'wearable', XR = 'xr', EMBEDDED = 'embedded', + + // browser types INAPP = 'inapp', - USER_AGENT = 'user-agent', - UA_MAX_LENGTH = 500, + + // client hints BRANDS = 'brands', FORMFACTORS = 'formFactors', FULLVERLIST = 'fullVersionList', @@ -59,12 +76,8 @@ CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM, CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version', CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS], - UA_BROWSER = 'browser', - UA_CPU = 'cpu', - UA_DEVICE = 'device', - UA_ENGINE = 'engine', - UA_OS = 'os', - UA_RESULT = 'result', + + // device vendors AMAZON = 'Amazon', APPLE = 'Apple', ASUS = 'ASUS', @@ -76,20 +89,29 @@ LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', + NVIDIA = 'Nvidia', + ONEPLUS = 'OnePlus', + OPPO = 'OPPO', SAMSUNG = 'Samsung', SHARP = 'Sharp', SONY = 'Sony', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', - PREFIX_MOBILE = 'Mobile ', - SUFFIX_BROWSER = ' Browser', + + // browsers CHROME = 'Chrome', + CHROMIUM = 'Chromium', CHROMECAST = 'Chromecast', EDGE = 'Edge', FIREFOX = 'Firefox', OPERA = 'Opera', FACEBOOK = 'Facebook', SOGOU = 'Sogou', + + PREFIX_MOBILE = 'Mobile ', + SUFFIX_BROWSER = ' Browser', + + // os WINDOWS = 'Windows'; var isWindow = typeof window !== UNDEF_TYPE, @@ -331,11 +353,11 @@ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer - // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon - /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon)\/([-\w\.]+)/i, + // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon - /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115 - /(weibo)__([\d\.]+)/i // Weibo + /(heytap|ovi|115|surf)browser\/([\d\.]+)/i, // HeyTap/Ovi/115/Surf + /(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i // Ecosia/Weibo ], [NAME, VERSION], [ /quark(?:pc)?\/([-\w\.]+)/i // Quark ], [VERSION, [NAME, 'Quark']], [ @@ -399,6 +421,7 @@ /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp + /(daum)apps[\/ ]([\w\.]+)/i, // Daum App /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(alipay)client\/([\w\.]+)/i, // Alipay @@ -461,8 +484,8 @@ /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, - // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser + /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, + // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird /\b(links) \(([\w\.]+)/i // Links ], [NAME, [VERSION, /_/g, '.']], [ @@ -472,30 +495,30 @@ cpu : [[ - /\b(?:(amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64) + /\b((amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64) ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i, // IA32 (quicktime) - /((?:i[346]|x)86)[;\)]/i // IA32 (x86) + /\b((i[346]|x)86)(pc)?\b/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ - /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 + /\b(aarch64|arm(v?[89]e?l?|_?64))\b/i // ARM64 ], [[ARCHITECTURE, 'arm64']], [ - /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF + /\b(arm(v[67])?ht?n?[fl]p?)\b/i // ARMHF ], [[ARCHITECTURE, 'armhf']], [ // PocketPC mistakenly identified as PowerPC - /windows (ce|mobile); ppc;/i + /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i ], [[ARCHITECTURE, 'arm']], [ - /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC + /((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ - /(sun4\w)[;\)]/i // SPARC + / sun4\w[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i + /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC ], [[ARCHITECTURE, lowerize]] ], @@ -529,37 +552,44 @@ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ // Honor - /(?:honor)([-\w ]+)[;\)]/i + /\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i + ], [MODEL, [VENDOR, HONOR], [TYPE, TABLET]], [ + /honor([-\w ]+)[;\)]/i ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [ // Huawei - /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i + /\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei)([-\w ]+)[;\)]/i, /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi + /oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i, + /\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i // Mi Pad tablets + ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ + /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models - /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i, // Xiaomi Mi + / ([\w ]+) miui\/v?\d/i ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ - /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad - /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets - ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO /; (\w+) bui.+ oppo/i, /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i - ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ - /\b(opd2\d{3}a?) bui/i - ], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [ + ], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [ + /\b(opd2(\d{3}a?))(?: bui|\))/i + ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '203'], '*' : OPPO }], [TYPE, TABLET]], [ + // BLU Vivo Series + /(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i + ], [MODEL, [VENDOR, 'BLU'], [TYPE, MOBILE]], [ // Vivo - /vivo (\w+)(?: bui|\))/i, + /; vivo (\w+)(?: bui|\))/i, /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ @@ -570,7 +600,7 @@ // Motorola /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, /\bmot(?:orola)?[- ](\w*)/i, - /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i + /((?:moto(?! 360)[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ /\b(mz60\d|xoom[2 ]{0,2}) build\//i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ @@ -579,22 +609,24 @@ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, - /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, + /\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch))(\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo - /(ideatab[-\w ]+)/i, - /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i + /(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i, + /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [ // Nokia - /(?:maemo|nokia).*(n900|lumia \d+)/i, - /nokia[-_ ]?([-\w\.]*)/i - ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ + /(nokia) (t[12][01])/i + ], [VENDOR, MODEL, [TYPE, TABLET]], [ + /(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i, + /nokia[-_ ]?(([-\w\. ]*))/i + ], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [ // Google - /(pixel c)\b/i // Google Pixel C + /(pixel (c|tablet))\b/i // Google Pixel C/Tablet ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ @@ -609,7 +641,7 @@ // OnePlus / (kb2005|in20[12]5|be20[12][59])\b/i, /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i - ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [ // Amazon /(alexa)webm/i, @@ -684,21 +716,29 @@ /droid.+; (a(?:015|06[35]|142p?))/i ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [ + // Archos + /; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i, + /archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i + ], [MODEL, [VENDOR, 'Archos'], [TYPE, TABLET]], [ + /archos ([\w ]+)( b|\))/i, + /; (ac[3-6]\d\w{2,8})( b|\))/i + ], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [ + // MIXED - /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, + /(imo) (tab \w+)/i, // IMO + /(infinix) (x1101b?)/i // Infinix XPad + ], [VENDOR, MODEL, [TYPE, TABLET]], [ + + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan - /; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO + /; (blu|hmd|imo|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/TCL /(hp) ([\w ]+\w)/i, // HP iPAQ - /(asus)-?(\w+)/i, // Asus /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia - /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo - /(jolla)/i, // Jolla + /(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i, // Lenovo /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(imo) (tab \w+)/i, // IMO /(kobo)\s(ereader|touch)/i, // Kobo - /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i // Kindle ], [VENDOR, MODEL, [TYPE, TABLET]], [ @@ -707,8 +747,8 @@ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ - /(shield[\w ]+) b/i // Nvidia Shield Tablets - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ + /((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i // Nvidia Tablets + ], [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]], [ /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin @@ -726,7 +766,9 @@ ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ - /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV + /tcast.+(lg)e?. ([-\w]+)/i // LG SmartTV + ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ + /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ @@ -738,21 +780,28 @@ ], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast, Linux-based or unknown ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ + /(portaltv)/i // Facebook Portal TV + ], [MODEL, [VENDOR, FACEBOOK], [TYPE, SMARTTV]], [ /droid.+aft(\w+)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ + /(shield \w+ tv)/i // Nvidia Shield TV + ], [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i, /(aquos-tv[\w ]+)\)/i // Sharp ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[ /(bravia[\w ]+)( bui|\))/i // Sony ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ - /(mitv-\w{5}) bui/i // Xiaomi + /(mi(tv|box)-?\w+) bui/i // Xiaomi ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ /Hbbtv.*(technisat) (.*);/i // TechniSAT ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors + // SmartTV from Unidentified Vendors + /droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i + ], [MODEL, [TYPE, SMARTTV]], [ + /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i ], [[TYPE, SMARTTV]], [ /////////////////// @@ -762,8 +811,8 @@ /(ouya)/i, // Ouya /(nintendo) (\w+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ - /droid.+; (shield) bui/i // Nvidia - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ + /droid.+; (shield)( bui|\))/i // Nvidia Portable + ], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [ /(playstation \w+)/i // Playstation ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox @@ -773,12 +822,23 @@ // WEARABLES /////////////////// - /\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch + /\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i // Samsung Galaxy Watch ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [ - /((pebble))app/i // Pebble + /((pebble))app/i, // Pebble + /(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i // Asus ZenWatch / LG Watch / Pixel Watch ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ + /(ow(?:19|20)?we?[1-3]{1,3})/i // Oppo Watch + ], [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]], [ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [ + /(opwwe\d{3})/i // OnePlus Watch + ], [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]], [ + /(moto 360)/i // Motorola 360 + ], [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]], [ + /(smartwatch 3)/i // Sony SmartWatch + ], [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]], [ + /(g watch r)/i // LG G Watch R + ], [MODEL, [VENDOR, LG], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ @@ -790,7 +850,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [ /(pico) (4|neo3(?: link|pro)?)/i // Pico ], [VENDOR, MODEL, [TYPE, XR]], [ - /; (quest( \d| pro)?)/i // Oculus Quest + /(quest( \d| pro)?s?).+vr/i // Meta Quest ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [ /////////////////// @@ -801,20 +861,22 @@ ], [VENDOR, [TYPE, EMBEDDED]], [ /(aeobc)\b/i // Echo Dot ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [ + /(homepod).+mac os/i // Apple HomePod + ], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [ + /windows iot/i + ], [[TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) /////////////////// - /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors - ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors - ], [MODEL, [TYPE, TABLET]], [ + /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i + ], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ - /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device + /droid .+?; ([\w\. -]+)( bui|\))/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] ], @@ -834,8 +896,11 @@ /ekioh(flow)\/([\w\.]+)/i, // Flow /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab - /\b(libweb)/i + + /\b(libweb)/i // LibWeb ], [NAME, VERSION], [ + /ladybird\//i + ], [[NAME, 'LibWeb']], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko ], [VERSION, NAME] @@ -846,15 +911,15 @@ // Windows /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ - /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone + /(windows (?:phone(?: os)?|mobile|iot))[\/ ]?([\d\.\w ]*)/i // Windows Phone ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ - /windows nt 6\.2; (arm)/i, // Windows RT - /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i, + /windows nt 6\.2; (arm)/i, // Windows RT + /windows[\/ ]([ntce\d\. ]+\w)(?!.+xbox)/i, /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [ // iOS/macOS - /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS + /[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i, /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ @@ -876,15 +941,15 @@ // Mobile OSes /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS - ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony - /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i, - /(blackberry)\w*\/([\w\.]*)/i, // Blackberry - /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS - /\((series40);/i // Series 40 + ], [VERSION, NAME], [ + /(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch + ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [ + // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen + /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/\.; ]?([\d\.]*)/i ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ - /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian + /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS ], [VERSION, [NAME, FIREFOX+' OS']], [ @@ -914,7 +979,7 @@ /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire - /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux + /(hurd|linux)(?: arm\w*| x86\w*| ?)([\w\.]*)/i, // Hurd/Linux /(gnu) ?([\w\.]*)/i, // GNU /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly /(haiku) (\w+)/i // Haiku @@ -1151,17 +1216,31 @@ switch (this.itemType) { case UA_BROWSER: + case UA_ENGINE: var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; if (brands) { for (var i in brands) { - var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]), + var brandName = brands[i].brand || brands[i], brandVersion = brands[i].version; - if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) { + if (this.itemType == UA_BROWSER && !/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && brandName != CHROMIUM))) { + brandName = strMapper(brandName, { + 'Chrome' : 'Google Chrome', + 'Edge' : 'Microsoft Edge', + 'Chrome WebView' : 'Android WebView', + 'Chrome Headless' : 'HeadlessChrome', + 'Huawei Browser' : 'HuaweiBrowser', + 'MIUI Browser' : 'Miui Browser', + 'Opera Mobi' : 'OperaMobile', + 'Yandex' : 'YaBrowser' + }); this.set(NAME, brandName) .set(VERSION, brandVersion) .set(MAJOR, majorize(brandVersion)); prevName = brandName; } + if (this.itemType == UA_ENGINE && brandName == CHROMIUM) { + this.set(VERSION, brandVersion); + } } } break; @@ -1178,11 +1257,16 @@ } if (uaCH[MODEL]) { this.set(MODEL, uaCH[MODEL]); - } - // Xbox-Specific Detection - if (uaCH[MODEL] == 'Xbox') { - this.set(TYPE, CONSOLE) - .set(VENDOR, MICROSOFT); + if (!this.get(TYPE) || !this.get(VENDOR)) { + var reParse = {}; + rgxMapper.call(reParse, 'droid 9; ' + uaCH[MODEL] + ')', rgxMap); + if (!this.get(TYPE) && !!reParse.type) { + this.set(TYPE, reParse.type); + } + if (!this.get(VENDOR) && !!reParse.vendor) { + this.set(VENDOR, reParse.vendor); + } + } } if (uaCH[FORMFACTORS]) { var ff; diff --git a/src/main/ua-parser.mjs b/src/main/ua-parser.mjs index 6ce3376..e7c9567 100644 --- a/src/main/ua-parser.mjs +++ b/src/main/ua-parser.mjs @@ -3,8 +3,8 @@ // Source: /src/main/ua-parser.js ///////////////////////////////////////////////////////////////////////////////// -/* UAParser.js v2.0.0 - Copyright © 2012-2023 Faisal Salman +/* UAParser.js v2.0.3 + Copyright © 2012-2025 Faisal Salman UAParser.js PRO Business License *//* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment. @@ -21,20 +21,35 @@ // Constants ///////////// - var LIBVERSION = '2.0.0', + var LIBVERSION = '2.0.3', + UA_MAX_LENGTH = 500, + USER_AGENT = 'user-agent', EMPTY = '', UNKNOWN = '?', + + // typeof FUNC_TYPE = 'function', UNDEF_TYPE = 'undefined', OBJ_TYPE = 'object', STR_TYPE = 'string', - MAJOR = 'major', - MODEL = 'model', + + // properties + UA_BROWSER = 'browser', + UA_CPU = 'cpu', + UA_DEVICE = 'device', + UA_ENGINE = 'engine', + UA_OS = 'os', + UA_RESULT = 'result', + NAME = 'name', TYPE = 'type', VENDOR = 'vendor', VERSION = 'version', ARCHITECTURE= 'architecture', + MAJOR = 'major', + MODEL = 'model', + + // device types CONSOLE = 'console', MOBILE = 'mobile', TABLET = 'tablet', @@ -42,9 +57,11 @@ WEARABLE = 'wearable', XR = 'xr', EMBEDDED = 'embedded', + + // browser types INAPP = 'inapp', - USER_AGENT = 'user-agent', - UA_MAX_LENGTH = 500, + + // client hints BRANDS = 'brands', FORMFACTORS = 'formFactors', FULLVERLIST = 'fullVersionList', @@ -61,12 +78,8 @@ CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM, CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version', CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS], - UA_BROWSER = 'browser', - UA_CPU = 'cpu', - UA_DEVICE = 'device', - UA_ENGINE = 'engine', - UA_OS = 'os', - UA_RESULT = 'result', + + // device vendors AMAZON = 'Amazon', APPLE = 'Apple', ASUS = 'ASUS', @@ -78,20 +91,29 @@ LG = 'LG', MICROSOFT = 'Microsoft', MOTOROLA = 'Motorola', + NVIDIA = 'Nvidia', + ONEPLUS = 'OnePlus', + OPPO = 'OPPO', SAMSUNG = 'Samsung', SHARP = 'Sharp', SONY = 'Sony', XIAOMI = 'Xiaomi', ZEBRA = 'Zebra', - PREFIX_MOBILE = 'Mobile ', - SUFFIX_BROWSER = ' Browser', + + // browsers CHROME = 'Chrome', + CHROMIUM = 'Chromium', CHROMECAST = 'Chromecast', EDGE = 'Edge', FIREFOX = 'Firefox', OPERA = 'Opera', FACEBOOK = 'Facebook', SOGOU = 'Sogou', + + PREFIX_MOBILE = 'Mobile ', + SUFFIX_BROWSER = ' Browser', + + // os WINDOWS = 'Windows'; var isWindow = typeof window !== UNDEF_TYPE, @@ -333,11 +355,11 @@ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer - // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon - /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon)\/([-\w\.]+)/i, + // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble + /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon - /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115 - /(weibo)__([\d\.]+)/i // Weibo + /(heytap|ovi|115|surf)browser\/([\d\.]+)/i, // HeyTap/Ovi/115/Surf + /(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i // Ecosia/Weibo ], [NAME, VERSION], [ /quark(?:pc)?\/([-\w\.]+)/i // Quark ], [VERSION, [NAME, 'Quark']], [ @@ -401,6 +423,7 @@ /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp + /(daum)apps[\/ ]([\w\.]+)/i, // Daum App /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(alipay)client\/([\w\.]+)/i, // Alipay @@ -463,8 +486,8 @@ /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla // Other - /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, - // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser + /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, + // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird /\b(links) \(([\w\.]+)/i // Links ], [NAME, [VERSION, /_/g, '.']], [ @@ -474,30 +497,30 @@ cpu : [[ - /\b(?:(amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64) + /\b((amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64) ], [[ARCHITECTURE, 'amd64']], [ /(ia32(?=;))/i, // IA32 (quicktime) - /((?:i[346]|x)86)[;\)]/i // IA32 (x86) + /\b((i[346]|x)86)(pc)?\b/i // IA32 (x86) ], [[ARCHITECTURE, 'ia32']], [ - /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 + /\b(aarch64|arm(v?[89]e?l?|_?64))\b/i // ARM64 ], [[ARCHITECTURE, 'arm64']], [ - /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF + /\b(arm(v[67])?ht?n?[fl]p?)\b/i // ARMHF ], [[ARCHITECTURE, 'armhf']], [ // PocketPC mistakenly identified as PowerPC - /windows (ce|mobile); ppc;/i + /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i ], [[ARCHITECTURE, 'arm']], [ - /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC + /((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ - /(sun4\w)[;\)]/i // SPARC + / sun4\w[;\)]/i // SPARC ], [[ARCHITECTURE, 'sparc']], [ - /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i + /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC ], [[ARCHITECTURE, lowerize]] ], @@ -531,37 +554,44 @@ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ // Honor - /(?:honor)([-\w ]+)[;\)]/i + /\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i + ], [MODEL, [VENDOR, HONOR], [TYPE, TABLET]], [ + /honor([-\w ]+)[;\)]/i ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [ // Huawei - /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i + /\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei)([-\w ]+)[;\)]/i, /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ // Xiaomi + /oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i, + /\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i // Mi Pad tablets + ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ + /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models - /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi + /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i, // Xiaomi Mi + / ([\w ]+) miui\/v?\d/i ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ - /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad - /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets - ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ // OPPO /; (\w+) bui.+ oppo/i, /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i - ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ - /\b(opd2\d{3}a?) bui/i - ], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [ + ], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [ + /\b(opd2(\d{3}a?))(?: bui|\))/i + ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '203'], '*' : OPPO }], [TYPE, TABLET]], [ + // BLU Vivo Series + /(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i + ], [MODEL, [VENDOR, 'BLU'], [TYPE, MOBILE]], [ // Vivo - /vivo (\w+)(?: bui|\))/i, + /; vivo (\w+)(?: bui|\))/i, /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ @@ -572,7 +602,7 @@ // Motorola /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, /\bmot(?:orola)?[- ](\w*)/i, - /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i + /((?:moto(?! 360)[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ /\b(mz60\d|xoom[2 ]{0,2}) build\//i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ @@ -581,22 +611,24 @@ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, - /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, + /\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch))(\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ // Lenovo - /(ideatab[-\w ]+)/i, - /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i + /(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i, + /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [ // Nokia - /(?:maemo|nokia).*(n900|lumia \d+)/i, - /nokia[-_ ]?([-\w\.]*)/i - ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ + /(nokia) (t[12][01])/i + ], [VENDOR, MODEL, [TYPE, TABLET]], [ + /(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i, + /nokia[-_ ]?(([-\w\. ]*))/i + ], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [ // Google - /(pixel c)\b/i // Google Pixel C + /(pixel (c|tablet))\b/i // Google Pixel C/Tablet ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ @@ -611,7 +643,7 @@ // OnePlus / (kb2005|in20[12]5|be20[12][59])\b/i, /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i - ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ + ], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [ // Amazon /(alexa)webm/i, @@ -686,21 +718,29 @@ /droid.+; (a(?:015|06[35]|142p?))/i ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [ + // Archos + /; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i, + /archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i + ], [MODEL, [VENDOR, 'Archos'], [TYPE, TABLET]], [ + /archos ([\w ]+)( b|\))/i, + /; (ac[3-6]\d\w{2,8})( b|\))/i + ], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [ + // MIXED - /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, + /(imo) (tab \w+)/i, // IMO + /(infinix) (x1101b?)/i // Infinix XPad + ], [VENDOR, MODEL, [TYPE, TABLET]], [ + + /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan - /; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO + /; (blu|hmd|imo|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/TCL /(hp) ([\w ]+\w)/i, // HP iPAQ - /(asus)-?(\w+)/i, // Asus /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia - /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo - /(jolla)/i, // Jolla + /(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i, // Lenovo /(oppo) ?([\w ]+) bui/i // OPPO ], [VENDOR, MODEL, [TYPE, MOBILE]], [ - /(imo) (tab \w+)/i, // IMO /(kobo)\s(ereader|touch)/i, // Kobo - /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i // Kindle ], [VENDOR, MODEL, [TYPE, TABLET]], [ @@ -709,8 +749,8 @@ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ - /(shield[\w ]+) b/i // Nvidia Shield Tablets - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ + /((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i // Nvidia Tablets + ], [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]], [ /(sprint) (\w+)/i // Sprint Phones ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i // Microsoft Kin @@ -728,7 +768,9 @@ ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ - /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV + /tcast.+(lg)e?. ([-\w]+)/i // LG SmartTV + ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ + /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i // Apple TV ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [ @@ -740,21 +782,28 @@ ], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ /crkey/i // Google Chromecast, Linux-based or unknown ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ + /(portaltv)/i // Facebook Portal TV + ], [MODEL, [VENDOR, FACEBOOK], [TYPE, SMARTTV]], [ /droid.+aft(\w+)( bui|\))/i // Fire TV ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ + /(shield \w+ tv)/i // Nvidia Shield TV + ], [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i, /(aquos-tv[\w ]+)\)/i // Sharp ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[ /(bravia[\w ]+)( bui|\))/i // Sony ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ - /(mitv-\w{5}) bui/i // Xiaomi + /(mi(tv|box)-?\w+) bui/i // Xiaomi ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ /Hbbtv.*(technisat) (.*);/i // TechniSAT ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ - /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors + // SmartTV from Unidentified Vendors + /droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i + ], [MODEL, [TYPE, SMARTTV]], [ + /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i ], [[TYPE, SMARTTV]], [ /////////////////// @@ -764,8 +813,8 @@ /(ouya)/i, // Ouya /(nintendo) (\w+)/i // Nintendo ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ - /droid.+; (shield) bui/i // Nvidia - ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ + /droid.+; (shield)( bui|\))/i // Nvidia Portable + ], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [ /(playstation \w+)/i // Playstation ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox @@ -775,12 +824,23 @@ // WEARABLES /////////////////// - /\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch + /\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i // Samsung Galaxy Watch ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [ - /((pebble))app/i // Pebble + /((pebble))app/i, // Pebble + /(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i // Asus ZenWatch / LG Watch / Pixel Watch ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ + /(ow(?:19|20)?we?[1-3]{1,3})/i // Oppo Watch + ], [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]], [ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [ + /(opwwe\d{3})/i // OnePlus Watch + ], [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]], [ + /(moto 360)/i // Motorola 360 + ], [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]], [ + /(smartwatch 3)/i // Sony SmartWatch + ], [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]], [ + /(g watch r)/i // LG G Watch R + ], [MODEL, [VENDOR, LG], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ @@ -792,7 +852,7 @@ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [ /(pico) (4|neo3(?: link|pro)?)/i // Pico ], [VENDOR, MODEL, [TYPE, XR]], [ - /; (quest( \d| pro)?)/i // Oculus Quest + /(quest( \d| pro)?s?).+vr/i // Meta Quest ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [ /////////////////// @@ -803,20 +863,22 @@ ], [VENDOR, [TYPE, EMBEDDED]], [ /(aeobc)\b/i // Echo Dot ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [ + /(homepod).+mac os/i // Apple HomePod + ], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [ + /windows iot/i + ], [[TYPE, EMBEDDED]], [ //////////////////// // MIXED (GENERIC) /////////////////// - /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors - ], [MODEL, [TYPE, MOBILE]], [ - /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors - ], [MODEL, [TYPE, TABLET]], [ + /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i + ], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[TYPE, MOBILE]], [ - /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device + /droid .+?; ([\w\. -]+)( bui|\))/i // Generic Android Device ], [MODEL, [VENDOR, 'Generic']] ], @@ -836,8 +898,11 @@ /ekioh(flow)\/([\w\.]+)/i, // Flow /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab - /\b(libweb)/i + + /\b(libweb)/i // LibWeb ], [NAME, VERSION], [ + /ladybird\//i + ], [[NAME, 'LibWeb']], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko ], [VERSION, NAME] @@ -848,15 +913,15 @@ // Windows /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [NAME, VERSION], [ - /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone + /(windows (?:phone(?: os)?|mobile|iot))[\/ ]?([\d\.\w ]*)/i // Windows Phone ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ - /windows nt 6\.2; (arm)/i, // Windows RT - /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i, + /windows nt 6\.2; (arm)/i, // Windows RT + /windows[\/ ]([ntce\d\. ]+\w)(?!.+xbox)/i, /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [ // iOS/macOS - /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS + /[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i, /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ @@ -878,15 +943,15 @@ // Mobile OSes /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS - ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony - /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i, - /(blackberry)\w*\/([\w\.]*)/i, // Blackberry - /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS - /\((series40);/i // Series 40 + ], [VERSION, NAME], [ + /(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch + ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [ + // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen + /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/\.; ]?([\d\.]*)/i ], [NAME, VERSION], [ /\(bb(10);/i // BlackBerry 10 ], [VERSION, [NAME, BLACKBERRY]], [ - /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian + /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i // Symbian ], [VERSION, [NAME, 'Symbian']], [ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS ], [VERSION, [NAME, FIREFOX+' OS']], [ @@ -916,7 +981,7 @@ /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire - /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux + /(hurd|linux)(?: arm\w*| x86\w*| ?)([\w\.]*)/i, // Hurd/Linux /(gnu) ?([\w\.]*)/i, // GNU /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly /(haiku) (\w+)/i // Haiku @@ -1153,17 +1218,31 @@ switch (this.itemType) { case UA_BROWSER: + case UA_ENGINE: var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName; if (brands) { for (var i in brands) { - var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]), + var brandName = brands[i].brand || brands[i], brandVersion = brands[i].version; - if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) { + if (this.itemType == UA_BROWSER && !/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && brandName != CHROMIUM))) { + brandName = strMapper(brandName, { + 'Chrome' : 'Google Chrome', + 'Edge' : 'Microsoft Edge', + 'Chrome WebView' : 'Android WebView', + 'Chrome Headless' : 'HeadlessChrome', + 'Huawei Browser' : 'HuaweiBrowser', + 'MIUI Browser' : 'Miui Browser', + 'Opera Mobi' : 'OperaMobile', + 'Yandex' : 'YaBrowser' + }); this.set(NAME, brandName) .set(VERSION, brandVersion) .set(MAJOR, majorize(brandVersion)); prevName = brandName; } + if (this.itemType == UA_ENGINE && brandName == CHROMIUM) { + this.set(VERSION, brandVersion); + } } } break; @@ -1180,11 +1259,16 @@ } if (uaCH[MODEL]) { this.set(MODEL, uaCH[MODEL]); - } - // Xbox-Specific Detection - if (uaCH[MODEL] == 'Xbox') { - this.set(TYPE, CONSOLE) - .set(VENDOR, MICROSOFT); + if (!this.get(TYPE) || !this.get(VENDOR)) { + var reParse = {}; + rgxMapper.call(reParse, 'droid 9; ' + uaCH[MODEL] + ')', rgxMap); + if (!this.get(TYPE) && !!reParse.type) { + this.set(TYPE, reParse.type); + } + if (!this.get(VENDOR) && !!reParse.vendor) { + this.set(VENDOR, reParse.vendor); + } + } } if (uaCH[FORMFACTORS]) { var ff; diff --git a/test/specs/browser-all.json b/test/data/ua/browser/browser-all.json similarity index 96% rename from test/specs/browser-all.json rename to test/data/ua/browser/browser-all.json index 8698597..3fc0e5e 100644 --- a/test/specs/browser-all.json +++ b/test/data/ua/browser/browser-all.json @@ -511,6 +511,16 @@ "major" : "2" } }, + { + "desc" : "Dooble", + "ua" : "Mozilla/5.0 (X11; Haiku BePC) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.15.17 Chrome/87.0.4280.144 Safari/537.36 Dooble/2023.12.25 Dooble/2023.12.25", + "expect" : + { + "name" : "Dooble", + "version" : "2023.12.25", + "major" : "2023" + } + }, { "desc" : "Doris", "ua" : "Doris/1.15 [en] (Symbian)", @@ -541,6 +551,26 @@ "major" : "5" } }, + { + "desc" : "Ecosia on Android", + "ua" : "Mozilla/5.0 (Linux; Android 10; SM-G975U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36 (Ecosia android@85.0.4183.127)", + "expect" : + { + "name" : "Ecosia", + "version" : "85.0.4183.127", + "major" : "85" + } + }, + { + "desc" : "Ecosia on iOS", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 (Ecosia ios@3.0.1.533)", + "expect" : + { + "name" : "Ecosia", + "version" : "3.0.1.533", + "major" : "3" + } + }, { "desc" : "Epiphany", "ua" : "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7) Gecko/20040628 Epiphany/1.2.6", @@ -1006,6 +1036,16 @@ "major" : "5" } }, + { + "desc" : "Otter", + "ua" : "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/602.1 (KHTML, like Gecko) Otter/1.0.81", + "expect" : + { + "name" : "Otter", + "version" : "1.0.81", + "major" : "1" + } + }, { "desc" : "PicoBrowser", "ua" : "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", @@ -1067,13 +1107,33 @@ } }, { - "desc" : "LibreWolf", - "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 LibreWolf/91.0", + "desc" : "Surf Browser", + "ua" : "Mozilla/5.0 (Android 6.0; HUAWEI ALE-L21) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36 SurfBrowser/3.0", "expect" : { - "name" : "LibreWolf", - "version" : "91.0", - "major" : "91" + "name" : "Surf", + "version" : "3.0", + "major" : "3" + } + }, + { + "desc" : "LG Browser", + "ua" : "Mozilla/5.0 (Unknown; Linux armv7l) AppleWebKit/537.1+ (KHTML, like Gecko) Safari/537.1+ LG Browser/6.00.00(+mouse+3D+SCREEN+TUNER; LGE; 47LA621V-ZD; 04.28.17; 0x00000001;); LG NetCast.TV-2013 /04.28.17 (LG, 47LA621V-ZD, wired)", + "expect" : + { + "name" : "LG Browser", + "version" : "6.00.00", + "major" : "6" + } + }, + { + "desc" : "Ladybird", + "ua" : "Mozilla/5.0 (Linux; x86_64) Ladybird/1.0", + "expect" : + { + "name" : "Ladybird", + "version" : "1.0", + "major" : "1" } }, { @@ -1618,6 +1678,16 @@ "major" : "1" } }, + { + "desc" : "qutebrowser", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) qutebrowser/2.4.0 QtWebEngine/5.15.6 Chrome/95.0.4628.2 Safari/537.36", + "expect" : + { + "name" : "qutebrowser", + "version" : "2.4.0", + "major" : "2" + } + }, { "desc" : "Rekonq 2", "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.21 (KHTML, like Gecko) rekonq/2.2.1 Safari/537.21", @@ -2493,6 +2563,26 @@ "type" : "inapp" } }, + { + "desc" : "Daum App Android", + "ua" : "Mozilla/5.0 (Linux; Android 11; SM-G970N Build/RP1A.200720.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36 DaumApps/7.5.0 DaumDevice/mobile", + "expect" : { + "name" : "Daum", + "version": "7.5.0", + "major" : "7", + "type" : "inapp" + } + }, + { + "desc" : "Daum App iOS", + "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Safari/605.1.15 Mobile/15E148 DaumApps/7.5.1 DaumDevice/mobile", + "expect" : { + "name" : "Daum", + "version": "7.5.1", + "major" : "7", + "type" : "inapp" + } + }, { "desc" : "TikTok", "ua" : "Mozilla/5.0 (Linux; Android 11; 21061119AG Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile Safari/537.36 trill_2022109040 JsSdk/1.0 NetType/MOBILE Channel/googleplay AppName/musical_ly app_version/21.9.4 ByteLocale/ru-RU ByteFullLocale/ru-RU Region/KG BytedanceWebview/d8a21c6", diff --git a/test/specs/cpu-all.json b/test/data/ua/cpu/cpu-all.json similarity index 90% rename from test/specs/cpu-all.json rename to test/data/ua/cpu/cpu-all.json index 41df5d0..a4f68b1 100644 --- a/test/specs/cpu-all.json +++ b/test/data/ua/cpu/cpu-all.json @@ -7,6 +7,14 @@ "architecture" : "ia32" } }, + { + "desc" : "i686", + "ua" : "Mozilla/5.0 (X11; U; CrOS i686 9.10.0; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.253.0 Safari/532.5", + "expect" : + { + "architecture" : "ia32" + } + }, { "desc" : "i386", "ua" : "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7) Gecko/20040628 Epiphany/1.2.6", @@ -167,6 +175,14 @@ "architecture" : "arm64" } }, + { + "desc" : "Google Search App", + "ua" : "Mozilla/5.0 (Linux; Android 9; JAT-LX1 Build/HONORJAT-LX1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.96 Mobile Safari/537.36 GoogleApp/11.11.10.21.arm", + "expect" : + { + "architecture" : "arm" + } + }, { "desc" : "Google Search App", "ua" : "Mozilla/5.0 (Linux; Android 6.0; M5s Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.147 Mobile Safari/537.36 GSA/12.40.17.23.arm64", @@ -262,5 +278,13 @@ { "architecture" : "68k" } + }, + { + "desc" : "x86", + "ua" : "Mozilla/5.0 (Photon; U; QNX x86pc; en-US; rv:1.8.1.20) Gecko/20090127 BonEcho/2.0.0.20", + "expect" : + { + "architecture" : "ia32" + } } ] diff --git a/test/data/ua/device/_others.json b/test/data/ua/device/_others.json new file mode 100644 index 0000000..c47da24 --- /dev/null +++ b/test/data/ua/device/_others.json @@ -0,0 +1,302 @@ +[ + { + "desc": "Generic Android Device", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; X96mini_RP Build/X96mini_RP)", + "expect": { + "vendor": "Generic", + "model": "X96mini_RP" + } + }, + { + "desc": "Generic Android Device", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)", + "expect": { + "vendor": "Generic", + "model": "i980" + } + }, + { + "desc": "K", + "ua": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "K", + "type": "mobile" + } + }, + { + "desc": "Unknown VR Device", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; Unknown Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile VR Safari/537.36", + "expect": { + "model": "Unknown", + "type": "xr" + } + }, + { + "desc": "Desktop (IE11 with Tablet string)", + "ua": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; GWX:MANAGED; rv:11.0) like Gecko", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "undefined" + } + }, + { + "desc": "Mobile (DuckDuckGo mobile browser)", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile DuckDuckGo/5 Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "ChangHong Android TV", + "ua": "Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; ChangHong Android TV Build/LMY49J) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/10.8 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "ChangHong", + "type": "smarttv" + } + }, + { + "desc": "MStar Android TV", + "ua": "Mozilla/5.0 (Linux; Android 4.3.1; MStar Android TV Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.95 Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "MStar", + "type": "smarttv" + } + }, + { + "desc": "ONIDA Android TV", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ONIDA Android TV Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/48.0.2542.0 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "ONIDA", + "type": "smarttv" + } + }, + { + "desc": "JVC LT-43V55LFA Smart TV", + "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB211 VSTVB MB200 HbbTV/1.2.1 (; JVC; MB211; 3.19.4.2; _TV_NT72563_2017 SmartTvA/3.0.0", + "expect": { + "vendor": "JVC", + "model": "MB211", + "type": "smarttv" + } + }, + { + "desc": "JVC LT-43V65LUA Smart TV", + "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB130 VSTVB MB100 HbbTV/1.2.1 (; JVC; MB130; 5.7.20.0; _TV_G10_2017;) SmartTvA/3.0.0", + "expect": { + "vendor": "JVC", + "model": "MB130", + "type": "smarttv" + } + }, + { + "desc": "Loewe Smart TV", + "ua": "Mozilla/5.0 (Linux; U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2207.0 LOEWE-SL410/5.2.0.0 HbbTV/1.4.1 (; LOEWE; SL410; LOH/5.2.0.0;;) FVC/3.0 (LOEWE; SL410;) CE-HTML/1.0 Config (L:deu,CC:DEU) NETRANGEMMH", + "expect": { + "vendor": "LOEWE", + "model": "SL410", + "type": "smarttv" + } + }, + { + "desc": "Issue #747", + "ua": "python-requests/2.25.1", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "undefined" + } + }, + { + "desc": "Issue #454", + "ua": "Mosamzilla/5.0 (Windows; U; Win98; en-US; rv:1.7.5) Gecko/20050603 Netscape/8.0.2", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "undefined" + } + }, + { + "desc": "OnePlus 7T Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; HD1913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36 EdgA/110.0.1587.66", + "expect": { + "vendor": "undefined", + "model": "HD1913", + "type": "mobile" + } + }, + { + "desc": "Philips SmartTV", + "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", + "expect": { + "vendor": "Philips", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Philips 32PFL6606K/02 SmartTV (2011)", + "ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70", + "expect": { + "vendor": "Philips", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Philips 32PFL6606K/02 SmartTV (2013)", + "ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70", + "expect": { + "vendor": "Philips", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Philips 32PHS5301/12 SmartTV (2016)", + "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 OPR/29.0.1803.0 OMI/4.5.23.37.MOT2.13 HbbTV/1.2.1 (;Philips;32PHS5301/12;;_TV_MT5800;) Firmware/TPM161E_012.002.045.001 en", + "expect": { + "vendor": "Philips", + "model": "32PHS5301/12", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV", + "ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "Android Phone Unidentified Vendor (docomo F-04K)", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-04K Build/V15R060P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "model": "F-04K", + "type": "mobile" + } + }, + { + "desc": "Android Tablet Unidentified Vendor (docomo F-02K)", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-02K Build/V44R059G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", + "expect": { + "model": "F-02K", + "type": "tablet" + } + }, + { + "desc": "Android Tablet Unidentified Vendor (docomo d-02K)", + "ua": "Mozilla/5.0 (Linux; Android 9; d-02K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Safari/537.36", + "expect": { + "model": "d-02K", + "type": "tablet" + } + }, + { + "desc": "Android TV", + "ua": "Mozilla/5.0 (Linux; Android 10; 2020/2021 UHD Android TV Build/QTG3.201102.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "Unknown Mobile using Firefox", + "ua": "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Firefox", + "ua": "Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown Mobile using Focus for Android", + "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Focus for Android", + "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown Device using Focus for Android with GeckoView", + "ua": "Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Mobile using Firefox OS", + "ua": "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc": "Unknown Tablet using Firefox OS", + "ua": "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "tablet" + } + }, + { + "desc": "Unknown TV using Firefox OS", + "ua": "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "PDA with Windows CE", + "ua": "Mozilla/4.0 (PDA; Windows CE/1.0.1) NetFront/3.0", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "mobile" + } + }, + { + "desc" : "Windows IoT", + "ua" : "Mozilla/5.0 (Windows IoT 10.0; Android 6.0.1; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Mobile Safari/537.36 Edge/18.17763", + "expect": { + "vendor": "undefined", + "model": "undefined", + "type": "embedded" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/acer.json b/test/data/ua/device/acer.json new file mode 100644 index 0000000..7eff9d8 --- /dev/null +++ b/test/data/ua/device/acer.json @@ -0,0 +1,11 @@ +[ + { + "desc": "Acer Iconia A1-810", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; A1-810 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", + "expect": { + "vendor": "Acer", + "model": "A1-810", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/advan.json b/test/data/ua/device/advan.json new file mode 100644 index 0000000..16a2331 --- /dev/null +++ b/test/data/ua/device/advan.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Advan M4", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; ADVAN M4 Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36 OPR/28.0.2254.119214", + "expect": { + "vendor": "ADVAN", + "model": "M4", + "type": "mobile" + } + }, + { + "desc": "Advan S40", + "ua": "Mozilla/5.0 (Linux; Android 7.0; ADVAN S40 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Mobile Safari/537.36 EdgA/79.0.309.58", + "expect": { + "vendor": "ADVAN", + "model": "S40", + "type": "mobile" + } + }, + { + "desc": "Advan Sketsa 2", + "ua": "Mozilla/5.0 (Linux; Android 11; ADVAN 1011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36", + "expect": { + "vendor": "ADVAN", + "model": "1011", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/alcatel.json b/test/data/ua/device/alcatel.json new file mode 100644 index 0000000..3cd613e --- /dev/null +++ b/test/data/ua/device/alcatel.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Alcatel 4056W", + "ua": "Mozilla/5.0 (Mobile; ALCATEL 4056W; rv:84.0) Gecko/84.0 Firefox/84.0 KAIOS/3.0", + "expect": { + "vendor": "ALCATEL", + "model": "4056W", + "type": "mobile" + } + }, + { + "desc": "Alcatel A564C", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ALCATEL A564C Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "ALCATEL", + "model": "A564C", + "type": "mobile" + } + }, + { + "desc": "Alcatel Go Flip", + "ua": "Mozilla/5.0 (Mobile; ALCATEL4044T; rv:37.0) Gecko/37.0 Firefox/37.0 KaiOS/1.0", + "expect": { + "vendor": "ALCATEL", + "model": "4044T", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/amazon.json b/test/data/ua/device/amazon.json new file mode 100644 index 0000000..6e60318 --- /dev/null +++ b/test/data/ua/device/amazon.json @@ -0,0 +1,137 @@ +[ + { + "desc": "Kindle Fire HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", + "expect": { + "vendor": "Amazon", + "model": "KFTT", + "type": "tablet" + } + }, + { + "desc": "Kindle Fire HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", + "expect": { + "vendor": "Amazon", + "model": "KFTT", + "type": "tablet" + } + }, + { + "desc": "Echo Show 5", + "ua": "Mozilla/5.0 (Linux; Android 5.1; AEORK Build/LVY48F; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "AEORK", + "type": "tablet" + } + }, + { + "desc": "Echo Show 8", + "ua": "Mozilla/5.0 (Linux; Android 7.1; AEOCH) AppleWebKit/537.36 (KHTML, like Gecko) Silk/77.2.21 like Chrome/77.0.3865.92 Mobile Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "AEOCH", + "type": "tablet" + } + }, + { + "desc": "Echo Show 8", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; AEOCW) AppleWebKit/537.36 (KHTML, like Gecko) Silk/106.3.3 like Chrome/106.0.5249.170 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "AEOCW", + "type": "tablet" + } + }, + { + "desc": "Echo Show 15", + "ua": "Mozilla/5.0 (Linux; Android 9; AEOHY) AppleWebKit/537.36 (KHTML, like Gecko) Silk/112.6.3 like Chrome/112.0.5615.213 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "AEOHY", + "type": "tablet" + } + }, + { + "desc": "Echo Dot", + "ua": "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AEOBC Build/LVY48F)", + "expect": { + "vendor": "Amazon", + "model": "AEOBC", + "type": "embedded" + } + }, + { + "desc": "Amazon Kindle Fire Tablet", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFSAWI", + "type": "tablet" + } + }, + { + "desc": "Amazon Kindle Fire Tablet", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFSAWI", + "type": "tablet" + } + }, + { + "desc": "Amazon Kindle Fire Tablet", + "ua": "Mozilla/5.0 (Linux; Android 9; KFMAWI Build/PS7312; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFMAWI", + "type": "tablet" + } + }, + { + "desc": "Amazon Fire TV", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; AFTB Build/JDQ39) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.173 Mobile Safari/537.22", + "expect": { + "vendor": "Amazon", + "model": "B", + "type": "smarttv" + } + }, + { + "desc": "Amazon Fire TV", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; AFTT) AppleWebKit/537.36 (KHTML, like Gecko) Silk/86.3.20 like Chrome/86.0.4240.198 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "T", + "type": "smarttv" + } + }, + { + "desc": "Amazon Fire TV", + "ua": "Mozilla/5.0 (Linux; Android 9; AFTKA Build/PS7633.3445N; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.160 Mobile Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KA", + "type": "smarttv" + } + }, + { + "desc": "Amazon Fire 7", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/80.5.3 like Chrome/80.0.3987.162 Safari/537.36", + "expect": { + "vendor": "Amazon", + "model": "KFAUWI", + "type": "tablet" + } + }, + { + "desc": "Amazon Alexa Echo Show", + "ua": "AlexaWebMediaPlayer/1.0.200641.0 (Linux;Android 5.1.1)", + "expect": { + "vendor": "Amazon", + "model": "Alexa", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/apple.json b/test/data/ua/device/apple.json new file mode 100644 index 0000000..ea68e8a --- /dev/null +++ b/test/data/ua/device/apple.json @@ -0,0 +1,137 @@ +[ + { + "desc": "Apple Desktop", + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15", + "expect": { + "vendor": "Apple", + "model": "Macintosh", + "type": "undefined" + } + }, + { + "desc": "Apple Watch", + "ua": "atc/1.0 watchOS/7.3.3 model/Watch4,2 hwp/t8006 build/18S830 (6; dt:191)", + "expect": { + "vendor": "Apple", + "model": "watch", + "type": "wearable" + } + }, + { + "desc": "iPad using UCBrowser", + "ua": "Mozilla/5.0 (iPad; U; CPU OS 11_2 like Mac OS X; zh-CN; iPad5,3) AppleWebKit/534.46 (KHTML, like Gecko) UCBrowser/3.0.1.776 U3/ Mobile/10A403 Safari/7543.48.3", + "expect": { + "vendor": "Apple", + "model": "iPad", + "type": "tablet" + } + }, + { + "desc": "iPad Air", + "ua": "Mozilla/5.0 (iPad; CPU OS 12_4_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPad4,1;FBMD/iPad;FBSN/iOS;FBSV/12.4.5;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPad", + "type": "tablet" + } + }, + { + "desc": "iPad using Facebook Browser", + "ua": "Mozilla/5.0 (iPad; CPU OS 14_4_2 like Mac OS X) WebKit/8610 (KHTML, like Gecko) Mobile/18D70 [FBAN/FBIOS;FBDV/iPad7,11;FBMD/iPad;FBSN/iOS;FBSV/14.4.2;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5]", + "expect": { + "vendor": "Apple", + "model": "iPad", + "type": "tablet" + } + }, + { + "desc": "iPod", + "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53", + "expect": { + "vendor": "Apple", + "model": "iPod touch", + "type": "mobile" + } + }, + { + "desc": "iPhone", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone SE", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone SE using Facebook App", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone 11 Pro Max", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone12,5;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPhone XS", + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone11,2;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + }, + { + "desc": "iPod touch", + "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53", + "expect": { + "vendor": "Apple", + "model": "iPod touch", + "type": "mobile" + } + }, + { + "desc": "FaceBook Mobile App", + "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", + "expect": { + "vendor": "Apple", + "model": "iPhone12,1", + "type": "mobile" + } + }, + { + "desc": "Apple HomePod", + "ua": "AppleCoreMedia/1.0.0.15D61 (HomePod; U; CPU OS 11_2_5 like Mac OS X; en_us)", + "expect": { + "vendor": "Apple", + "model": "HomePod", + "type": "embedded" + } + }, + { + "desc": "Issue #519", + "ua": "ios/iPhone/14.2/SOME_CUSTOM_APP_VERSION", + "expect": { + "vendor": "Apple", + "model": "iPhone", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/archos.json b/test/data/ua/device/archos.json new file mode 100644 index 0000000..53628c5 --- /dev/null +++ b/test/data/ua/device/archos.json @@ -0,0 +1,227 @@ +[ + { + "desc": "Archos 5", + "ua": "Mozilla/5.0 (Linux; U; Android 1.6; fr-fr; Archos5 Build/Donut) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1", + "expect": { + "vendor": "Archos", + "model": "5", + "type": "tablet" + } + }, + { + "desc": "Archos 40b Titanium Surround", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Archos 40b Titanium Surround Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "40b Titanium Surround", + "type": "mobile" + } + }, + { + "desc": "Archos 40c Titanium v2", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ARCHOS 40C TIv2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "40C TIv2", + "type": "mobile" + } + }, + { + "desc": "Archos 45 Neon", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Archos 45 Neon Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "45 Neon", + "type": "mobile" + } + }, + { + "desc": "Archos 45 Neon", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; AC45NE Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 YaBrowser/15.6.2311.6088.00 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC45NE", + "type": "mobile" + } + }, + { + "desc": "Archos 45B Helium", + "ua": "Mozilla/5.0 (Linux; Android 7.0; AC45BHE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.109 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC45BHE", + "type": "mobile" + } + }, + { + "desc": "Archos 45B Titanium", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Archos 45B Titanium) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "45B Titanium", + "type": "mobile" + } + }, + { + "desc": "Archos 50 Cesium", + "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; ARCHOS; AC50CE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", + "expect": { + "vendor": "Archos", + "model": "AC50CE", + "type": "mobile" + } + }, + { + "desc": "Archos 50B Helium 4G", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; AC50BHE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC50BHE", + "type": "mobile" + } + }, + { + "desc": "Archos 55 diamond Selfie", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Archos 55 diamond Selfie Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.91 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "55 diamond Selfie", + "type": "mobile" + } + }, + { + "desc": "Archos 80 G9", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; zh-tw; ARCHOS 80G9 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "Archos", + "model": "80G9", + "type": "tablet" + } + }, + { + "desc": "Archos 80 Xenon", + "ua": "Mozilla/5.0 (Linux; Android 4.1.2; Archos 80 Xenon Build/JZO54K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Safari/537.36 OPR/50.6.2426.201126", + "expect": { + "vendor": "Archos", + "model": "80 Xenon", + "type": "tablet" + } + }, + { + "desc": "Archos 97c Platinum", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Archos 97c Platinum Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "97c Platinum", + "type": "tablet" + } + }, + { + "desc": "Archos 101 Access 3G V2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Archos Access 101 3G V2 Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.130 Safari/537.36[FBAN/EMA;FBLC/pt_PT;FBAV/360.0.0.7.53;]", + "expect": { + "vendor": "Archos", + "model": "Access 101 3G V2", + "type": "tablet" + } + }, + { + "desc": "Archos 101 Oxygen 4G", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Archos 101 Oxygen 4G Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.71 Safari/537.36 [FB_IAB/FB4A;FBAV/374.0.0.20.109;]", + "expect": { + "vendor": "Archos", + "model": "101 Oxygen 4G", + "type": "tablet" + } + }, + { + "desc": "Archos 101 Platinum 3G V2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; AC101PL3GV2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC101PL3GV2", + "type": "tablet" + } + }, + { + "desc": "Archos 101B Helium 4G", + "ua": "Mozilla/5.0 (Linux; Android 6.0; AC101BHE Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "AC101BHE", + "type": "tablet" + } + }, + { + "desc": "Archos 101s Oxygen Ardoiz", + "ua": "Mozilla/5.0 (Linux; Android 9; Archos Oxygen 101S ARDOIZ Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.102 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "Oxygen 101S ARDOIZ", + "type": "tablet" + } + }, + { + "desc": "Archos GAMEPAD2", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; ARCHOS GAMEPAD2 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.94 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "GAMEPAD2", + "type": "tablet" + } + }, + { + "desc": "Archos Hello 7", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Archos Hello 7 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.53 Safari/537.36 GoogleApp/13.24.9.26.arm64", + "expect": { + "vendor": "Archos", + "model": "Hello 7", + "type": "tablet" + } + }, + { + "desc": "Archos Sense 101 X", + "ua": "Mozilla/5.0 (Linux; arm; Android 7.0; Archos Sense 101 X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 YaBrowser/20.2.0.215.01 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "Sense 101 X", + "type": "tablet" + } + }, + { + "desc": "Archos T101 FHD WiFi", + "ua": "Mozilla/5.0 (Linux; Android 13; ARCHOS T101 FHD WiFi Build/T00624; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.159 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "T101 FHD WiFi", + "type": "tablet" + } + }, + { + "desc": "Archos Tikeasy 10d", + "ua": "Mozilla/5.0 (Linux; Android 13; Tikeasy 10d Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.260 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "Tikeasy 10d", + "type": "tablet" + } + }, + { + "desc": "Archos T96 WIFI", + "ua": "Mozilla/5.0 (Linux; Android 11; ARCHOS T96 WIFI_EEA Build/RP1A.201005.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.78 Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "T96 WIFI_EEA", + "type": "tablet" + } + }, + { + "desc": "Archos X67 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; X67 5G Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.58 Mobile Safari/537.36", + "expect": { + "vendor": "Archos", + "model": "X67 5G", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/asus.json b/test/data/ua/device/asus.json new file mode 100644 index 0000000..e5fee47 --- /dev/null +++ b/test/data/ua/device/asus.json @@ -0,0 +1,164 @@ +[ + { + "desc": "ASUS Nexus 7", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "Nexus 7", + "type": "tablet" + } + }, + { + "desc": "ASUS Padfone", + "ua": "Mozilla/5.0 (Linux; Android 4.1.1; PadFone 2 Build/JRO03L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "PadFone", + "type": "tablet" + } + }, + { + "desc": "ASUS ZenPad 10", + "ua": "Mozilla/5.0 (Linux; Android 6.0; P00C Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "P00C", + "type": "tablet" + } + }, + { + "desc": "ASUS ZenPad Z8s", + "ua": "Mozilla/5.0 (Linux; Android 7.0; ASUS_P00J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Safari/537.36\n", + "expect": { + "vendor": "ASUS", + "model": "P00J", + "type": "tablet" + } + }, + { + "desc": "ASUS ROG", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ZS600KL Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZS600KL", + "type": "mobile" + } + }, + { + "desc": "ASUS ROG II", + "ua": "Mozilla/5.0 (Linux; Android 9; ASUS_I001DA Build/PKQ1.190414.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "I001DA", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 2", + "ua": "Mozilla/5.0 (Linux; Android 5.0; ASUS ZenFone 2 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZenFone 2", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 3 Deluxe", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_Z016D Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.132 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "Z016D", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 5", + "ua": "Mozilla/5.0 (Linux; Android 8.0; ZE620KL Build/OPR1.170623.032) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZE620KL", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 7", + "ua": "Mozilla/5.0 (Linux; Android 10; ASUS_I002D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.81 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "I002D", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 7 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; ZS671KS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZS671KS", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; ZB602KL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZB602KL", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max Pro (M1)", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X00TD Build/OPM1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X00TD", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max M2", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01AD) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X01AD", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Max Pro M2", + "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01BDA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X01BDA", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone Go", + "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_X009DA Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "X009DA", + "type": "mobile" + } + }, + { + "desc": "ASUS Zenfone 2 Laser", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ASUS_Z00ED) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "Z00ED", + "type": "mobile" + } + }, + { + "desc": "ASUS ZenWatch", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; ASUS ZenWatch Build/LWX48S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/19.77.34.5 Mobile Safari/537.36", + "expect": { + "vendor": "ASUS", + "model": "ZenWatch", + "type": "wearable" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/blackberry.json b/test/data/ua/device/blackberry.json new file mode 100644 index 0000000..f809d55 --- /dev/null +++ b/test/data/ua/device/blackberry.json @@ -0,0 +1,47 @@ +[ + { + "desc": "BlackBerry Priv", + "ua": "User-Agent: Mozilla/5.0 (Linux; Android 5.1.1; STV100-1 Build/LMY47V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/46.0.2490.76 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "STV100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Keyone", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBB100-1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBB100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Key2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBF100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBF100-1", + "type": "mobile" + } + }, + { + "desc": "BlackBerry Key2 LE", + "ua": "User-Agent: Mozilla/5.0 (Linux; Android 8.1.0; BBE100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497 Mobile Safari/537.36", + "expect": { + "vendor": "BlackBerry", + "model": "BBE100-1", + "type": "mobile" + } + }, + { + "desc": "Blackview 4900Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; BV4900Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "BV4900Pro", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/blu.json b/test/data/ua/device/blu.json new file mode 100644 index 0000000..969d086 --- /dev/null +++ b/test/data/ua/device/blu.json @@ -0,0 +1,101 @@ +[ + { + "desc": "BLU Grand X LTE", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BLU Grand X LTE Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "Grand X LTE", + "type": "mobile" + } + }, + { + "desc": "BLU Neo Energy Mini", + "ua": "Mozilla/5.0 (Linux; Android 10; BLU_NEO_ENERGY_MINI Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.54 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "NEO_ENERGY_MINI", + "type": "mobile" + } + }, + { + "desc": "BLU NEO X PLUS", + "ua": "Mozilla/5.0 (Linux; Android 5.1; BLU NEO X PLUS Build/N090U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "NEO X PLUS", + "type": "mobile" + } + }, + { + "desc": "BLU STUDIO X MINI", + "ua": "Mozilla/5.0 (Linux; Android 5.1; BLU STUDIO X MINI Build/S0150UU) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.93 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "STUDIO X MINI", + "type": "mobile" + } + }, + { + "desc": "BLU Tank Mega", + "ua": "Mozilla/5.0 (Mobile; BLU_TankMega_3G; rv:48.0; CAEN) Gecko/48.0 Firefox/48.0 KAIOS/2.5.1.1", + "expect": { + "vendor": "BLU", + "model": "TankMega_3G", + "type": "mobile" + } + }, + { + "desc": "BLU TOUCHBOOK G7", + "ua": "Mozilla/5.0 (Linux; Android 5.0; BLU TOUCHBOOK G7 Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.107 Safari/537.36 OPR/29.0.1809.91837", + "expect": { + "vendor": "BLU", + "model": "TOUCHBOOK G7", + "type": "mobile" + } + }, + { + "desc": "BLU Vivo 5 Mini", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Vivo 5 Mini Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "BLU", + "model": "Vivo 5 Mini", + "type": "mobile" + } + }, + { + "desc": "BLU VIVO AIR LTE", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; BLU VIVO AIR LTE Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.107 Mobile Safari/537.36 OPR/29.0.1809.91837", + "expect": { + "vendor": "BLU", + "model": "VIVO AIR LTE", + "type": "mobile" + } + }, + { + "desc": "BLU VIVO GO", + "ua": "Mozilla/5.0 (Linux; U; Android 9; VIVO GO Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/72.0.3626.121 Mobile Safari/537.36 OPR/50.0.2254.149182", + "expect": { + "vendor": "BLU", + "model": "VIVO GO", + "type": "mobile" + } + }, + { + "desc": "BLU Vivo One Plus 2019", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Vivo One Plus 2019 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/277.0.0.41.126;]", + "expect": { + "vendor": "BLU", + "model": "Vivo One Plus 2019", + "type": "mobile" + } + }, + { + "desc": "BLU VIVO SELFIE", + "ua": "Mozilla/5.0 (Linux; U; Android 5.0; es-LA; BLU VIVO SELFIE Build/LRX21M) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/11.3.5.972 U3/0.8.0 Mobile Safari/534.30", + "expect": { + "vendor": "BLU", + "model": "VIVO SELFIE", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/cat.json b/test/data/ua/device/cat.json new file mode 100644 index 0000000..7c5710d --- /dev/null +++ b/test/data/ua/device/cat.json @@ -0,0 +1,38 @@ +[ + { + "desc": "Cat B15Q", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; B15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "Cat", + "model": "B15Q", + "type": "mobile" + } + }, + { + "desc": "Cat B35", + "ua": "Mozilla/5.0 (Mobile; CAT B35; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.1", + "expect": { + "vendor": "Cat", + "model": "B35", + "type": "mobile" + } + }, + { + "desc": "Cat S22 Flip", + "ua": "Mozilla/5.0 (Linux; Android 11; S22 FLIP Build/RKQ1.210416.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36", + "expect": { + "vendor": "Cat", + "model": "S22 FLIP", + "type": "mobile" + } + }, + { + "desc": "Cat S62 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; S62 Pro Build/RKQ1.210406.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.85 Mobile Safari/537.36 GSA/12.34.17.23.arm64", + "expect": { + "vendor": "Cat", + "model": "S62 Pro", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/energizer.json b/test/data/ua/device/energizer.json new file mode 100644 index 0000000..ec1ec47 --- /dev/null +++ b/test/data/ua/device/energizer.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Energizer Energy 400", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Energy400 Build/MRA58K test-keys; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.158 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/172.0.0.66.93;]", + "expect": { + "vendor": "Energizer", + "model": "Energy400", + "type": "mobile" + } + }, + { + "desc": "Energizer Energy 400S", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Energy 400S Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.85 Mobile Safari/537.36", + "expect": { + "vendor": "Energizer", + "model": "Energy 400S", + "type": "mobile" + } + }, + { + "desc": "Energizer Ultimate 65G", + "ua": "Mozilla/5.0 (Linux; Android 14; Energizer Ultimate 65G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Energizer", + "model": "Ultimate 65G", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/facebook.json b/test/data/ua/device/facebook.json new file mode 100644 index 0000000..f08f81f --- /dev/null +++ b/test/data/ua/device/facebook.json @@ -0,0 +1,47 @@ +[ + { + "desc": "Oculus Quest", + "ua": "Mozilla/5.0 (Linux; Android 10; Quest) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest", + "type": "xr" + } + }, + { + "desc": "Oculus Quest 2", + "ua": "Mozilla/5.0 (Linux; Android 10; Quest 2) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest 2", + "type": "xr" + } + }, + { + "desc": "Oculus Quest 3", + "ua": "Mozilla/5.0 (X11; Linux x86_64; Quest 3) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/31.4.0.6.51.566757996 Chrome/120.0.6099.283 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest 3", + "type": "xr" + } + }, + { + "desc": "Oculus Quest Pro", + "ua": "Mozilla/5.0 (X11; Linux x86_64; Quest Pro) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/24.4.0.22.60.426469926 SamsungBrowser/4.0 Chrome/106.0.5249.181 VR Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "Quest Pro", + "type": "xr" + } + }, + { + "desc": "Portal TV", + "ua": "Mozilla/5.0 (Linux; Android 9; PortalTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.120 Mobile Safari/537.36", + "expect": { + "vendor": "Facebook", + "model": "PortalTV", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/fairphone.json b/test/data/ua/device/fairphone.json new file mode 100644 index 0000000..e341cf7 --- /dev/null +++ b/test/data/ua/device/fairphone.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Fairphone 1U", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; FP1U Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Fairphone", + "model": "FP1U", + "type": "mobile" + } + }, + { + "desc": "Fairphone 2", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; FP2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Fairphone", + "model": "FP2", + "type": "mobile" + } + }, + { + "desc": "Fairphone 3", + "ua": "Mozilla/5.0 (Linux; Android 9; FP3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "Fairphone", + "model": "FP3", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/google.json b/test/data/ua/device/google.json new file mode 100644 index 0000000..a06b991 --- /dev/null +++ b/test/data/ua/device/google.json @@ -0,0 +1,236 @@ +[ + { + "desc": "Google Chromecast with Google TV", + "ua": "Mozilla/5.0 (Linux; Android 12.0; Build/STTL.240206.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.0 Safari/537.36 CrKey/1.56.500000 DeviceType/AndroidTV", + "expect": { + "vendor": "Google", + "model": "Chromecast AndroidTV", + "type": "smarttv" + } + }, + { + "desc": "Google Chromecast Mini Smart Speaker", + "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/SmartSpeaker", + "expect": { + "vendor": "Google", + "model": "Chromecast SmartSpeaker", + "type": "smarttv" + } + }, + { + "desc": "Google Chromecast Third Generation", + "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast", + "expect": { + "vendor": "Google", + "model": "Chromecast Third Generation", + "type": "smarttv" + } + }, + { + "desc": "Google Chromecast Nest Hub", + "ua": "Mozilla/5.0 (Fuchsia) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 CrKey/1.56.500000", + "expect": { + "vendor": "Google", + "model": "Chromecast Nest Hub", + "type": "smarttv" + } + }, + { + "desc": "Google Chromecast", + "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.84 Safari/537.36 CrKey/1.22.79313", + "expect": { + "vendor": "Google", + "model": "Chromecast", + "type": "smarttv" + } + }, + { + "desc": "Google Pixel C", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel C", + "type": "tablet" + } + }, + { + "desc": "Google Pixel C", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel C", + "type": "tablet" + } + }, + { + "desc": "Google Pixel", + "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel Build/NDE63V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel", + "type": "mobile" + } + }, + { + "desc": "Google Pixel Tablet", + "ua": "Mozilla/5.0 (Linux; Android 14; Pixel Tablet Build/AP2A.240905.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel Tablet", + "type": "tablet" + } + }, + { + "desc": "Google Pixel Watch", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Google Pixel Watch Build/TWD4.231005.002)", + "expect": { + "vendor": "Google", + "model": "Pixel Watch", + "type": "wearable" + } + }, + { + "desc": "Google Pixel Watch 2", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Google Pixel Watch 2 Build/TWD9.240605.001.A1)", + "expect": { + "vendor": "Google", + "model": "Pixel Watch 2", + "type": "wearable" + } + }, + { + "desc": "Google Pixel XL", + "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel XL Build/NDE63X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 2", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 2 XL", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 XL Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 2 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 2 XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 2 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 2 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3 XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3 XL", + "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3a", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3a", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 3a XL", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 3a XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 4", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 4a", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4a", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 4 XL", + "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 4 XL", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 5", + "ua": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.120 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 5", + "type": "mobile" + } + }, + { + "desc": "Google Pixel 7", + "ua": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Google", + "model": "Pixel 7", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/hmd.json b/test/data/ua/device/hmd.json new file mode 100644 index 0000000..a7d38e2 --- /dev/null +++ b/test/data/ua/device/hmd.json @@ -0,0 +1,38 @@ +[ + { + "desc": "HMD Barbie Phone", + "ua": "Mozilla/5.0 (Mobile; HMD Barbie Phone; rv:84.0) Gecko/84.0 Firefox/84.0 KAIOS/3.1", + "expect": { + "vendor": "HMD", + "model": "Barbie Phone", + "type": "mobile" + } + }, + { + "desc": "HMD Pulse", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse", + "type": "mobile" + } + }, + { + "desc": "HMD Pulse Plus", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse Plus) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse Plus", + "type": "mobile" + } + }, + { + "desc": "HMD Pulse Pro", + "ua": "Mozilla/5.0 (Linux; Android 14; HMD Pulse Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "HMD", + "model": "Pulse Pro", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/honor.json b/test/data/ua/device/honor.json new file mode 100644 index 0000000..321e51b --- /dev/null +++ b/test/data/ua/device/honor.json @@ -0,0 +1,164 @@ +[ + { + "desc": "Honor MagicPad 13 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; GDI-W09 Build/HONORGDI-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "GDI-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 2", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; en-nz; JDN-W09 Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/6.0 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "JDN-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 2", + "ua": "Mozilla/5.0 (Linux; U; Android 9; zh-Hans-CN; JDN2-W09HN Build/HUAWEIJDN2-W09HN) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.6.6.164 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "JDN2-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 7 10.1", + "ua": "Mozilla/5.0 (Linux; Android 12; AGM3-AL09HN Build/HONORAGM3-AL09HN; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.46 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/490.0.0.63.82;IABMV/1;]", + "expect": { + "vendor": "Honor", + "model": "AGM3-AL09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 8 12.0", + "ua": "Mozilla/5.0 (Linux; Android 12; HEY-W09 Build/HONORHEY-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "HEY-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 9 12.1", + "ua": "Mozilla/5.0 (Linux; Android 13; HEY2-N09 Build/HONORHEY2-N09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 [FB_IAB/FB4A;FBAV/465.0.0.63.83;]", + "expect": { + "vendor": "Honor", + "model": "HEY2-N09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad 9 12.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; HEY2-W09 Build/HONORHEY2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/129.0.6668.102 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", + "expect": { + "vendor": "Honor", + "model": "HEY2-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad V7 Pro 11", + "ua": "Mozilla/5.0 (Linux; Android 12; BRT-AN09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 EdgA/109.0.1518.53", + "expect": { + "vendor": "Honor", + "model": "BRT-AN09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad V7 Pro 11 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; BRT-W09 Build/HONORBRT-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.5.0.336 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "BRT-W09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X6", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09HN Build/HUAWEIAGR-W09HN; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.9 SP-engine/2.28.0 baiduboxapp/12.9.0.11 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Honor", + "model": "AGR-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X7 8 LTE", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-AL00HN; HMSCore 6.0.0.306) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.3.300 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "KOB2-AL00HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X7 8 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-W09HN; HMSCore 6.1.0.314) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 HuaweiBrowser/12.0.0.301 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "KOB2-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X8 Lite", + "ua": "Mozilla/5.0 (Linux; Android 12; AGM-W09HN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "AGM-W09HN", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X9 11.5 LTE", + "ua": "Mozilla/5.0 (Linux; Android 13; ELN-L09 Build/HONORELN-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Mobile Safari/537.36[FBAN/EMA;FBLC/zh_CN;FBAV/432.0.0.9.110;FBCX/modulariab;]", + "expect": { + "vendor": "Honor", + "model": "ELN-L09", + "type": "tablet" + } + }, + { + "desc": "Honor Pad X9 11.5 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 13; ELN-W09 Build/HONORELN-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "ELN-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei Honor 6A", + "ua": "Mozilla/5.0 (Linux; Android 7.0; DLI-L22 Build/HONORDLI-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/252.0.0.22.355;]", + "expect": { + "vendor": "Honor", + "model": "DLI-L22", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 7", + "ua": "Mozilla/5.0 (Linux; Android 6.0; PLK-L01 Build/HONORPLK-L01; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "PLK-L01", + "type": "mobile" + } + }, + { + "desc": "Huawei 10 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; HRY-LX1 Build/HONORHRY-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", + "expect": { + "vendor": "Honor", + "model": "HRY-LX1", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/htc.json b/test/data/ua/device/htc.json new file mode 100644 index 0000000..51ff339 --- /dev/null +++ b/test/data/ua/device/htc.json @@ -0,0 +1,29 @@ +[ + { + "desc": "HTC Desire 820", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; HTC Desire 820 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", + "expect": { + "vendor": "HTC", + "model": "Desire 820", + "type": "mobile" + } + }, + { + "desc": "HTC Evo Shift 4G", + "ua": "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0", + "expect": { + "vendor": "Sprint", + "model": "APA7373KT", + "type": "mobile" + } + }, + { + "desc": "HTC Nexus 9", + "ua": "Mozilla/5.0 (Linux; Android 5.0; Nexus 9 Build/LRX21R) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Mobile Crosswalk/7.36.154.13 Safari/537.36", + "expect": { + "vendor": "HTC", + "model": "Nexus 9", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/huawei.json b/test/data/ua/device/huawei.json new file mode 100644 index 0000000..670879e --- /dev/null +++ b/test/data/ua/device/huawei.json @@ -0,0 +1,947 @@ +[ + { + "desc": "Huawei Honor", + "ua": "Mozilla/5.0 (Linux; U; Android 2.3; xx-xx; U8860 Build/HuaweiU8860) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", + "expect": { + "vendor": "Huawei", + "model": "U8860", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L41) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L41", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-AL10", + "type": "mobile" + } + }, + { + "desc": "Huawei Nexus 6P", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC19V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537", + "expect": { + "vendor": "Huawei", + "model": "Nexus 6P", + "type": "mobile" + } + }, + { + "desc": "Huawei P10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; VTR-L09 Build/HUAWEIVTR-L09; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VTR-L09", + "type": "mobile" + } + }, + { + "desc": "Huawei Y3II", + "ua": "Mozilla/5.0 (Linux; U; Android 5.1; xx-xx; HUAWEI LUA-L03 Build/HUAWEILUA-L03) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LUA-L03", + "type": "mobile" + } + }, + { + "desc": "HUAWEI MediaPad C5 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; MON-AL19B Build/HUAWEIMON-AL19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.83 Mobile Safari/537.36 T7/11.7 baiduboxapp/11.7.0.10 (Baidu; P1 7.0)", + "expect": { + "vendor": "Huawei", + "model": "MON-AL19B", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M2 10.1", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; HUAWEI M2-A01L Build/HUAWEIM2-A01L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/95.0.4638.74 Safari/537.36[FBAN/EMA;FBLC/fr_FR;FBAV/421.0.0.14.100;]", + "expect": { + "vendor": "Huawei", + "model": "M2-A01L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; en-US; BTV-DL09 Build/HUAWEIBEETHOVEN-DL09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11.5.0.1015 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTV-DL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; HUAWEI BTV-W09 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.96 Mobile Safari/537.36 AlohaBrowser/3.1.1", + "expect": { + "vendor": "Huawei", + "model": "BTV-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 Lite", + "ua": "Mozilla/5.0 (Linux; Android 7.0; CPN-L09 Build/HUAWEICPN-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36[FBAN/EMA;FBLC/ru_RU;FBAV/233.0.0.12.118;]", + "expect": { + "vendor": "Huawei", + "model": "CPN-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 Lite", + "ua": "Mozilla/5.0 (Linux; Android 7.0; CPN-W09 Build/HUAWEICPN-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.71 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/374.0.0.20.109;]", + "expect": { + "vendor": "Huawei", + "model": "CPN-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M3 Lite 10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BAH-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 10.8", + "ua": "Mozilla/5.0 (Linux; Android 9; CMR-W09 Build/HUAWEICMR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.102 Safari/537.36 Line/14.18.1/IAB", + "expect": { + "vendor": "Huawei", + "model": "CMR-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; BAH2-W19 Build/HUAWEIBAH2-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH2-W19", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; JDN2-W09 Build/HUAWEIJDN2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/90.0.4430.210 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/318.0.0.39.154;]", + "expect": { + "vendor": "Huawei", + "model": "JDN2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; JDN2-AL50 Build/HUAWEIJDN2-AL50; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.13.0 SP-engine/2.29.0 matrixstyle/0 lite baiduboxapp/5.8.0.10 (Baidu; P1 9) NABar/1.", + "expect": { + "vendor": "Huawei", + "model": "JDN2-AL50", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5 8.4", + "ua": "Mozilla/5.0 (Linux; Android 9; SHT-W09 Build/HUAWEISHT-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.87 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SHT-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M5", + "ua": "Mozilla/5.0 (Linux; Android 9; SHT-AL09 Build/HUAWEISHT-AL09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SHT-AL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M6 10.8", + "ua": "Mozilla/5.0 (Linux; Android 14; SCM-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6612.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SCM-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad M6 8.4", + "ua": "Mozilla/5.0 (Linux; Android 9; VRD-W09; HMSCore 6.14.0.321; GMSCore 22.26.15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VRD-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T5", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-L09 Build/HUAWEIAGS2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.125 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS2-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10", + "ua": "Mozilla/5.0 (Linux; U; Android 10; en-US; AGR-L09 Build/HUAWEIAGR-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.3.8.1305 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09 Build/HUAWEIAGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS3-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T 8.0", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-L09 Build/HUAWEIKOB2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/396.0.0.21.104;]", + "expect": { + "vendor": "Huawei", + "model": "KOB2-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T 8.0", + "ua": "Mozilla/5.0 (Linux; Android 10; KOB2-W09 Build/HUAWEIKOB2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 Mobile Safari/537.36 HuaweiBrowser/15.0.4.312 HMSCore/6.14.0.301", + "expect": { + "vendor": "Huawei", + "model": "KOB2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; T1-A21w Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Safari/537.36 SputnikBrowser/1.2.8.161", + "expect": { + "vendor": "Huawei", + "model": "T1-A21w", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; T1-A23L Build/HuaweiMediaPad; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 BingWeb/6.9.10", + "expect": { + "vendor": "Huawei", + "model": "T1-A23L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 10", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; T1-A21L Build/HuaweiMediaPad) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.93 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "T1-A21L", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 7", + "ua": "Mozilla/5.0 (Linux; 4.4.2; T1-701u) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "T1-701u", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T1 8", + "ua": "Mozilla/5.0 (Linux; U; Android 9.0; MediaPad T1 8.0 Build/HuaweiMediaPad) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30 OPR/28.0.2254.119224", + "expect": { + "vendor": "Huawei", + "model": "MediaPad T1 8.0", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10 9.7", + "ua": "Mozilla/5.0 (Linux; U; Android 10; en-US; AGRK-L09 Build/HUAWEIAGRK-L09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.6.0.1315 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGRK-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10 9.7 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; AGRK-W09; HMSCore 6.14.0.321) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGRK-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s 10.1 LTE", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3K-L09 Build/HUAWEIAGS3K-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36 [FB_IAB/FB4A;FBAV/362.0.0.27.109;]", + "expect": { + "vendor": "Huawei", + "model": "AGS3K-L09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T10s 10.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; AGS3K-W09; HMSCore 6.14.0.321) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS3K-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T2 10.0 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; 605HW Build/HuaweiMediaPad; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.78 Safari/537.36 [FB_IAB/FB4A;FBAV/436.0.0.35.101;]", + "expect": { + "vendor": "Huawei", + "model": "605HW", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T2 7.0 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0; BGO-DL09 Build/HuaweiBAGGIO; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/407.0.0.30.97;]", + "expect": { + "vendor": "Huawei", + "model": "BGO-DL09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; AGS-W09 Build/HUAWEIAGS-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.90 Safari/537.36 GSA/10.83.10.21.arm64", + "expect": { + "vendor": "Huawei", + "model": "AGS-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 7", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BG2-U03 Build/HUAWEIBG2-U03; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.111 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BG2-U03", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T3 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; KOB-W09 Build/HUAWEIKOB-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 Safari/537.36 [FB_IAB/Orca-Android;FBAV/354.0.0.10.113;]", + "expect": { + "vendor": "Huawei", + "model": "KOB-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad T5 10", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-W09 Build/HUAWEIAGS2-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Huawei", + "model": "AGS2-W09", + "type": "tablet" + } + }, + { + "desc": "HUAWEI MediaPad X2", + "ua": "Mozilla/5.0 (Linux; Android 8.0; GEM-703L Build/HUAWEIGEM-703L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/043906 Mobile Safari/537.36 MicroMessenger/6.6.3.1260(0x26060339) NetType/WIFI Language/zh_", + "expect": { + "vendor": "Huawei", + "model": "GEM-703L", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH3-W09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH3-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH3-L09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH3-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; BAH3-W59 Build/HUAWEIBAH3-W59; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36HiSearch/22.0.6.315", + "expect": { + "vendor": "Huawei", + "model": "BAH3-W59", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 (2022)", + "ua": "Mozilla/5.0 (Linux; Android 10; BAH4-L09 Build/HUAWEIBAH4-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH4-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 (2022) WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; BAH4-W09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BAH4-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 SE", + "ua": "Mozilla/5.0 (Linux; Android 12; AGS5-L09 Build/HUAWEIAGS5-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS5-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 10.4 SE WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; AGS5-W09 Build/HUAWEIAGS5-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Safari/537.36 [FB_IAB/FB4A;FBAV/480.0.0.54.88;]", + "expect": { + "vendor": "Huawei", + "model": "AGS5-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11 (2023) WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; DBR-W10 Build/HUAWEIDBR-W10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.9.6.501 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DBR-W10", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11 WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-cn; DBY-W09 Build/HUAWEIDBY-W09) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.86 MQQBrowser/14.6 Mobile Safari/537.36 COVC/046801", + "expect": { + "vendor": "Huawei", + "model": "DBY-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 Air WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; DBY2-W00 Build/HUAWEIDBY2-W00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/7.3.8.663 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DBY2-W00", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 LTE", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; BTK-AL09; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTK-AL09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 S WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; TGR-W09; HMSCore 6.14.0.322; GMSCore 0.3.3.1.240913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 HuaweiBrowser/14.0.2.317 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TGR-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad 11.5 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; BTK-W09; HMSCore 6.14.0.322; GMSCore 214816056) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTK-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad C5 8", + "ua": "Mozilla/5.0 (Linux; Android 7.0; MON-W19 Build/HUAWEIMON-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Mobile Safari/537.36 [Pinterest/Android]", + "expect": { + "vendor": "Huawei", + "model": "MON-W19", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 12; GOT-AL09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 YaBrowser/23.5.5.60.01 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "GOT-AL09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 11 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 12; GOT-W09 Build/HUAWEIGOT-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/97.0.4692.98 Safari/537.36 T7/13.19 BDOS/1.0 (HarmonyOS 3.0.0) SP-engine/2.57.0 baiduboxapp/13.19.0.12 (Baidu; P1 12) NABar/1.0", + "expect": { + "vendor": "Huawei", + "model": "GOT-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 12.6 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; WGR-W09 Build/HUAWEIWGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.105 Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/412.0.0.8.106;]", + "expect": { + "vendor": "Huawei", + "model": "WGR-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad SE 11 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; HarmonyOS; AGS6-W09; HMSCore 6.12.2.309) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.5.315 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGS6-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad Pro 13.2", + "ua": "Mozilla/5.0 (Linux; Android 12; HarmonyOS; PCE-W29; HMSCore 6.14.0.322) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 HuaweiBrowser/15.0.4.312 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "PCE-W29", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T 10", + "ua": "Mozilla/5.0 (Linux; Android 10; AGR-L09; HMSCore 5.0.4.301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.3.304 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AGR-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T10s", + "ua": "Mozilla/5.0 (Linux; U; Android 10; zh-cn; AGS3-AL00 Build/HUAWEIAGS3-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/11.4 Mobile Safari/537.36 COVC/045530", + "expect": { + "vendor": "Huawei", + "model": "AGS3-AL00", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T10s WiFi", + "ua": "Mozilla/5.0 (Linux; U; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/88.0.4324.93 Safari/537.36 OPR/60.0.2254.59405", + "expect": { + "vendor": "Huawei", + "model": "AGS3-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei MatePad T8 8 LTE", + "ua": "Mozilla/5.0 (Linux; U; Android 10; KOB2K-L09 Build/HUAWEIKOB2K-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36 OPR/83.0.2254.73002", + "expect": { + "vendor": "Huawei", + "model": "KOB2K-L09", + "type": "tablet" + } + }, + { + "desc": "Huawei M3", + "ua": "Mozilla/5.0 (Linux; Android 7.0; BTV-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BTV-W09", + "type": "tablet" + } + }, + { + "desc": "Huawei Mate 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 8.0; BLA-L29 Build/HUAWEIBLA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.6 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BLA-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate X", + "ua": "Mozilla/5.0 (Linux; Android 9; TAH-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TAH-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate X2", + "ua": "Mozilla/5.0 (Linux; Android 10; TET-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "TET-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 X", + "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "EVR-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L09", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-AL10", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L0C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L0C", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; LYA-TL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LYA-TL00", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 50 Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; DCO-LX9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DCO-LX9", + "type": "mobile" + } + }, + { + "desc": "Huawei P20 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ANE-LX1", + "type": "mobile" + } + }, + { + "desc": "Huawei P20", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; EML-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "EML-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P20 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "CLT-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P30", + "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ELE-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P30 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "VOG-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei P40", + "ua": "Mozilla/5.0 (Linux; Android 10; ANA-AN00 Build/HUAWEIANA-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/11.26 SP-engine/2.22.0 baiduboxapp/11.26.0.10 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Huawei", + "model": "ANA-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei P40 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; ELS-AN00 Build/HUAWEIELS-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/6.0.0", + "expect": { + "vendor": "Huawei", + "model": "ELS-AN00", + "type": "mobile" + } + }, + { + "desc": "Huawei 30 Pro+", + "ua": "Mozilla/5.0 (Linux; Android 10; EBG-AN10 Build/HUAWEIEBG-AN10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36 EdgA/42.0.0.2741", + "expect": { + "vendor": "Huawei", + "model": "EBG-AN10", + "type": "mobile" + } + }, + { + "desc": "Huawei 30S", + "ua": "Mozilla/5.0 (Linux; Android 10; CDY-AN90 Build/HUAWEICDY-AN90; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/5.8.0", + "expect": { + "vendor": "Huawei", + "model": "CDY-AN90", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L21", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L61", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L71) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L71", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YAL-L61D", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L61A", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L61D", + "type": "mobile" + } + }, + { + "desc": "Huawei Nova 5T", + "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L71A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "YALE-L71A", + "type": "mobile" + } + }, + { + "desc": "Huawei Enjoy10e", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", + "expect": { + "vendor": "Huawei", + "model": "MED-AL00", + "type": "mobile" + } + }, + { + "desc": "Huawei Y7 2018", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; LDN-L01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "LDN-L01", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 8X", + "ua": "Mozilla/5.0 (Linux; Android 9; JSN-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "JSN-L21", + "type": "mobile" + } + }, + { + "desc": "Huawei Y6 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; MRD-LX1N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "MRD-LX1N", + "type": "mobile" + } + }, + { + "desc": "Huawei Y9 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; JKM-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "JKM-LX2", + "type": "mobile" + } + }, + { + "desc": "Huawei Y5", + "ua": "Mozilla/5.0 (Linux; Android 9; AMN-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "AMN-LX3", + "type": "mobile" + } + }, + { + "desc": "Huawei Y7p", + "ua": "Mozilla/5.0 (Linux; Android 9; ART-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "ART-L29", + "type": "mobile" + } + }, + { + "desc": "Huawei Mate 20 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SNE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "SNE-LX1", + "type": "mobile" + } + }, + { + "desc": "Huawei P10 Lite", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; WAS-LX1A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "WAS-LX1A", + "type": "mobile" + } + }, + { + "desc": "Huawei Y5 Lite 2018", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; DRA-LX5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "DRA-LX5", + "type": "mobile" + } + }, + { + "desc": "Huawei Honor 8C", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BKK-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Huawei", + "model": "BKK-LX2", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/imo.json b/test/data/ua/device/imo.json new file mode 100644 index 0000000..e794a80 --- /dev/null +++ b/test/data/ua/device/imo.json @@ -0,0 +1,38 @@ +[ + { + "desc": "IMO FEEL A2", + "ua": "Mozilla/5.0 (Linux; Android 5.1; IMO FEEL A2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/49.0.2623.105 Mobile Safari/537.36", + "expect": { + "vendor": "IMO", + "model": "FEEL A2", + "type": "mobile" + } + }, + { + "desc": "IMO Q2", + "ua": "Mozilla/5.0 (Linux; Android 5.1; IMO Q2 Build/LMY47D; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/65.0.3325.109 Mobile Safari/537.36 GSA/7.22.24.21.arm", + "expect": { + "vendor": "IMO", + "model": "Q2", + "type": "mobile" + } + }, + { + "desc": "IMO S2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; IMO S2 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.162 Mobile Safari/537.36", + "expect": { + "vendor": "IMO", + "model": "S2", + "type": "mobile" + } + }, + { + "desc": "IMO Tab X9", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; id-id; IMO TAB X9 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "IMO", + "model": "TAB X9", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/infinix.json b/test/data/ua/device/infinix.json new file mode 100644 index 0000000..6c356d3 --- /dev/null +++ b/test/data/ua/device/infinix.json @@ -0,0 +1,56 @@ +[ + { + "desc": "Infinix Hot 7 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; Infinix X625C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X625C", + "type": "mobile" + } + }, + { + "desc": "Infinix Hot 10T", + "ua": "Mozilla/5.0 (Linux; Android 11; Infinix X689C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X689C", + "type": "mobile" + } + }, + { + "desc": "Infinix Hot 11s", + "ua": "Mozilla/5.0 (Linux; Android 11; Infinix X6812 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X6812", + "type": "mobile" + } + }, + { + "desc": "Infinix Smart 5", + "ua": "Mozilla/5.0 (Linux; Android 10; Infinix X657C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X657C", + "type": "mobile" + } + }, + { + "desc": "Infinix XPad", + "ua": "Mozilla/5.0 (Linux; Android 14; Infinix X1101B Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.99 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", + "expect": { + "vendor": "Infinix", + "model": "X1101B", + "type": "tablet" + } + }, + { + "desc": "Infinix Zero 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; Infinix X6815B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Infinix", + "model": "X6815B", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/itel.json b/test/data/ua/device/itel.json new file mode 100644 index 0000000..109e6e0 --- /dev/null +++ b/test/data/ua/device/itel.json @@ -0,0 +1,56 @@ +[ + { + "desc": "itel A25", + "ua": "Mozilla/5.0 (Linux; Android 9; itel L5002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.130 Mobile Safari/537.36 OPR/63.3.3216.58675", + "expect": { + "vendor": "itel", + "model": "L5002", + "type": "mobile" + } + }, + { + "desc": "itel A50", + "ua": "Mozilla/5.0 (Linux; U; Android 14; itel A667L Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Mobile Safari/537.36 OPR/83.1.2254.73239", + "expect": { + "vendor": "itel", + "model": "A667L", + "type": "mobile" + } + }, + { + "desc": "itel KidPad 1", + "ua": "Mozilla/5.0 (Linux; Android 10; Itel W7001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", + "expect": { + "vendor": "itel", + "model": "W7001", + "type": "tablet" + } + }, + { + "desc": "itel Pad One", + "ua": "Mozilla/5.0 (Linux; Android 12; itel P10001L Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.172 Safari/537.36", + "expect": { + "vendor": "itel", + "model": "P10001L", + "type": "tablet" + } + }, + { + "desc": "itel RS4", + "ua": "Mozilla/5.0 (Linux; Android 13; itel S666LN Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.165 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/468.1.0.56.78;]", + "expect": { + "vendor": "itel", + "model": "S666LN", + "type": "mobile" + } + }, + { + "desc": "itel Vision 2S", + "ua": "Mozilla/5.0 (Linux; Android 11; itel P651L Build/RP1A.201005.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.76 Mobile Safari/537.36", + "expect": { + "vendor": "itel", + "model": "P651L", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/jolla.json b/test/data/ua/device/jolla.json new file mode 100644 index 0000000..622fea0 --- /dev/null +++ b/test/data/ua/device/jolla.json @@ -0,0 +1,11 @@ +[ + { + "desc": "Jolla", + "ua": "Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0", + "expect": { + "vendor": "Jolla", + "model": "undefined", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/kobo.json b/test/data/ua/device/kobo.json new file mode 100644 index 0000000..6648a9a --- /dev/null +++ b/test/data/ua/device/kobo.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Kobo eReader", + "ua": "Mozilla/5.0 (Unknown; Linux) AppleWebKit/538.1 (KHTML, like Gecko) Kobo eReader Safari/538.1", + "expect": { + "vendor": "Kobo", + "model": "eReader", + "type": "tablet" + } + }, + { + "desc": "Kobo Touch", + "ua": "Mozilla/5.0 (Linux; U; Android 2.0; en-us;) AppleWebKit/538.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/538.1 (Kobo Touch 0377/4.20.14622)", + "expect": { + "vendor": "Kobo", + "model": "Touch", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/lenovo.json b/test/data/ua/device/lenovo.json new file mode 100644 index 0000000..526a3b5 --- /dev/null +++ b/test/data/ua/device/lenovo.json @@ -0,0 +1,1100 @@ +[ + { + "desc": "Lenovo A7", + "ua": "Mozilla/5.0 (Linux; U; Android 9; en-US; Lenovo L19111 Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/13.2.8.1301 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L19111", + "type": "mobile" + } + }, + { + "desc": "Lenovo A8", + "ua": "Mozilla/5.0 (Linux; Android 10; Lenovo L10041) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.73 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L10041", + "type": "mobile" + } + }, + { + "desc": "Lenovo dtab Compact 42A", + "ua": "Mozilla/5.0 (Linux; Android 12; d-42A Build/SKQ1.220201.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.125 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "d-42A", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab A7-50", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo A3500-HV Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "A3500-HV", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab A2109A", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; ru-ru; A2109A Build/JDQ39; CyanogenMod-10.1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "A2109A", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab S6000", + "ua": "Mozilla/5.0 (Linux; Android 6.0; S6000 Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/55.0.2883.91 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "S6000", + "type": "tablet" + } + }, + { + "desc": "Lenovo IdeaTab S6000", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; IdeaTab S6000-H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 YaBrowser/18.11.1.1011.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "IdeaTab S6000-H", + "type": "tablet" + } + }, + { + "desc": "Lenovo K5 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 9;zh-cn; Lenovo L38041 Build/PKQ1.190127.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.117 MobileLenovoBrowser/9.1.3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L38041", + "type": "mobile" + } + }, + { + "desc": "Lenovo K9", + "ua": "Mozilla/5.0 (Linux; U; Android 8.1.0; en-US; Lenovo L38043 Build/O11019) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.89 UCBrowser/11.4.8.1012 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L38043", + "type": "mobile" + } + }, + { + "desc": "Lenovo K10 Plus", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo L39051) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.66 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L39051", + "type": "mobile" + } + }, + { + "desc": "Lenovo K12", + "ua": "Mozilla/5.0 (Linux; Android 10; Lenovo XT2081-4 Build/QCZ30.30-Q3-45-17; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/409.0.0.27.106;]", + "expect": { + "vendor": "Lenovo", + "model": "XT2081-4", + "type": "mobile" + } + }, + { + "desc": "Lenovo K12", + "ua": "Mozilla/5.0 (Linux; U; Android 10; Lenovo K12 Build/QOGS30.569-83-18; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.130 Mobile Safari/537.36 OPR/69.0.2254.66073", + "expect": { + "vendor": "Lenovo", + "model": "K12", + "type": "mobile" + } + }, + { + "desc": "Lenovo Legion 2 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; Lenovo L70081 Build/RKQ1.201112.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.58 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L70081", + "type": "mobile" + } + }, + { + "desc": "Lenovo Legion Y90", + "ua": "Mozilla/5.0 (Linux; U; Android 12;en-us; Lenovo L71061/SKQ1.211113.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.132 MobileLenovoBrowser/8.6.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L71061", + "type": "mobile" + } + }, + { + "desc": "Lenovo Legion Y700", + "ua": "Mozilla/5.0 (Linux; U; Android 13;zh-cn; Lenovo TB-9707F Build/TKQ1.221013.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.117 MobileLenovoBrowser/2.1.7 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-9707F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Legion Y700", + "ua": "Mozilla/5.0 (Linux; Android 12; TB320FC) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB320FC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Moto Tab", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; TB-X704A Build/NMF26F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X704A", + "type": "tablet" + } + }, + { + "desc": "Lenovo Phone", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Lenovo PB2-650M Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/311.0.0.44.117;]", + "expect": { + "vendor": "Lenovo", + "model": "PB2-650M", + "type": "mobile" + } + }, + { + "desc": "Lenovo S5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo L58041) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L58041", + "type": "mobile" + } + }, + { + "desc": "Lenovo Smart Tab M8", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 10; Lenovo TB-8505XS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 YaBrowser/21.11.7.71.00 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8505XS", + "type": "tablet" + } + }, + { + "desc": "Lenovo Smart Tab M8", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 10; Lenovo TB-8505FS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.166 YaBrowser/21.8.4.111.00 (beta) SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8505FS", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 2", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Lenovo TAB 2 A7-30HC Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7-30HC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 2 A7", + "ua": "Mozilla/5.0 (Linux; Android 7.0.99; Lenovo TAB 2 A7-30DC Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.141 Safari/537.36 OPR/45.1.2246.125351", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7-30DC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 2 A10", + "ua": "Mozilla/5.0 (Linux; U; Android 5.0.1; Lenovo TAB 2 A10-70L Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.116 Safari/537.36 OPR/29.0.2254.120398", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A10-70L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 2 A10-30", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; TB2-X30F Build/LenovoTB2-X30F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Mobile Safari/537.36 EdgA/90.0.818.49", + "expect": { + "vendor": "Lenovo", + "model": "TB2-X30F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 7", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Lenovo TB3-730X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB3-730X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 7 Essential", + "ua": "Mozilla/5.0 (Linux; Android 5.1; Lenovo TB3-710I Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.127 Safari/537.36 GSA/5.4.28.19.arm", + "expect": { + "vendor": "Lenovo", + "model": "TB3-710I", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 7 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; en-US; Lenovo TB-7703X Build/S100) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.2.5.1102 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7703X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 8 Dual", + "ua": "Mozilla/5.0 (Linux; Android 6.0; 602LV Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/93.0.4577.82 Safari/537.36 GSA/12.36.22.23.arm64", + "expect": { + "vendor": "Lenovo", + "model": "602LV", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 8 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; Lenovo TB-8703F Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/9.8 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8703F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 8 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; Lenovo TB-8703X Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/65.0.3325.109 Safari/537.36 OPR/33.0.2254.125672", + "expect": { + "vendor": "Lenovo", + "model": "TB-8703X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 10 Business", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; Lenovo TB3-X70F Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Safari/537.36 OPR/32.0.2254.123747", + "expect": { + "vendor": "Lenovo", + "model": "TB3-X70F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 10 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0; Lenovo TB3-X70L Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/86.0.4240.185 Safari/537.36 OPR/52.1.2254.54298", + "expect": { + "vendor": "Lenovo", + "model": "TB3-X70L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X90F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X90F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo TB-X304F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X304F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo TAB 2 A7-30HC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TAB 2 A7-30HC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Lenovo TB-8504F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Mobile Safari/537.36 OPR/64.2.3282.60128", + "expect": { + "vendor": "Lenovo", + "model": "TB-8504F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8", + "ua": "Mozilla/5.0 (Linux; U; Android 8.1.0; Lenovo TB-8504X Build/OPM1.171019.019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36 OPR/52.2.2254.54723", + "expect": { + "vendor": "Lenovo", + "model": "TB-8504X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8 Plus", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 8.1.0; Lenovo TB-8704F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 YaApp_Android/21.21.0/apad YaSearchBrowser/21.21.0/apad BroPP/1.0 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8704F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8 Plus", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; TB-8704V Build/OPM1.171019.019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/104.0.5112.97 Safari/537.36 [FB_IAB/FB4A;FBAV/380.0.0.29.109;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-8704V", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8 Plus", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 8.1.0; Lenovo TB-8704X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 YaBrowser/19.10.4.187.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8704X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 8 REL", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo TB-8X04F Build/NMF26F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.100 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8X04F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 10", + "ua": "Mozilla/5.0 (Linux; U; Android 8.1.0; Lenovo TB-X304L Build/OPM1.171019.026; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.149 Safari/537.36 OPR/47.0.2254.146760", + "expect": { + "vendor": "Lenovo", + "model": "TB-X304L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 10 Plus", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.1.1; Lenovo TB-X704L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 YaBrowser/20.12.4.100.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X704L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 4 10 Plus", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.1.1; Lenovo TB-X704F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 YaBrowser/20.8.5.97.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X704F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 6", + "ua": "Mozilla/5.0 (Linux; Android 11; A101LV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.61 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "A101LV", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 7", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Lenovo TB-7504X Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/119.0.6045.193 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/436.0.0.35.101;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-7504X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 7 Essential", + "ua": "Mozilla/5.0 (Linux; U; Android 7.0; Lenovo TB-7304I Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Safari/537.36 OPR/54.0.2254.56148", + "expect": { + "vendor": "Lenovo", + "model": "TB-7304I", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 7 Essential", + "ua": "Mozilla/5.0 (Linux; Android 7.0; Lenovo TB-7304X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7304X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab 10 10.1", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo TB-X103F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X103F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab E7", + "ua": "Mozilla/5.0 (Linux; arm; Android 8.1.0; Lenovo TB-7104I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 BroPP/1.0 SA/3 Mobile Safari/537.36 YandexSearch/7.52/apad YandexSearchBrowser/7.52", + "expect": { + "vendor": "Lenovo", + "model": "TB-7104I", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab E8", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.0; Lenovo TB-8304F1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 YaBrowser/19.7.4.97.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8304F1", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab K10", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-X6C6X Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X6C6X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab K10", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-X6C6F Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.83 Safari/537.36 [FB_IAB/FB4A;FBAV/488.0.0.78.79;IABMV/1;] FBNV/5", + "expect": { + "vendor": "Lenovo", + "model": "TB-X6C6F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab K11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 10; Lenovo TB-J606N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 YaApp_Android/22.31.1/apad YaSearchBrowser/22.31.1/apad BroPP/1.0 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J606N", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab K11 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-J607Z Build/SKQ1.211103.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.58 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J607Z", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M7", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-7305X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Mobile Safari/537.36 OPR/63.3.3216.58675", + "expect": { + "vendor": "Lenovo", + "model": "TB-7305X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M7", + "ua": "Mozilla/5.0 (Linux; arm; Android 9; Lenovo TB-7305I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 YaApp_Android/20.85.0/apad YaSearchBrowser/20.85.0/apad BroPP/1.0 SA/1 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7305I", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M7 (Gen 3)", + "ua": "Mozilla/5.0 (Linux; Android 11; Lenovo TB-7306F Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Safari/537.36 [FB_IAB/FB4A;FBAV/489.0.0.66.81;IABMV/1;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-7306F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M7 (Gen 3)", + "ua": "Mozilla/5.0 (Linux; arm; Android 11; Lenovo TB-7306X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 YaBrowser/20.12.5.127.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-7306X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8", + "ua": "Mozilla/5.0 (Linux; Android 10; Lenovo TB-8505X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8505X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-8505F Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36 GSA/10.82.8.21.arm64", + "expect": { + "vendor": "Lenovo", + "model": "TB-8505F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8 (Gen 3)", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-TW; Lenovo TB-8506X Build/RP1A.200720.011) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.4.0.1306 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8506X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8 (Gen 4)", + "ua": "Mozilla/5.0 (Linux; Android 13; TB300FU Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/417.0.0.9.97;]", + "expect": { + "vendor": "Lenovo", + "model": "TB300FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8 (Gen 4) (2024)", + "ua": "Mozilla/5.0 (Linux; Android 13; TB301FU Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.170 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/472.0.0.45.79;]", + "expect": { + "vendor": "Lenovo", + "model": "TB301FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M8 FHD", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-8705X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.99 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-8705X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; Android 12; TB310FU) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB310FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; 13; TB310XU) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB310XU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X606F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 YaBrowser/20.9.4.99.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Android 14; Mobile; Lenovo TB-X505F; rv:131.0) Gecko/131.0 Firefox/131.0", + "expect": { + "vendor": "Lenovo", + "model": "TB-X505F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; Android 14; Lenovo TB-X505L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6554.180 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X505L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-X605F Build/PKQ1.190319.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Safari/537.36 [FB_IAB/FB4A;FBAV/298.0.0.46.116;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-X605F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10", + "ua": "Mozilla/5.0 (Linux; U; Android 10; Lenovo TB-X505X Build/QKQ1.191224.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/81.0.4044.138 Safari/537.36 OPR/52.2.2254.54723", + "expect": { + "vendor": "Lenovo", + "model": "TB-X505X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 (Gen 3) ", + "ua": "Mozilla/5.0 (Linux; Android 12; TB328XU Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.58 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB328XU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 (Gen 3) ", + "ua": "Mozilla/5.0 (Linux; Android 12; TB328FU Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.57 Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]", + "expect": { + "vendor": "Lenovo", + "model": "TB328FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD", + "ua": "Mozilla/5.0 (Linux; Android 13; Lenovo TB-X605FC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6481.193 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X605FC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-X605LC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X605LC", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X605L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 YaBrowser/20.12.0.141.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X605L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD Plus", + "ua": "Mozilla/5.0 (Linux; Android 14; Lenovo TB-X606F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6496.93 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD Plus", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo TB-X606FA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5813.205 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606FA", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 FHD Plus", + "ua": "Mozilla/5.0 (Linux; Android 10; Lenovo TB-X606X Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X606X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 HD", + "ua": "Mozilla/5.0 (Linux; U; Android 10; it-it; Lenovo TB-X306F Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36 PHX/6.2", + "expect": { + "vendor": "Lenovo", + "model": "TB-X306F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 HD", + "ua": "Mozilla/5.0 (Linux; U; Android 10; it-it; Lenovo TB-X306F Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36 PHX/6.2", + "expect": { + "vendor": "Lenovo", + "model": "TB-X306F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M10 Plus (Gen 3)", + "ua": "Mozilla/5.0 (Linux; U; Android 10; Lenovo TB-X306X Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/90.0.4430.210 Safari/537.36 OPR/55.1.2254.56965", + "expect": { + "vendor": "Lenovo", + "model": "TB-X306X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab M11", + "ua": "Mozilla/5.0 (Linux; Android 14; TB330FU Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.60 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB330FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P10", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X705L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 YaBrowser/21.3.3.160.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-X705L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; Lenovo TB-J606L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.2311.135 YaBrowser/21.11.5.121.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J606L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-cn; Lenovo TB-J606F Build/RKQ1.210303.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.72 MQQBrowser/12.1 Mobile Safari/537.36 COVC/045830", + "expect": { + "vendor": "Lenovo", + "model": "TB-J606F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Plus", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-J616X Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]", + "expect": { + "vendor": "Lenovo", + "model": "TB-J616X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 (Gen 2)", + "ua": "Mozilla/5.0 (Linux; Android 14; TB350FU Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.46 Safari/537.36 [FB_IAB/FB4A;FBAV/490.0.0.63.82;IABMV/1;]", + "expect": { + "vendor": "Lenovo", + "model": "TB350FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Plus", + "ua": "Mozilla/5.0 (Linux; Android 12; Lenovo TB-J616F Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/129.0.6668.9 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J616F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-CN; Lenovo TB-J706F Build/RKQ1.201112.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/5.8.6.223 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J706F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; Lenovo TB-J706L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 EdgA/103.0.1264.71", + "expect": { + "vendor": "Lenovo", + "model": "TB-J706L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P11 Pro (Gen 2)", + "ua": "Mozilla/5.0 (Linux; Android 13; TB132FU Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB132FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P12", + "ua": "Mozilla/5.0 (Linux; Android 14; TB370FU Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.106 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB370FU", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P12 Pro", + "ua": "Mozilla/5.0 (Linux; Android 13; Lenovo TB-Q706F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-Q706F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab P12 Pro", + "ua": "Mozilla/5.0 (Linux; Android 13; Lenovo TB-Q706Z Build/TKQ1.221013.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-Q706Z", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab QT K11 WiFi", + "ua": "Mozilla/5.0 (Linux; arm; Android 12; Lenovo TB-J6C6F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.114 YaBrowser/22.9.3.82.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J6C6F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab QT K11 Pro WiFi", + "ua": "Mozilla/5.0 (Linux; Android 11; Lenovo TB-J607F Build/RKQ1.201217.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "TB-J607F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab V7", + "ua": "Mozilla/5.0 (Linux; U; Android 9; en-US; Lenovo PB-6505M Build/PKQ1) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.9.9.1155 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "PB-6505M", + "type": "tablet" + } + }, + { + "desc": "Lenovo Tab V7", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo PB-6505Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 YaBrowser/20.9.3.85.00 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "PB-6505Y", + "type": "tablet" + } + }, + { + "desc": "Lenovo X3 Lite", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo X3 Lite) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.88 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "X3 Lite", + "type": "mobile" + } + }, + { + "desc": "Lenovo Yoga Smart Tab", + "ua": "Mozilla/5.0 (Android 11; Mobile; Lenovo YT-X705X; rv:129.0) Gecko/129.0 Firefox/129.0", + "expect": { + "vendor": "Lenovo", + "model": "YT-X705X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Smart Tab", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 10; Lenovo YT-X705F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 YaBrowser/20.2.4.153.01 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT-X705F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Smart Tab", + "ua": "Mozilla/5.0 (Linux; Android 9; Lenovo YT-X705L Build/PKQ1.181218.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Safari/537.36 GSA/11.38.8.23.arm64", + "expect": { + "vendor": "Lenovo", + "model": "YT-X705L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; Lenovo YT3-X50L Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.149 Safari/537.36 OPR/46.0.2254.145391", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X50L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; Lenovo YT3-X50L Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.149 Safari/537.36 OPR/46.0.2254.145391", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X50L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X50M Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-X50M", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 8", + "ua": "Mozilla/5.0(Linux; U; Android 5.1.1; pt-BR; Lenovo YT3-850F Build/LMY47V) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-850F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 8", + "ua": "Mozilla/5.0(Linux; U; Android 5.1.1; lv-LV; Lenovo YT3-850L Build/LMY47V) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-850L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 10", + "ua": "Mozilla/5.0(Linux; U; Android 5.1.1; vi-VN; Lenovo YT3-850M Build/LMY47V) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT3-850M", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 Plus", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo YT-X703L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 OPR/64.2.3282.60128", + "expect": { + "vendor": "Lenovo", + "model": "YT-X703L", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 3 Plus", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; YT-X703F Build/NJH47F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.141 Safari/537.36 OPR/45.0.2246.125120", + "expect": { + "vendor": "Lenovo", + "model": "YT-X703F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tab 11", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 12; Lenovo YT-J706X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.42 YaBrowser/24.1.1.42.01 (beta) Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "YT-J706X", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 8", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.2; ru-ru; Lenovo B6000; Android/4.4.2; Release/08.26.2015) AppleWebKit/534.30 (KHTML, like Gecko) Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "B6000", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 8", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo B6000-H Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 GSA/7.24.32.16.arm", + "expect": { + "vendor": "Lenovo", + "model": "B6000-H", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 8", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; es-us; Lenovo B6000-F/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.2.2 Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "B6000-F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 10", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; ru-ru; Lenovo B8000-F Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "B8000-F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 10", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; ru-ru; Lenovo B8000-H Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30 Mobile UCBrowser/3.4.3.532", + "expect": { + "vendor": "Lenovo", + "model": "B8000-H", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 10 HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-US; Lenovo B8080-H Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.0.0.1088 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "B8080-H", + "type": "tablet" + } + }, + { + "desc": "Lenovo Yoga Tablet 10 HD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; ru-ru; Lenovo B8080-F/JLS36C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.3 Mobile Safari/534.30", + "expect": { + "vendor": "Lenovo", + "model": "B8080-F", + "type": "tablet" + } + }, + { + "desc": "Lenovo Z6", + "ua": "Mozilla/5.0 (Linux; U; Android 9;zh-cn; Lenovo L78121 Build/PKQ1.190319.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.117 MobileLenovoBrowser/9.1.3 Mobile Safari/537.36", + "expect": { + "vendor": "Lenovo", + "model": "L78121", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/lg.json b/test/data/ua/device/lg.json new file mode 100644 index 0000000..9d63ac1 --- /dev/null +++ b/test/data/ua/device/lg.json @@ -0,0 +1,191 @@ +[ + { + "desc": "LG V40 ThinQ", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-V405) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-V405", + "type": "mobile" + } + }, + { + "desc": "LG K30", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; LM-X410.F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-X410.F", + "type": "mobile" + } + }, + { + "desc": "LG K30", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-X410.FGN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-X410.FGN", + "type": "mobile" + } + }, + { + "desc": "LG K40", + "ua": "Mozilla/5.0 (Linux; Android 10; LM-X420) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-X420", + "type": "mobile" + } + }, + { + "desc": "LG Stylo 4", + "ua": "Mozilla/5.0 (Linux; Android 10; LM-Q710(FGN)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36", + "expect": { + "vendor": "undefined", + "model": "LM-Q710(FGN)", + "type": "mobile" + } + }, + { + "desc": "LG Stylo 5", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-Q720) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-Q720", + "type": "mobile" + } + }, + { + "desc": "LG G7 ThinQ", + "ua": "Mozilla/5.0 (Linux; Android 9; LM-G710VM Build/PKQ1.181105.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-G710VM", + "type": "mobile" + } + }, + { + "desc": "LG K20", + "ua": "Mozilla/5.0 (Android 13; Mobile; LG-M255; rv:111.0) Gecko/111.0 Firefox/111.0", + "expect": { + "vendor": "LG", + "model": "M255", + "type": "mobile" + } + }, + { + "desc": "LG K500", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; LG-K500 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "K500", + "type": "mobile" + } + }, + { + "desc": "LG Nexus 4", + "ua": "Mozilla/5.0 (Linux; Android 4.2.1; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", + "expect": { + "vendor": "LG", + "model": "Nexus 4", + "type": "mobile" + } + }, + { + "desc": "LG Nexus 4", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; Google Nexus 4 - 4.3 - API 18 - 768x1280 Build/JLS36G) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "LG", + "model": "Nexus 4", + "type": "mobile" + } + }, + { + "desc": "LG Nexus 5", + "ua": "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", + "expect": { + "vendor": "LG", + "model": "Nexus 5", + "type": "mobile" + } + }, + { + "desc": "LG Wing", + "ua": "Mozilla/5.0 (Linux; Android 10; LM-F100N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LM-F100N", + "type": "mobile" + } + }, + { + "desc": "LG Smart TV", + "ua": "Mozilla/5.0 (DirectFB; U; Linux mips; en) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) LG Browser (; LG NetCast.TV-2011)", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "LG Smart TV", + "ua": "Mozilla/5.0 (Linux; NetCast; U) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/53.0.2785 34 Safari/537.31 SmartTV/8.5", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "LG Smart TV", + "ua": "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.41 (KHTML, like Gecko) Large Screen Safari/537.41 LG Browser/7.00.00(LGE; 42LB670V-ZA; 05.05.90; 1); webOS.TV-2014; LG NetCast.TV-2013 Compatible (LGE, 42LB670V-ZA, wireless)", + "expect": { + "vendor": "LG", + "model": "42LB670V-ZA", + "type": "smarttv" + } + }, + { + "desc": "LG Android TV", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; LG Android TV Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "LG", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "LG VK Series Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; VK700 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.84 Safari/537.36", + "expect": { + "vendor": "LG", + "model": "VK700", + "type": "tablet" + } + }, + { + "desc": "LG LK Series Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.0.1; LGLK430 Build/LRX21Y) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Safari/537.36", + "expect": { + "vendor": "LG", + "model": "LK430", + "type": "tablet" + } + }, + { + "desc": "LG Watch Urbane", + "ua": "Mozilla/5.0 Linux; Android 7.1.1; LG Watch Urbane Build/NWD1.180306.004 AppleWebKit/537.36 KHTML, like Gecko Chrome/19.77.34.5 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "Watch Urbane", + "type": "wearable" + } + }, + { + "desc": "LG G Watch R", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; G Watch R Build/LCA44B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Crosswalk/15.44.384.12 Mobile Safari/537.36", + "expect": { + "vendor": "LG", + "model": "G Watch R", + "type": "wearable" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/meizu.json b/test/data/ua/device/meizu.json new file mode 100644 index 0000000..e18fdf0 --- /dev/null +++ b/test/data/ua/device/meizu.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Meizu M5 Note", + "ua": "Mozilla/5.0 (Linux; Android 6.0; M5 Note Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043024 Safari/537.36 MicroMessenger/6.5.7.1040 NetType/WIFI Language/zh_CN", + "expect": { + "vendor": "Meizu", + "model": "M5 Note", + "type": "mobile" + } + }, + { + "desc": "Meizu M3S", + "ua": "Mozilla/5.0 (X11; Linux; Android 5.1; MZ-M3s Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrom/45.0.2454.94 Mobile Safari/537.36", + "expect": { + "vendor": "Meizu", + "model": "M3s", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/micromax.json b/test/data/ua/device/micromax.json new file mode 100644 index 0000000..0416420 --- /dev/null +++ b/test/data/ua/device/micromax.json @@ -0,0 +1,30 @@ +[ + + { + "desc": "Micromax Bharat 2 Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 7.0; en-US; Micromax Q402Plus Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.12.9.1226 Mobile Safari/537.36", + "expect": { + "vendor": "Micromax", + "model": "Q402Plus", + "type": "mobile" + } + }, + { + "desc": "Micromax Canvas Infinity", + "ua": "Mozilla/5.0 (Linux; U; Android 7.1.2; en-US; Micromax HS2 Build/N2G47H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/13.2.0.1296 (SpeedMode) U4/1.0 UCWEB/2.0 Mobile Safari/534.30", + "expect": { + "vendor": "Micromax", + "model": "HS2", + "type": "mobile" + } + }, + { + "desc": "Micromax In 1b", + "ua": "Mozilla/5.0 (Linux; U; Android 10; Micromax E7533 Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36 OPR/54.0.2254.56148", + "expect": { + "vendor": "Micromax", + "model": "E7533", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/microsoft.json b/test/data/ua/device/microsoft.json new file mode 100644 index 0000000..79c3511 --- /dev/null +++ b/test/data/ua/device/microsoft.json @@ -0,0 +1,47 @@ +[ + { + "desc": "Microsoft Lumia 950", + "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", + "expect": { + "vendor": "Microsoft", + "model": "Lumia 950", + "type": "mobile" + } + }, + { + "desc": "Microsoft Surface Duo", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; Surface Duo Build/2020.1014.61)", + "expect": { + "vendor": "Microsoft", + "model": "Surface Duo", + "type": "tablet" + } + }, + { + "desc": "Microsoft Lumia 950", + "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", + "expect": { + "vendor": "Microsoft", + "model": "Lumia 950", + "type": "mobile" + } + }, + { + "desc": "Xbox", + "ua": "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)", + "expect": { + "vendor": "Microsoft", + "model": "Xbox", + "type": "console" + } + }, + { + "desc": "Xbox One", + "ua": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; Xbox; Xbox One)", + "expect": { + "vendor": "Microsoft", + "model": "Xbox One", + "type": "console" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/motorola.json b/test/data/ua/device/motorola.json new file mode 100644 index 0000000..b9227ba --- /dev/null +++ b/test/data/ua/device/motorola.json @@ -0,0 +1,92 @@ +[ + { + "desc": "Motorola Moto X", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; XT1097 Build/KXE21.187-38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.109 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "XT1097", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto Z3 Play", + "ua": "Mozilla/5.0 (Linux; Android 9; Moto Z3 Play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Moto Z3 Play", + "type": "mobile" + } + }, + { + "desc": "Motorola Nexus 6", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.20 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Nexus 6", + "type": "mobile" + } + }, + { + "desc": "Motorola Droid RAZR 4G", + "ua": "Mozilla/5.0 (Linux; U; Android 2.3; xx-xx; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", + "expect": { + "vendor": "Motorola", + "model": "DROID RAZR 4G", + "type": "mobile" + } + }, + { + "desc": "Motorola RAZR 2019", + "ua": "Mozilla/5.0 (Linux; Android 9; motorola razr) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.1 Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "razr", + "type": "mobile" + } + }, + { + "desc": "Moto X", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2; xx-xx; XT1058 Build/13.9.0Q2.X-70-GHOST-ATT_LE-2) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Motorola", + "model": "XT1058", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto g(6) Play", + "ua": "Mozilla/5.0 (Linux; Android 9; moto g(6) play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "moto g(6) play", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto g(7) Supra", + "ua": "Mozilla/5.0 (Linux; Android 9; moto g(7) supra Build/PCOS29.114-134-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/73.0.3683.90 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "moto g(7) supra", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto E", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Moto E (4) Build/NDQS26.69-64-11-7; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Moto E (4)", + "type": "mobile" + } + }, + { + "desc": "Motorola Moto 360", + "ua": "Mozilla/5.0 (Linux; Android 4.4; Moto 360 Build/KNX01S) AppleWebKit/537.36 (KHTML, like Gecko) WIB/0.9.8 Mobile Safari/537.36", + "expect": { + "vendor": "Motorola", + "model": "Moto 360", + "type": "wearable" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/nintendo.json b/test/data/ua/device/nintendo.json new file mode 100644 index 0000000..eb879b3 --- /dev/null +++ b/test/data/ua/device/nintendo.json @@ -0,0 +1,47 @@ +[ + { + "desc": "Nintendo Switch", + "ua": "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", + "expect": { + "vendor": "Nintendo", + "model": "Switch", + "type": "console" + } + }, + { + "desc": "Nintendo WiiU", + "ua": "Mozilla/5.0 (Nintendo WiiU) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.4.2.9 NintendoBrowser/4.2.0.11146.EU", + "expect": { + "vendor": "Nintendo", + "model": "WiiU", + "type": "console" + } + }, + { + "desc": "Nintendo Wii", + "ua": "Opera/9.10 (Nintendo Wii; U; ; 1621; en)", + "expect": { + "vendor": "Nintendo", + "model": "Wii", + "type": "console" + } + }, + { + "desc": "Nintendo 3DS", + "ua": "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7610.EU", + "expect": { + "vendor": "Nintendo", + "model": "3DS", + "type": "console" + } + }, + { + "desc": "Nintendo 3DS", + "ua": "Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.EU", + "expect": { + "vendor": "Nintendo", + "model": "3DS", + "type": "console" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/nokia.json b/test/data/ua/device/nokia.json new file mode 100644 index 0000000..375cfcc --- /dev/null +++ b/test/data/ua/device/nokia.json @@ -0,0 +1,119 @@ +[ + { + "desc": "Nokia3xx", + "ua": "Nokia303/14.87 CLDC-1.1", + "expect": { + "vendor": "Nokia", + "model": "303", + "type": "mobile" + } + }, + { + "desc": "Nokia 3.2", + "ua": "Mozilla/5.0 (Linux; Android 10; Nokia 3.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "3.2", + "type": "mobile" + } + }, + { + "desc": "Nokia 5800 XpressMusic", + "ua": "Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Nokia5800d-1/10.4.016; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413", + "expect": { + "vendor": "Nokia", + "model": "5800d-1", + "type": "mobile" + } + }, + { + "desc": "Nokia 7", + "ua": "Mozilla/5.0 (Linux; Android 11; Nokia 7.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "7.2", + "type": "mobile" + } + }, + { + "desc": "Nokia 808 PureView", + "ua": "Mozilla/5.0 (Symbian; U; Nokia808 PureView; en-GB) AppleWebKit/534.3 (KHTML, like Gecko) Version/3.0 Mobile/1A543a Mobile Safari/534.3", + "expect": { + "vendor": "Nokia", + "model": "808 PureView", + "type": "mobile" + } + }, + { + "desc": "Nokia 808 PureView", + "ua": "Mozilla/5.0 (Symbian/3; Series60/5.5 Nokia808PureView/113.010.1508; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/535.1 (KHTML, like Gecko) NokiaBrowser/8.3.2.21 Mobile Safari/535.1 3gpp-gba", + "expect": { + "vendor": "Nokia", + "model": "808PureView", + "type": "mobile" + } + }, + { + "desc": "Nokia Lumia 630", + "ua": "UCWEB/2.0 (Windows; U; wds 8.10; en-IN; NOKIA; RM-978_1046) U2/1.0.0 UCBrowser/4.2.0.524 U2/1.0.0 Mobile", + "expect": { + "vendor": "Nokia", + "model": "RM-978", + "type": "mobile" + } + }, + { + "desc": "Nokia N9", + "ua": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", + "expect": { + "vendor": "Nokia", + "model": "N9", + "type": "mobile" + } + }, + { + "desc": "Nokia N900", + "ua": "Mozilla/5.0 (Linux; Maemo 5.0; Nokia N900; Build/4.0.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Mobile Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "N900", + "type": "mobile" + } + }, + { + "desc": "Nokia T20", + "ua": "Mozilla/5.0 (Linux; Android 12; Nokia T20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "T20", + "type": "tablet" + } + }, + { + "desc": "Nokia T20", + "ua": "Mozilla/5.0 (Linux; Android 11; Nokia T20 Build/RP1A.201005.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/93.0.4577.62 Safari/537.36", + "expect": { + "vendor": "Nokia", + "model": "T20", + "type": "tablet" + } + }, + { + "desc": "Nokia T21", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; Nokia T21 Build/TP1A.220624.014)", + "expect": { + "vendor": "Nokia", + "model": "T21", + "type": "tablet" + } + }, + { + "desc": "Nokia 2720 Flip", + "ua": "Mozilla/5.0 (Mobile; Nokia_2720_Flip; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.2", + "expect": { + "vendor": "Nokia", + "model": "2720 Flip", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/nothing.json b/test/data/ua/device/nothing.json new file mode 100644 index 0000000..56dc460 --- /dev/null +++ b/test/data/ua/device/nothing.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Nothing 1", + "ua": "Mozilla/5.0 (Linux; Android 13; A063) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36", + "expect": { + "vendor": "Nothing", + "model": "A063", + "type": "mobile" + } + }, + { + "desc": "Nothing 2", + "ua": "Mozilla/5.0 (Linux; Android 14; A065 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.53 Mobile Safari/537.36", + "expect": { + "vendor": "Nothing", + "model": "A065", + "type": "mobile" + } + }, + { + "desc": "Nothing 2a", + "ua": "Mozilla/5.0 (Linux; Android 14; A142 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.71 Mobile Safari/537.36", + "expect": { + "vendor": "Nothing", + "model": "A142", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/nvidia.json b/test/data/ua/device/nvidia.json new file mode 100644 index 0000000..96a2afc --- /dev/null +++ b/test/data/ua/device/nvidia.json @@ -0,0 +1,47 @@ +[ + { + "desc": "Tegra Note 7", + "ua": "Mozilla/5.0 (Linux; Android 5.1; TegraNote-P1640 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "TegraNote-P1640", + "type": "tablet" + } + }, + { + "desc": "Nvidia Shield", + "ua": "Mozilla/5.0 (Linux; Android 5.1; SHIELD) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD", + "type": "console" + } + }, + { + "desc": "Nvidia Shield Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SHIELD Tablet Build/LVY48E; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.19 Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD Tablet", + "type": "tablet" + } + }, + { + "desc": "Nvidia Shield Tablet K1", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SHIELD Tablet K1 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Safari/537.36", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD Tablet K1", + "type": "tablet" + } + }, + { + "desc": "Nvidia Shield TV", + "ua": "Mozilla/5.0 (Linux; Android 11; SHIELD Android TV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36 ", + "expect": { + "vendor": "Nvidia", + "model": "SHIELD Android TV", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/oneplus.json b/test/data/ua/device/oneplus.json new file mode 100644 index 0000000..74ddcf6 --- /dev/null +++ b/test/data/ua/device/oneplus.json @@ -0,0 +1,128 @@ +[ + { + "desc": "OnePlus One", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A0001", + "type": "mobile" + } + }, + { + "desc": "OnePlus One", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; OnePlus One A0001 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A0001", + "type": "mobile" + } + }, + { + "desc": "OnePlus 2", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ONE A2003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A2003", + "type": "mobile" + } + }, + { + "desc": "OnePlus 3", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ONEPLUS A3000 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A3000", + "type": "mobile" + } + }, + { + "desc": "OnePlus 6", + "ua": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A6003", + "type": "mobile" + } + }, + { + "desc": "OnePlus 6T", + "ua": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6010) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "A6010", + "type": "mobile" + } + }, + { + "desc": "OnePlus 8T", + "ua": "Mozilla/5.0 (Linux; Android 11; KB2005) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "KB2005", + "type": "mobile" + } + }, + { + "desc": "OnePlus 8 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; IN2025) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.119 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "IN2025", + "type": "mobile" + } + }, + { + "desc": "OnePlus Nord N100", + "ua": "Mozilla/5.0 (Linux; Android 10; BE2015 Build/QKQ1.200719.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "BE2015", + "type": "mobile" + } + }, + { + "desc": "OnePlus Nord N10 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; BE2029) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "BE2029", + "type": "mobile" + } + }, + { + "desc": "OnePlus Pad Go 11.35", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 14; OPD2304) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.629 YaApp_Android/24.101/apad YaSearchBrowser/24.101/apad BroPP/1.0 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2304", + "type": "tablet" + } + }, + { + "desc": "OnePlus Pad 2 12.1 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; OPD2403 Build/UKQ1.231108.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2403", + "type": "tablet" + } + }, + { + "desc": "OnePlus Pad 11.61 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 14; OPD2203 Build/UKQ1.230924.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36", + "expect": { + "vendor": "OnePlus", + "model": "OPD2203", + "type": "tablet" + } + }, + { + "desc": "OnePlus Watch 2", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; OPWWE231 Build/TWR7.231113.001.OPWWE231_11_A.117.240703)", + "expect": { + "vendor": "OnePlus", + "model": "OPWWE231", + "type": "wearable" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/oppo.json b/test/data/ua/device/oppo.json new file mode 100644 index 0000000..367039e --- /dev/null +++ b/test/data/ua/device/oppo.json @@ -0,0 +1,173 @@ +[ + { + "desc": "OnePlus 10RT", + "ua": "Mozilla/5.0 (Linux; Android 13; CPH2413) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH2413", + "type": "mobile" + } + }, + { + "desc": "OPPO Pad", + "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; OPD2101 Build/TP1A.220905.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "OPD2101", + "type": "tablet" + } + }, + { + "desc": "OPPO Neo", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; R831T Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 OppoBrowser/3.3.2 Mobile Safari/534.30", + "expect": { + "vendor": "OPPO", + "model": "R831T", + "type": "mobile" + } + }, + { + "desc": "OPPO R7s", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; OPPO R7s Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/7.1 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "R7s", + "type": "mobile" + } + }, + { + "desc": "OPPO A3s", + "ua": "Mozilla/5.0 (Linux; Android 8.1; CPH1803 Build/OPM1.171019.026; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH1803", + "type": "mobile" + } + }, + { + "desc": "OPPO A12", + "ua": "Mozilla/5.0 (Linux; Android 9; CPH2083) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH2083", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno", + "ua": "Mozilla/5.0 (Linux; Android 9; PCAT00 Build/PKQ1.190101.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PCAT00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno3 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; PCLM50) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.117 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PCLM50", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 SE", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PEAM00 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PEAM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; PDPM00 Build/QKQ1.200216.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PDPM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno4 Pro 5G", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PDNT00 Build/QKQ1.200216.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PDNT00", + "type": "mobile" + } + }, + { + "desc": "OPPO Reno5 A", + "ua": "Mozilla/5.0 (Linux; Android 11; A101OP) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "A101OP", + "type": "mobile" + } + }, + { + "desc": "OPPO Find X", + "ua": "Mozilla/5.0 (Linux; Android 8.1; PAFM00 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "PAFM00", + "type": "mobile" + } + }, + { + "desc": "OPPO Find 7a", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; xx-xx; X9007 Build/JLS36C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "OPPO", + "model": "X9007", + "type": "mobile" + } + }, + { + "desc": "OPPO F5", + "ua": "ozilla/5.0 (Linux; Android 7.1.1; CPH1723) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "CPH1723", + "type": "mobile" + } + }, + { + "desc": "OPPO Watch 46mm", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; OW19W3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "OW19W3", + "type": "wearable" + } + }, + { + "desc": "OPPO Watch 41mm", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; OW19W2 Build/OPM1.171019.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "OW19W2", + "type": "wearable" + } + }, + { + "desc": "OPPO Watch 2", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; OW20W1 Build/OPM1.171019.026.11_A.37.210713172937; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36", + "expect": { + "vendor": "OPPO", + "model": "OW20W1", + "type": "wearable" + } + }, + { + "desc": "OPPO Watch X", + "ua": "Dalvik/2.1.0 (Linux; U; Android 13; OWWE231 Build/TWR7.231113.001.OWWE231_11_A.117.240703)", + "expect": { + "vendor": "OPPO", + "model": "OWWE231", + "type": "wearable" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/ouya.json b/test/data/ua/device/ouya.json new file mode 100644 index 0000000..1fa74c0 --- /dev/null +++ b/test/data/ua/device/ouya.json @@ -0,0 +1,11 @@ +[ + { + "desc": "Ouya", + "ua": "Mozilla/5.0 (Linux; Android 4.1.2; OUYA Console Build/JZO54L-OUYA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.84 Safari/537.36", + "expect": { + "vendor": "OUYA", + "model": "undefined", + "type": "console" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/panasonic.json b/test/data/ua/device/panasonic.json new file mode 100644 index 0000000..568c21d --- /dev/null +++ b/test/data/ua/device/panasonic.json @@ -0,0 +1,47 @@ +[ + { + "desc": "Panasonic T31", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Panasonic T31 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.170 Mobile Safari/537.36 ", + "expect": { + "vendor": "Panasonic", + "model": "T31", + "type": "mobile" + } + }, + { + "desc": "Panasonic TX-32CSW514 SmartTV", + "ua": "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", + "expect": { + "vendor": "Panasonic", + "model": "VIERA 2015", + "type": "smarttv" + } + }, + { + "desc": "Panasonic TX-40FXW724 SmartTV", + "ua": "HbbTV/1.4.1 (+DRM;Panasonic;SmartTV2018mid;3.024;4301-0003 0002-0000;SmartTV2018;)", + "expect": { + "vendor": "Panasonic", + "model": "SmartTV2018mid", + "type": "smarttv" + } + }, + { + "desc": "Panasonic TX-43HXW904 SmartTV", + "ua": "HbbTV/1.5.1 (+DRM;Panasonic;SmartTV2020mid;3.326;4301-0003 0008-0000;com.panasonic.SmartTV2020mid;)", + "expect": { + "vendor": "Panasonic", + "model": "SmartTV2020mid", + "type": "smarttv" + } + }, + { + "desc": "Panasonic DMR-HST130 SAT receiver", + "ua": "HbbTV/1.1.1 (+PVR;Panasonic;DIGA WebKit M8658;3.420;;)", + "expect": { + "vendor": "Panasonic", + "model": "DIGA WebKit M8658", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/pico.json b/test/data/ua/device/pico.json new file mode 100644 index 0000000..2f28212 --- /dev/null +++ b/test/data/ua/device/pico.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Pico 4", + "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.8.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.38 Chrome/105.0.5195.68 VR Safari/537.36", + "expect": { + "vendor": "PICO", + "model": "4", + "type": "xr" + } + }, + { + "desc": "Pico 4", + "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0", + "expect": { + "vendor": "PICO", + "model": "4", + "type": "xr" + } + }, + { + "desc": "Pico Neo3 Link", + "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", + "expect": { + "vendor": "Pico", + "model": "Neo3 Link", + "type": "xr" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/polytron.json b/test/data/ua/device/polytron.json new file mode 100644 index 0000000..595c27f --- /dev/null +++ b/test/data/ua/device/polytron.json @@ -0,0 +1,38 @@ +[ + { + "desc": "Polytron Prime 7 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 7.0; POLYTRON_P552 Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/64.0.3282.137 Mobile Safari/537.36 OPR/50.0.2254.149182", + "expect": { + "vendor": "POLYTRON", + "model": "P552", + "type": "mobile" + } + }, + { + "desc": "Polytron Rocket T1", + "ua": "Mozilla/5.0 (Linux; U; Android 5.0; en-US; POLYTRON R2501 Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/13.1.2.1293 Mobile Safari/537.36", + "expect": { + "vendor": "POLYTRON", + "model": "R2501", + "type": "mobile" + } + }, + { + "desc": "Polytron Rocket T6", + "ua": "Mozilla/5.0 (Linux; Android 7.0; POLYTRON R2509) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.92 Mobile Safari/537.36", + "expect": { + "vendor": "POLYTRON", + "model": "R2509", + "type": "mobile" + } + }, + { + "desc": "Polytron Zap 6 Posh", + "ua": "Mozilla/5.0 (Linux; U; Android 5.1; in-ID; POLYTRON_4G501 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.10.0.1163 UCTurbo/1.9.9.900 Mobile Safari/537.36", + "expect": { + "vendor": "POLYTRON", + "model": "4G501", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/realme.json b/test/data/ua/device/realme.json new file mode 100644 index 0000000..c16d4d0 --- /dev/null +++ b/test/data/ua/device/realme.json @@ -0,0 +1,74 @@ +[ + { + "desc": "Realme C1", + "ua": "Mozilla/5.0 (Linux; Android 8.1; RMX1811 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1811", + "type": "mobile" + } + }, + { + "desc": "Realme C2", + "ua": "Mozilla/5.0 (Linux; Android 9; RMX1941) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1941", + "type": "mobile" + } + }, + { + "desc": "Realme Narzo 20", + "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; RMX2193 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX2193", + "type": "mobile" + } + }, + { + "desc": "Realme 2 Pro", + "ua": "Mozilla/5.0 (Linux; Android 9; RMX1801) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1801", + "type": "mobile" + } + }, + { + "desc": "Realme 3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; RMX1851) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX1851", + "type": "mobile" + } + }, + { + "desc": "Realme 8", + "ua": "Mozilla/5.0 (Linux; Android 12; RMX3085) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX3085", + "type": "mobile" + } + }, + { + "desc": "Realme 9 Pro", + "ua": "Mozilla/5.0 (Linux; Android 13; RMX3471) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX3471", + "type": "mobile" + } + }, + { + "desc": "Realme GT Master", + "ua": "Mozilla/5.0 (Linux; Android 13; RMX3363) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Realme", + "model": "RMX3363", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/roku.json b/test/data/ua/device/roku.json new file mode 100644 index 0000000..a042f29 --- /dev/null +++ b/test/data/ua/device/roku.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Roku", + "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", + "expect": { + "vendor": "Roku", + "model": "", + "type": "smarttv" + } + }, + { + "desc": "Roku", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Roku/DVP-8.10 (468.10E04145A)", + "expect": { + "vendor": "Roku", + "model": "DVP-8.10", + "type": "smarttv" + } + }, + { + "desc": "Roku", + "ua": "Roku4640X/DVP-7.70 (297.70E04154A)", + "expect": { + "vendor": "Roku", + "model": "DVP-7.70", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/samsung.json b/test/data/ua/device/samsung.json new file mode 100644 index 0000000..56e7b73 --- /dev/null +++ b/test/data/ua/device/samsung.json @@ -0,0 +1,389 @@ +[ + { + "desc": "Samsung Galaxy A21s", + "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-A217F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.0 Chrome/75.0.3770.143 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A217F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A31", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-A315G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A315G", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A50", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-A505F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.105 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A505F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A50s", + "ua": "Mozilla/5.0 (Linux; Android 11; SM-A507FN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A507FN", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A52s", + "ua": "Mozilla/5.0 (Linux; Android 13; SM-A528B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A528B", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy A80", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-A805F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.112 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-A805F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Fold", + "ua": "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-F900U Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.2 Chrome/67.0.3396.87 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F900U", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Z Flip", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-F700N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F700N", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Z Fold2", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-F916B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-F916B", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S10E", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-G970F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G970F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S20 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; SCG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SCG01", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 10+", + "ua": "Mozilla/5.0 (Linux; Android 9; SM-N976V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-N976V", + "type": "mobile" + } + }, + { + "desc": "Samsung SM-C5000", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; SM-C5000 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 wkbrowser 4.1.35 3065", + "expect": { + "vendor": "Samsung", + "model": "SM-C5000", + "type": "mobile" + } + }, + { + "desc": "Samsung C8", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; SM-C7108) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-C7108", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 8", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; GT-N5100 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "GT-N5100", + "type": "tablet" + } + }, + { + "desc": "Samsung SM-T231", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T231 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T231", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab 6 Lite", + "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-P610) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/12.0 Chrome/79.0.3945.136 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-P610", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab A 9.7", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; SM-P550 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-P550", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab A 10.1", + "ua": " Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-T515) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/13.0 Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T515", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab S7", + "ua": "Mozilla/5.0 (Linux; Android 10; SM-T870) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T870", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab S8", + "ua": "Mozilla/5.0 (Linux; Android 12; SM-X706B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-X706B", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab S", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T700 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T700", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Tab Pro 10.1", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T520 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-T520", + "type": "tablet" + } + }, + { + "desc": "Samsung Galaxy Watch", + "ua": "Mozilla/5.0 (Linux; Tizen 5.5; SAMSUNG SM-R805W) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.0 Chrome/69.0.3497.106 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-R805W", + "type": "wearable" + } + }, + { + "desc": "Samsung Galaxy Watch Active 2", + "ua": "Mozilla/5.0 (Linux; Tizen 5.5; SAMSUNG SM-R820) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.0 Chrome/69.0.3497.106 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-R820", + "type": "wearable" + } + }, + { + "desc": "Samsung Galaxy Watch4", + "ua": "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-R875U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.2. Chrome/102.0.5005.125 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-R875U", + "type": "wearable" + } + }, + { + "desc": "Samsung Galaxy Watch5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-R925U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.2. Chrome/111.0.5563.116 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-R925U", + "type": "wearable" + } + }, + { + "desc": "Samsung Galaxy Watch7", + "ua": "Dalvik/2.1.0 (Linux; U; Android 14; SM-L300 Build/AW2E.240318.016)", + "expect": { + "vendor": "Samsung", + "model": "SM-L300", + "type": "wearable" + } + }, + { + "desc": "Samsung Note 10.1", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-P605) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-P605", + "type": "tablet" + } + }, + { + "desc": "Samsung SmartTV2011", + "ua": "HbbTV/1.1.1 (;;;;;) Maple;2011", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2011", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV2012", + "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2012", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV2014", + "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2014;T-NT14UDEUC-1060.4;;) WebKit", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2014", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV", + "ua": "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", + "expect": { + "vendor": "Samsung", + "model": "undefined", + "type": "smarttv" + } + }, + { + "desc": "Samsung SmartTV HBBTV", + "ua": "HbbTV/1.5.1 (+DRM;Samsung;SmartTV2021:UAU7000;T-KSU2EDEUC-1506.0;KantSU2e;urn:samsungtv:familyname:21_KANTSU2E_UHD_BASIC:2021;) Tizen/6.0 (+TVPLUS+SmartHubLink) Chrome/76 LaTivu_1.0.1_2021 RVID/17", + "expect": { + "vendor": "Samsung", + "model": "SmartTV2021:UAU7000", + "type": "smarttv" + } + }, + { + "desc": "Galaxy Nexus", + "ua": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", + "expect": { + "vendor": "Samsung", + "model": "Galaxy Nexus", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy C9 Pro", + "ua": "Mozilla/5.0 (Linux; Android 6.0; SAMSUNG SM-C900F Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.2 Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-C900F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S5", + "ua": "Mozilla/5.0 (Linux; Android 5.0; SM-G900F Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.78 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G900F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy J7 Prime", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SM-G610F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G610F", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S6", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-G920I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G920I", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy S6 Edge", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-G925I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-G925I", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 5 Chrome", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-N920C Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.91 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-N920C", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Note 5 Samsung Browser", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SAMSUNG SM-N920C Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "SM-N920C", + "type": "mobile" + } + }, + { + "desc": "Samsung Galaxy Gear Live", + "ua": "Mozilla/5.0 (Linux; Android 4.4; Gear Live Build/KMV78X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/19.77.34.5 Mobile Safari/537.36", + "expect": { + "vendor": "Samsung", + "model": "Gear Live", + "type": "wearable" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/sharp.json b/test/data/ua/device/sharp.json new file mode 100644 index 0000000..32d5340 --- /dev/null +++ b/test/data/ua/device/sharp.json @@ -0,0 +1,56 @@ +[ + { + "desc": "Sharp AQUOS-TVX19B", + "ua": "Mozilla/5.0 (Linux; Android 9; AQUOS-TVX19B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "AQUOS-TVX19B", + "type": "smarttv" + } + }, + { + "desc": "Sharp Aquos B10", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-A01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-A01", + "type": "mobile" + } + }, + { + "desc": "Sharp Aquos L2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02 Build/S4045) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-L02", + "type": "mobile" + } + }, + { + "desc": "Sharp Aquos L2", + "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-L02", + "type": "mobile" + } + }, + { + "desc": "Sharp Aquos R2", + "ua": "Mozilla/5.0 (Linux; Android 8.0; SHV42) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SHV42", + "type": "mobile" + } + }, + { + "desc": "Docomo SH-02M", + "ua": "Mozilla/5.0 (Linux; Android 9; SH-02M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Sharp", + "model": "SH-02M", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/smartfren.json b/test/data/ua/device/smartfren.json new file mode 100644 index 0000000..5413bb7 --- /dev/null +++ b/test/data/ua/device/smartfren.json @@ -0,0 +1,29 @@ +[ + { + "desc": "Smartfren Andromax L", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Andromax B26D2H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Smartfren", + "model": "Andromax B26D2H", + "type": "mobile" + } + }, + { + "desc": "Smartfren Andromax G2", + "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Smartfren Andromax AD9A1H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.83 Mobile Safari/537.36", + "expect": { + "vendor": "Smartfren", + "model": "Andromax AD9A1H", + "type": "mobile" + } + }, + { + "desc": "Smartfren New Andromax I", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; id-id; New Andromax-i Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Smartfren", + "model": "New Andromax-i", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/sony.json b/test/data/ua/device/sony.json new file mode 100644 index 0000000..92151af --- /dev/null +++ b/test/data/ua/device/sony.json @@ -0,0 +1,218 @@ +[ + { + "desc": "SONY Xperia 1 III", + "ua": "Mozilla/5.0 (Linux; Android 11; A101SO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "A101SO", + "type": "mobile" + } + }, + { + "desc": "Sony G8141 (Xperia XZ1)", + "ua": "Mozilla/5.0 (Linux; Android 9; SO-01K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SO-01K", + "type": "mobile" + } + }, + { + "desc": "Sony G8141 (Xperia XZ Premium)", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; G8141) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "G8141", + "type": "mobile" + } + }, + { + "desc": "Sony C5303 (Xperia SP)", + "ua": "Mozilla/5.0 (Linux; Android 4.3; C5303 Build/12.1.A.1.205) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.93 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "C5303", + "type": "mobile" + } + }, + { + "desc": "Sony SO-02F (Xperia Z1 F)", + "ua": "Mozilla/5.0 (Linux; Android 4.2.2; SO-02F Build/14.1.H.2.119) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SO-02F", + "type": "mobile" + } + }, + { + "desc": "Sony D6653 (Xperia Z3)", + "ua": "Mozilla/5.0 (Linux; Android 4.4; D6653 Build/23.0.A.0.376) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "D6653", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia SOL25 (ZL2)", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4; SOL25 Build/17.1.1.C.1.64) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Sony", + "model": "SOL25", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia SP", + "ua": "Mozilla/5.0 (Linux; Android 4.3; C5302 Build/12.1.A.1.201) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "C5302", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia L4", + "ua": "Mozilla/5.0 (Linux; Android 9; XQ-AD51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AD51", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia 1ii", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AT51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AT51", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia 1ii", + "ua": "Mozilla/5.0 (Linux; Android 10; SOG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SOG01", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia 10ii", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AU52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AU52", + "type": "mobile" + } + }, + { + "desc": "Sony Xperia Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AQ52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "XQ-AQ52", + "type": "mobile" + } + }, + { + "desc": "Sony SGP521 (Xperia Z2 Tablet)", + "ua": "Mozilla/5.0 (Linux; Android 4.4; SGP521 Build/17.1.A.0.432) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, + { + "desc": "Sony Xperia Z2 Tablet", + "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SGP561) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, + { + "desc": "Sony Tablet S", + "ua": "Mozilla/5.0 (Linux; U; Android 3.1; Sony Tablet S Build/THMAS10000) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, + { + "desc": "Sony Tablet Z LTE", + "ua": "Mozilla/5.0 (Linux; U; Android 4.1; SonySGP321 Build/10.2.C.0.143) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", + "expect": { + "vendor": "Sony", + "model": "Xperia Tablet", + "type": "tablet" + } + }, + { + "desc": "Sony BRAVIA 4K GB ATV3", + "ua": "Mozilla/5.0 (Linux; Andr0id 9; BRAVIA 4K GB ATV3 Build/PTT1.190515.001.S38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.0.180.DIA5.104 Model/Sony-BRAVIA-4K-GB-ATV3", + "expect": { + "vendor": "Sony", + "model": "BRAVIA 4K GB ATV3", + "type": "smarttv" + } + }, + { + "desc": "Sony BRAVIA 4K GB ATV3", + "ua": "Mozilla/5.0 (Linux; Android 9; BRAVIA 4K GB ATV3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "BRAVIA 4K GB ATV3", + "type": "smarttv" + } + }, + { + "desc": "Sony Bravia 4k UR2", + "ua": "Mozilla/5.0 (Linux: Andr0id 9: BRAVIA 4K UR2 Build/PTT1.190515.001.S104) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.5.431.DIA5HBBTV.250 Model/Sony-BRAVIA-4K-UR2", + "expect": { + "vendor": "Sony", + "model": "BRAVIA 4K UR2", + "type": "smarttv" + } + }, + { + "desc": "PlayStation 4", + "ua": "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", + "expect": { + "vendor": "Sony", + "model": "PlayStation 4", + "type": "console" + } + }, + { + "desc": "PlayStation 5", + "ua": "Mozilla/5.0 (Playstation; Playstation 5/1.05) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15", + "expect": { + "vendor": "Sony", + "model": "Playstation 5", + "type": "console" + } + }, + { + "desc": "PlayStation Vita", + "ua": "Mozilla/5.0 (PlayStation Vita 3.52) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2", + "expect": { + "vendor": "Sony", + "model": "PlayStation Vita", + "type": "console" + } + }, + { + "desc": "Sony SmartWatch 3", + "ua": "Mozilla/5.0 (Linux; Android 5.0.2; SmartWatch 3 Build/LWX49K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/19.77.34.5 Mobile Safari/537.36", + "expect": { + "vendor": "Sony", + "model": "SmartWatch 3", + "type": "wearable" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/tcl.json b/test/data/ua/device/tcl.json new file mode 100644 index 0000000..8c80537 --- /dev/null +++ b/test/data/ua/device/tcl.json @@ -0,0 +1,488 @@ +[ + { + "desc": "TCL 10 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; T790Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 EdgA/114.0.1823.43", + "expect": { + "vendor": "TCL", + "model": "T790Y", + "type": "mobile" + } + }, + { + "desc": "TCL 10 5G UW", + "ua": "Mozilla/5.0 (Linux; Android 10; T790S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T790S", + "type": "mobile" + } + }, + { + "desc": "TCL 10 Plus", + "ua": "Mozilla/5.0 (Linux; Android 11; T782H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Mobile Safari/537.36 OPR/64.3.3282.60839", + "expect": { + "vendor": "TCL", + "model": "T782H", + "type": "mobile" + } + }, + { + "desc": "TCL 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; T799B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T799B", + "type": "mobile" + } + }, + { + "desc": "TCL 10 SE", + "ua": "Mozilla/5.0 (Linux; Android 10; T766H_RU) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T766H", + "type": "mobile" + } + }, + { + "desc": "TCL 10 TabMax", + "ua": "Mozilla/5.0 (Linux; Android 11; 9296Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9296Q", + "type": "tablet" + } + }, + { + "desc": "TCL 10 TabMax 4G", + "ua": "Mozilla/5.0 (Linux; Android 10; 9295G_EEA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9295G", + "type": "tablet" + } + }, + { + "desc": "TCL 10 TabMax WiFi", + "ua": "Mozilla/5.0 (Linux; Android 10; 9296G_TR) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9296G", + "type": "tablet" + } + }, + { + "desc": "TCL 10L", + "ua": "Mozilla/5.0 (Linux; Android 10; T770B Build/QKQ1.200329.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 GSA/11.41.10.23.arm64", + "expect": { + "vendor": "TCL", + "model": "T770B", + "type": "mobile" + } + }, + { + "desc": "TCL 10L", + "ua": "Mozilla/5.0 (Linux; Android 11; T770H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T770H", + "type": "mobile" + } + }, + { + "desc": "TCL 20 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; T781) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T781", + "type": "mobile" + } + }, + { + "desc": "TCL 20 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T810S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Mobile Safari/537.36 EdgA/113.0.1774.63", + "expect": { + "vendor": "TCL", + "model": "T810S", + "type": "mobile" + } + }, + { + "desc": "TCL 20 SE", + "ua": "Mozilla/5.0 (Linux; Android 11; T671H Build/RKQ1.201112.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.73 Mobile Safari/537.36 GoogleApp/13.9.7.23.arm64", + "expect": { + "vendor": "TCL", + "model": "T671H", + "type": "mobile" + } + }, + { + "desc": "TCL 20 XE", + "ua": "Mozilla/5.0 (Linux; Android 11; 5087Z) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "5087Z", + "type": "mobile" + } + }, + { + "desc": "TCL 20B", + "ua": "Mozilla/5.0 (Linux; Android 11; 6159K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "6159K", + "type": "mobile" + } + }, + { + "desc": "TCL 205", + "ua": "Mozilla/5.0 (Linux; Android 11; 4187D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "4187D", + "type": "mobile" + } + }, + { + "desc": "TCL 20E", + "ua": "Mozilla/5.0 (Linux; Android 11; 6125A) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/18.0 Chrome/99.0.4844.88 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "6125A", + "type": "mobile" + } + }, + { + "desc": "TCL 20L", + "ua": "Mozilla/5.0 (Linux; Android 11; T774H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.59 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T774H", + "type": "mobile" + } + }, + { + "desc": "TCL 20L Plus", + "ua": "Mozilla/5.0 (Linux; Android 11; T775H Build/RKQ1.210107.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T775H", + "type": "mobile" + } + }, + { + "desc": "TCL 20R 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; T767H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36 OPR/71.3.3718.67322", + "expect": { + "vendor": "TCL", + "model": "T767H", + "type": "mobile" + } + }, + { + "desc": "TCL 20S", + "ua": "Mozilla/5.0 (Linux; Android 11; T773O) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T773O", + "type": "mobile" + } + }, + { + "desc": "TCL 20Y", + "ua": "Mozilla/5.0 (Linux; Android 11; 6156D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.134 Mobile Safari/537.36 OPR/70.3.3653.66287", + "expect": { + "vendor": "TCL", + "model": "6156D", + "type": "mobile" + } + }, + { + "desc": "TCL 30 V 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; T781S Build/RKQ1.210614.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/369.0.0.5.110;]", + "expect": { + "vendor": "TCL", + "model": "T781S", + "type": "mobile" + } + }, + { + "desc": "TCL 30 XE 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T767W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/416.0.0.35.85;]", + "expect": { + "vendor": "TCL", + "model": "T767W", + "type": "mobile" + } + }, + { + "desc": "TCL 305", + "ua": "Mozilla/5.0 (Linux; arm; Android 11; 6102D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.167 YaBrowser/22.7.6.96.00 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "6102D", + "type": "mobile" + } + }, + { + "desc": "TCL 306", + "ua": "Mozilla/5.0 (Linux; Android 12; 6102H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.141 Mobile Safari/537.36[FBAN/EMA;FBLC/it_IT;FBAV/332.0.0.22.108;]", + "expect": { + "vendor": "TCL", + "model": "6102H", + "type": "mobile" + } + }, + { + "desc": "TCL 30", + "ua": "Mozilla/5.0 (Linux; Android 12; T676H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T676H", + "type": "mobile" + } + }, + { + "desc": "TCL 30+", + "ua": "Mozilla/5.0 (Linux; Android 12; T676J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T676J", + "type": "mobile" + } + }, + { + "desc": "TCL 30 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T776H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T776H", + "type": "mobile" + } + }, + { + "desc": "TCL 30 LE", + "ua": "Mozilla/5.0 (Linux; Android 12; 4188V Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/352.0.0.14.108;]", + "expect": { + "vendor": "TCL", + "model": "4188V", + "type": "mobile" + } + }, + { + "desc": "TCL 30 SE", + "ua": "Mozilla/5.0 (Linux; Android 12; 6165H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/396.1.0.28.104;]", + "expect": { + "vendor": "TCL", + "model": "6165H", + "type": "mobile" + } + }, + { + "desc": "TCL 30E", + "ua": "Mozilla/5.0 (Linux; Android 12; 6127I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "6127I", + "type": "mobile" + } + }, + { + "desc": "TCL 40 NxtPaper", + "ua": "Mozilla/5.0 (Linux; Android 13; T612B Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.53 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T612B", + "type": "mobile" + } + }, + { + "desc": "TCL 4056S", + "ua": "Mozilla/5.0 (Mobile; TCL 4056S; rv:84.0) Gecko/84.0 Firefox/84.0 KAIOS/3.0", + "expect": { + "vendor": "TCL", + "model": "4056S", + "type": "mobile" + } + }, + { + "desc": "TCL A3", + "ua": "Mozilla/5.0 (Linux; Android 11; A509DL Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Mobile Safari/537.36 GSA/13.18.7.23.arm64", + "expect": { + "vendor": "TCL", + "model": "A509DL", + "type": "mobile" + } + }, + { + "desc": "TCL A30", + "ua": "Mozilla/5.0 (Linux; Android 11; 5102L Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/413.0.0.30.104;]", + "expect": { + "vendor": "TCL", + "model": "5102L", + "type": "mobile" + } + }, + { + "desc": "TCL 40 SE", + "ua": "Mozilla/5.0 (Linux; Android 13; T610K Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T610K", + "type": "mobile" + } + }, + { + "desc": "TCL 40 XE 5G", + "ua": "Mozilla/5.0 (Linux; Android 13; T609DL Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.136 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/466.1.0.57.85;]", + "expect": { + "vendor": "TCL", + "model": "T609DL", + "type": "mobile" + } + }, + { + "desc": "TCL 403", + "ua": "Mozilla/5.0 (Linux; Android 12; T431D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T431D", + "type": "mobile" + } + }, + { + "desc": "TCL 405", + "ua": "Mozilla/5.0 (Linux; Android 12; T506D Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]", + "expect": { + "vendor": "TCL", + "model": "T506D", + "type": "mobile" + } + }, + { + "desc": "TCL 408", + "ua": "Mozilla/5.0 (Linux; U; Android 12; T507U Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/105.0.5195.136 Mobile Safari/537.36 OPR/75.0.2254.68857", + "expect": { + "vendor": "TCL", + "model": "T507U", + "type": "mobile" + } + }, + { + "desc": "TCL 40R 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T771K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 EdgA/114.0.1823.37", + "expect": { + "vendor": "TCL", + "model": "T771K", + "type": "mobile" + } + }, + { + "desc": "TCL Ion X", + "ua": "Mozilla/5.0 (Linux; Android 12; T430W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.60 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T430W", + "type": "mobile" + } + }, + { + "desc": "TCL NxtPaper 11", + "ua": "Mozilla/5.0 (Linux; Android 13; 9466X Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.179 Safari/537.36 [FB_IAB/FB4A;FBAV/473.0.0.41.81;]", + "expect": { + "vendor": "TCL", + "model": "9466X", + "type": "tablet" + } + }, + { + "desc": "TCL Stylus 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; T779W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.2 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "T779W", + "type": "mobile" + } + }, + { + "desc": "TCL Tab 8 4G", + "ua": "Mozilla/5.0 (Linux; Android 10; 9048S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9048S", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 8 LE", + "ua": "Mozilla/5.0 (Linux; Android 12; 9137W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9137W", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10 FHD 4G", + "ua": "Mozilla/5.0 (Linux; Android 11; 9060G Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.196 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9060G", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10 HD 4G", + "ua": "Mozilla/5.0 (Linux; Android 11; 9060X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9060X", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10 LTE", + "ua": "Mozilla/5.0 (Linux; Android 13; 8196G Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.162 Safari/537.36 [FB_IAB/FB4A;FBAV/471.0.0.35.80;]", + "expect": { + "vendor": "TCL", + "model": "8196G", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 13; 8496G Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.61 Safari/537.36 [FB_IAB/FB4A;FBAV/474.0.0.52.74;]", + "expect": { + "vendor": "TCL", + "model": "8496G", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10L", + "ua": "Mozilla/5.0 (Linux; Android 11; 8491X_EEA Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.105 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "8491X", + "type": "tablet" + } + }, + { + "desc": "TCL Tab 10s 4G", + "ua": "Mozilla/5.0 (Linux; Android 11; 9080G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "9080G", + "type": "tablet" + } + }, + { + "desc": "TCL Xess P17AA", + "ua": "Mozilla/5.0 (Linux; Android 5.1; TCL Xess P17AA Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Safari/537.36", + "expect": { + "vendor": "TCL", + "model": "Xess P17AA", + "type": "tablet" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/technisat.json b/test/data/ua/device/technisat.json new file mode 100644 index 0000000..e9dca81 --- /dev/null +++ b/test/data/ua/device/technisat.json @@ -0,0 +1,20 @@ +[ + { + "desc": "TechniSAT Digit ISIO S SAT receiver", + "ua": "Opera/9.80 (Linux sh4; U; HbbTV/1.1.1 (;;;;;); CE-HTML; TechniSat Digit ISIO S; de) Presto/2.9.167 Version/11.50", + "expect": { + "vendor": "TechniSat", + "model": "Digit ISIO S", + "type": "smarttv" + } + }, + { + "desc": "TechniSAT MultyVision SmartTV", + "ua": "Opera/9.80 (Linux i686; U; HbbTV/1.1.1 (;;;;;); CE-HTML; TechniSat MultyVision ISIO; de) Presto/2.9.167 Version/11.50", + "expect": { + "vendor": "TechniSat", + "model": "MultyVision ISIO", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/tecno.json b/test/data/ua/device/tecno.json new file mode 100644 index 0000000..a002fcf --- /dev/null +++ b/test/data/ua/device/tecno.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Tecno KC8", + "ua": "Mozilla/5.0 (Linux; Android 10; TECNO KC8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TECNO", + "model": "KC8", + "type": "mobile" + } + }, + { + "desc": "Tecno Spark 8C", + "ua": "Mozilla/5.0 (Linux; Android 11; TECNO KG5n) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "TECNO", + "model": "KG5n", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/tesla.json b/test/data/ua/device/tesla.json new file mode 100644 index 0000000..34faa35 --- /dev/null +++ b/test/data/ua/device/tesla.json @@ -0,0 +1,20 @@ +[ + { + "desc": "Tesla", + "ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", + "expect": { + "vendor": "Tesla", + "model": "undefined", + "type": "embedded" + } + }, + { + "desc": "Tesla", + "ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/79.0.3945.130 Chrome/79.0.3945.130 Safari/537.36 Tesla/2020.16.2.1-e99c70fff409", + "expect": { + "vendor": "Tesla", + "model": "undefined", + "type": "embedded" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/ulefone.json b/test/data/ua/device/ulefone.json new file mode 100644 index 0000000..c7aff32 --- /dev/null +++ b/test/data/ua/device/ulefone.json @@ -0,0 +1,92 @@ +[ + { + "desc": "Ulefone Armor", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Armor Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.107 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Armor", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 6.0; Armor) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 YaBrowser/20.4.2.101.00 SA/1 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Armor", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor 8 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; Armor 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.1.3922.71199", + "expect": { + "vendor": "Ulefone", + "model": "Armor 8 Pro", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor 12 5G", + "ua": "Mozilla/5.0 (Linux; Android 11; Armor 12 5G Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Armor 12 5G", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor 20WT", + "ua": "Mozilla/5.0 (Linux; Android 12; Armor 20WT) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Armor 20WT", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor Pad", + "ua": "Mozilla/5.0 (Linux; Android 12; Armor Pad Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/431.0.0.30.108;]", + "expect": { + "vendor": "Ulefone", + "model": "Armor Pad", + "type": "mobile" + } + }, + { + "desc": "Ulefone Armor X5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; Armor X5 Pro Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/430.0.0.23.113;]", + "expect": { + "vendor": "Ulefone", + "model": "Armor X5 Pro", + "type": "mobile" + } + }, + { + "desc": "Ulefone Power Armor 14 Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor14 Pro Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.138 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Power Armor14 Pro", + "type": "mobile" + } + }, + { + "desc": "Ulefone Power Armor 18T", + "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor 18T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Ulefone", + "model": "Power Armor 18T", + "type": "mobile" + } + }, + { + "desc": "Ulefone Power Armor 19T", + "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor 19T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.3.3922.71982", + "expect": { + "vendor": "Ulefone", + "model": "Power Armor 19T", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/vivo.json b/test/data/ua/device/vivo.json new file mode 100644 index 0000000..cad62f9 --- /dev/null +++ b/test/data/ua/device/vivo.json @@ -0,0 +1,74 @@ +[ + { + "desc": "Vivo S1 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; vivo 1920) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Vivo", + "model": "1920", + "type": "mobile" + } + }, + { + "desc": "Vivo Y52s", + "ua": "Mozilla/5.0 (Linux; Android 10; V2057A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.10 SP-engine/2.28.0 baiduboxapp/12.10.0.10 (Baidu; P1 10) NABar/1.0", + "expect": { + "vendor": "Vivo", + "model": "V2057A", + "type": "mobile" + } + }, + { + "desc": "Vivo X60", + "ua": "Mozilla/5.0 (Linux; Android 11; V2046A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.8.71.0", + "expect": { + "vendor": "Vivo", + "model": "V2046A", + "type": "mobile" + } + }, + { + "desc": "Vivo Y79A", + "ua": "Mozilla/5.0 (Linux; Android 7.1.2; vivo Y79A Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", + "expect": { + "vendor": "Vivo", + "model": "Y79A", + "type": "mobile" + } + }, + { + "desc": "Vivo Y93", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; vivo 1814) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Vivo", + "model": "1814", + "type": "mobile" + } + }, + { + "desc": "Vivo Y97", + "ua": "Mozilla/5.0 (Linux; Android 8.1.0; V1813T Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", + "expect": { + "vendor": "Vivo", + "model": "V1813T", + "type": "mobile" + } + }, + { + "desc": "Vivo iQOO Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; V1916A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.1.10.6", + "expect": { + "vendor": "Vivo", + "model": "V1916A", + "type": "mobile" + } + }, + { + "desc": "Vivo 1906 (Y11)", + "ua": "Mozilla/5.0 (Linux; Android 11; vivo 1906) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Vivo", + "model": "1906", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/xiaomi.json b/test/data/ua/device/xiaomi.json new file mode 100644 index 0000000..86593ef --- /dev/null +++ b/test/data/ua/device/xiaomi.json @@ -0,0 +1,569 @@ +[ + { + "desc": "MIUI Xiaomi Mi MIX 3 5G", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; Mi MIX 3 5G MIUI/V10.3.2.0.PEMEUVF)", + "expect": { + "vendor": "Xiaomi", + "model": "Mi MIX 3 5G", + "type": "mobile" + } + }, + { + "desc": "MIUI POCOPHONE F1", + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; POCOPHONE F1 MIUI/9.6.27)", + "expect": { + "vendor": "Xiaomi", + "model": "POCOPHONE F1", + "type": "mobile" + } + }, + { + "desc": "MIUI Xiaomi M2006C3MT", + "ua": "Dalvik/2.1.0 (Linux; U; Android 10; M2006C3MT MIUI/V12.0.7.0.QCRMIXM)", + "expect": { + "vendor": "Xiaomi", + "model": "M2006C3MT", + "type": "mobile" + } + }, + { + "desc": "Xiaomi 2201117TG", + "ua": "Mozilla/5.0 (Linux; Android 11; 2201117TG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.98 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "2201117TG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi M2004J19C", + "ua": "Mozilla/5.0 (Linux; Android 11; M2004J19C Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.77 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2004J19C", + "type": "mobile" + } + }, + { + "desc": "Xiaomi M2006C3MNG", + "ua": "Mozilla/5.0 (Linux; Android 11; M2006C3MNG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2006C3MNG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi 21061119DG", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; 21061119DG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 YaBrowser/23.3.7.24.00 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "21061119DG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi 2013023", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; en-US; 2013023 Build/HM2013023) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/10.0.1.512 U3/0.8.0 Mobile Safari/533.1", + "expect": { + "vendor": "Xiaomi", + "model": "2013023", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Hongmi Note 1W", + "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-CN; HM NOTE 1W Build/JDQ39) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.7.9.439 U3/0.8.0 Mobile Safari/533.1", + "expect": { + "vendor": "Xiaomi", + "model": "HM NOTE 1W", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 3C", + "ua": "Mozilla/5.0 (Linux; U; Android 4.3; zh-CN; MI 3C Build/JLS36C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.7.9.439 U3/0.8.0 Mobile Safari/533.1", + "expect": { + "vendor": "Xiaomi", + "model": "MI 3C", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 5", + "ua": "Mozilla/5.0 (Linux; Android 7.0; MI 5 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.83 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI 5", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 6", + "ua": "Mozilla/5.0 (Linux; Android 7.1; MI 6 Build/NMF26X; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.125 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI 6", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 10 Pro", + "ua": "Linux; U; Android 13; Mi 10 Pro Build/TKQ1.221114.001", + "expect": { + "vendor": "Xiaomi", + "model": "Mi 10 Pro", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 5s Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; MI 5s Plus Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/8.7.1", + "expect": { + "vendor": "Xiaomi", + "model": "MI 5s Plus", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Mi A1 Build/OPR1.170623.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A1", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi Note", + "ua": "Mozilla/5.0 (Linux; Android 4.4.4; MI NOTE LTE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI NOTE LTE", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi One Plus", + "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; MI-ONE Plus Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", + "expect": { + "vendor": "Xiaomi", + "model": "MI-ONE Plus", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi Max 3", + "ua": "Mozilla/5.0 (Linux; Android 9; MI MAX 3 Build/PKQ1.181007.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI MAX 3", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A1", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.101 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A1", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A2 Lite", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2 Lite) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A2 Lite", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi 9 SE", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi 9 SE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi 9 SE", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi A2", + "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Mi A2", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Mi CC9", + "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-cn; MI CC 9 Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.116 Mobile Safari/537.36 XiaoMi/MiuiBrowser/15.5.18", + "expect": { + "vendor": "Xiaomi", + "model": "MI CC 9", + "type": "mobile" + } + }, + { + "desc": "Xiaomi MI PAD", + "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; en-us; MI PAD Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.3.2", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 2", + "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 2", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 2", + "ua": "Mozilla/5.0 (Linux; x86_64; Android 5.1; MI PAD 2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 YaBrowser/20.11.2.69.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 2", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 3", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 7.0; MI PAD 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.216 YaBrowser/21.5.6.56.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 3", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 4", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 8.1.0; MI PAD 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 YaBrowser/19.9.1.126.01 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 4", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 4 PLUS", + "ua": "Mozilla/5.0 (Linux; Android 8.1; MI PAD 4 PLUS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MI PAD 4 PLUS", + "type": "tablet" + } + }, + { + "desc": "Xiaomi MI PAD 4 WiFi", + "ua": "Mozilla/5.0 (Linux; Android 8.1; Mi Pad4 Wi-Fi) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Mobile Safari/537.36 EdgA/86.0.622.61", + "expect": { + "vendor": "Xiaomi", + "model": "Mi Pad4 Wi-Fi", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5", + "ua": "Mozilla/5.0 (Linux; Android 13; 21051182G Build/TKQ1.221013.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Xiaomi", + "model": "21051182G", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; M2105K81AC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Safari/537.36 Line/13.15.1/IAB", + "expect": { + "vendor": "Xiaomi", + "model": "M2105K81AC", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 5 Pro 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; M2105K81C) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2105K81C", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 6 Max 14", + "ua": "Mozilla/5.0 (Linux; U; Android 14; zh-tw; 2307BRPDCC Build/UKQ1.230804.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.118 Mobile Safari/537.36 Device/yudi Model/2307BRPDCC XiaoMi/MiuiBrowser/14.10.6", + "expect": { + "vendor": "Xiaomi", + "model": "2307BRPDCC", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Mi Pad 6 Pro", + "ua": "Mozilla/5.0 (Linux; U; Android 13; en-US; 23046RP50C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.6.2.1316 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "23046RP50C", + "type": "tablet" + } + }, + { + "desc": "Xiaomi Pad 6S Pro 12.4", + "ua": "Mozilla/5.0 (Linux; Android 14; 24018RPACC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "24018RPACC", + "type": "tablet" + } + }, + { + "desc": "Xiaomi POCO X2", + "ua": "Mozilla/5.0 (Linux; Android 10; POCO X2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "POCO X2", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO X3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 11; M2102J20SI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2102J20SI", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO X3 Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; M2102J20SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2102J20SG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO X3 NFC", + "ua": "Mozilla/5.0 (Linux; Android 12; M2007J20CG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2007J20CG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO M2 Pro", + "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; POCO M2 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 YaBrowser/22.11.7.42.00 SA/3 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "POCO M2 Pro", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCO M3", + "ua": "Mozilla/5.0 (Linux; Android 10; M2010J19CI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2010J19CI", + "type": "mobile" + } + }, + { + "desc": "Xiaomi POCOPHONE F1", + "ua": "Mozilla/5.0 (Linux; Android 10; POCOPHONE F1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "POCOPHONE F1", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi 4A", + "ua": "Mozilla/5.0 (Linux; Android 6.0; Redmi 4A Build/MMB29M; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi 4A", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi 10C", + "ua": "Mozilla/5.0 (Linux; Android 12; 220333QAG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "220333QAG", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi K30 5G", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 5G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi K30 5G", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi K30 Pro", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi K30 Pro", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi Note 3", + "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Redmi Note 3 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.116 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 3", + "type": "mobile" + } + }, + { + "desc": "Xiaomi Redmi Note 9 Pro Max", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9 Pro Max) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.99 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 9 Pro Max", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 9S", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 9S", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 10 5G", + "ua": "Mozilla/5.0 (Linux; Android 12; M2103K19C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2103K19C", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 13; M2101K6P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2101K6P", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 10 Pro", + "ua": "Mozilla/5.0 (Linux; Android 12; M2101K6G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "M2101K6G", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 8", + "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Note 8", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Note 12 Turbo", + "ua": "Mozilla/5.0 (Linux; Android 13; 23049RAD8C; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/16.7.1.1", + "expect": { + "vendor": "Xiaomi", + "model": "23049RAD8C", + "type": "mobile" + } + }, + { + "desc": "XiaoMi Redmi Pad", + "ua": "Mozilla/5.0 (Linux; U; Android 12; id-id; Redmi Pad Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36 XiaoMi/MiuiBrowser/14.1.1-gn", + "expect": { + "vendor": "Xiaomi", + "model": "Redmi Pad", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad", + "ua": "Mozilla/5.0 (Linux; Android 14; 22081283G Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Safari/537.36 Flipboard/4.3.31/5486,4.3.31.5486", + "expect": { + "vendor": "Xiaomi", + "model": "22081283G", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad Pro", + "ua": "Mozilla/5.0 (Linux; Android 14; 2405CRPFDG Build/UKQ1.240116.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.97 Safari/537.36 [FB_IAB/FB4A;FBAV/476.0.0.49.74;] FBNV/1", + "expect": { + "vendor": "Xiaomi", + "model": "2405CRPFDG", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad SE", + "ua": "Dalvik/2.1.0 (Linux; U; Android 14; 23073RPBFG Build/UKQ1.231003.002)", + "expect": { + "vendor": "Xiaomi", + "model": "23073RPBFG", + "type": "tablet" + } + }, + { + "desc": "XiaoMi Redmi Pad SE 8.7", + "ua": "Mozilla/5.0 (Linux; Android 14; 24076RP19G Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Mobile Safari/537.36 Line/14.18.1/IAB", + "expect": { + "vendor": "Xiaomi", + "model": "24076RP19G", + "type": "tablet" + } + }, + { + "desc": "Xiaomi TV", + "ua": "Mozilla/5.0 (Linux; Android 10; MiTV-MOOQ0 Build/QTG3.200305.006; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.61 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MiTV-MOOQ0", + "type": "smarttv" + } + }, + { + "desc": "Xiaomi Mi TV", + "ua": "Mozilla/5.0 (Linux; Android 9; MiTV4I Build/PI; en-in) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36 Puffin/7.8.3.40913AP", + "expect": { + "vendor": "Xiaomi", + "model": "MiTV4I", + "type": "smarttv" + } + }, + { + "desc": "Xiaomi Mi Box", + "ua": "Mozilla/5.0 (Linux; Android 9; MIBOX3 Build/PI; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/119.0.6045.193 Mobile Safari/537.36", + "expect": { + "vendor": "Xiaomi", + "model": "MIBOX3", + "type": "smarttv" + } + } +] \ No newline at end of file diff --git a/test/data/ua/device/zte.json b/test/data/ua/device/zte.json new file mode 100644 index 0000000..5b43bea --- /dev/null +++ b/test/data/ua/device/zte.json @@ -0,0 +1,11 @@ +[ + { + "desc": "ZTE Blade A6", + "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE BLADE A0620 Build/NMF26F; ru-ru) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.2.0.50586AP", + "expect": { + "vendor": "ZTE", + "model": "BLADE A0620", + "type": "mobile" + } + } +] \ No newline at end of file diff --git a/test/specs/engine-all.json b/test/data/ua/engine/engine-all.json similarity index 96% rename from test/specs/engine-all.json rename to test/data/ua/engine/engine-all.json index 7523fc3..c686031 100644 --- a/test/specs/engine-all.json +++ b/test/data/ua/engine/engine-all.json @@ -62,6 +62,15 @@ "version" : "4.5.4" } }, + { + "desc" : "LibWeb", + "ua" : "Mozilla/5.0 (Linux; x86_64) Ladybird/1.0", + "expect" : + { + "name" : "LibWeb", + "version" : "undefined" + } + }, { "desc" : "LibWeb", "ua" : "Mozilla/4.0 (SerenityOS; x86) LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb", diff --git a/test/specs/browser-clis.json b/test/data/ua/extension/cli.json similarity index 100% rename from test/specs/browser-clis.json rename to test/data/ua/extension/cli.json diff --git a/test/specs/browser-crawlers.json b/test/data/ua/extension/crawler.json similarity index 74% rename from test/specs/browser-crawlers.json rename to test/data/ua/extension/crawler.json index 04a1a35..8ed2d00 100644 --- a/test/specs/browser-crawlers.json +++ b/test/data/ua/extension/crawler.json @@ -9,6 +9,16 @@ "type" : "crawler" } }, + { + "desc" : "AdIdxBot", + "ua" : "Mozilla/5.0 (compatible; adidxbot/2.0; +http://www.bing.com/bingbot.htm)", + "expect" : + { + "name" : "adidxbot", + "version" : "2.0", + "type" : "crawler" + } + }, { "desc" : "AdsBot Mobile Web", "ua" : "AdsBot-Google (+http://www.google.com/adsbot.html)", @@ -79,6 +89,16 @@ "type" : "crawler" } }, + { + "desc" : "Applebot-Extended", + "ua" : "Applebot-Extended", + "expect" : + { + "name" : "Applebot-Extended", + "version" : "undefined", + "type" : "crawler" + } + }, { "desc" : "Amazonbot", "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Amazonbot/0.1; +https://developer.amazon.com/support/amazonbot)", @@ -89,6 +109,126 @@ "type" : "crawler" } }, + { + "desc" : "Anthropic AI", + "ua" : "anthropic-ai", + "expect" : + { + "name" : "anthropic-ai", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Archive.org Bot", + "ua" : "ia_archiver/8.1 (Windows 2000 1.9; en-US;)", + "expect" : + { + "name" : "ia_archiver", + "version" : "8.1", + "type" : "crawler" + } + }, + { + "desc" : "Archive.org Bot", + "ua" : "Mozilla/5.0 (compatible; archive.org_bot/3.3.0 +https://archive.org/details/archive.org_bot)", + "expect" : + { + "name" : "archive.org_bot", + "version" : "3.3.0", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider", + "ua" : "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)", + "expect" : + { + "name" : "Baiduspider", + "version" : "2.0", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-ads", + "ua" : "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0; Baiduspider-ads) Gecko/17.0 Firefox/17.0", + "expect" : + { + "name" : "Baiduspider-ads", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-cpro", + "ua" : "Mozilla/5.0 (compatible; Baiduspider-cpro; +http://www.baidu.com/search/spider.html)", + "expect" : + { + "name" : "Baiduspider-cpro", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-favo", + "ua" : "Baiduspider-favo", + "expect" : + { + "name" : "Baiduspider-favo", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-image", + "ua" : "Baiduspider-image+(+http://www.baidu.com/search/spider.htm)", + "expect" : + { + "name" : "Baiduspider-image", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-news", + "ua" : "Baiduspider-news", + "expect" : + { + "name" : "Baiduspider-news", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-render", + "ua" : "Mozilla/5.0 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html)", + "expect" : + { + "name" : "Baiduspider-render", + "version" : "2.0", + "type" : "crawler" + } + }, + { + "desc" : "Baiduspider-video", + "ua" : "Baiduspider-video", + "expect" : + { + "name" : "Baiduspider-video", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "Bingbot", + "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/", + "expect" : + { + "name" : "bingbot", + "version" : "2.0", + "type" : "crawler" + } + }, { "desc" : "Bytespider", "ua" : "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.1511.1269 Mobile Safari/537.36; Bytespider", @@ -179,6 +319,16 @@ "type" : "crawler" } }, + { + "desc" : "DuckDuckBot", + "ua" : "DuckDuckBot/1.1; ( http://duckduckgo.com/duckduckbot.html)", + "expect" : + { + "name" : "DuckDuckBot", + "version" : "1.1", + "type" : "crawler" + } + }, { "desc" : "Exabot", "ua" : "Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)", @@ -339,26 +489,6 @@ "type" : "crawler" } }, - { - "desc" : "Archive.org Bot", - "ua" : "ia_archiver/8.1 (Windows 2000 1.9; en-US;)", - "expect" : - { - "name" : "ia_archiver", - "version" : "8.1", - "type" : "crawler" - } - }, - { - "desc" : "Archive.org Bot", - "ua" : "Mozilla/5.0 (compatible; archive.org_bot/3.3.0 +https://archive.org/details/archive.org_bot)", - "expect" : - { - "name" : "archive.org_bot", - "version" : "3.3.0", - "type" : "crawler" - } - }, { "desc" : "ImagesiftBot", "ua" : "Mozilla/5.0 (compatible; ImagesiftBot; +imagesift.com)", @@ -369,6 +499,26 @@ "type" : "crawler" } }, + { + "desc" : "Linespider", + "ua" : "Mozilla/5.0 (compatible; Linespider/1.1; +https://lin.ee/4dwXkTH)", + "expect" : + { + "name" : "Linespider", + "version" : "1.1", + "type" : "crawler" + } + }, + { + "desc" : "LinkedInBot", + "ua" : "LinkedInBot/1.0 (compatible; Mozilla/5.0; Apache-HttpClient +http://www.linkedin.com)", + "expect" : + { + "name" : "LinkedInBot", + "version" : "1.0", + "type" : "crawler" + } + }, { "desc" : "magpie-crawler", "ua" : "magpie-crawler/1.1 (robots-txt-checker; +http://www.brandwatch.net)", @@ -462,7 +612,7 @@ }, { "desc" : "PetalBot", - "ua" : "Mozilla/5.0 (Linux; Android 7.0;) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; PetalBot;+https://webmaster.petalsearch.com/site/petalbot) ", + "ua" : "Mozilla/5.0 (Linux; Android 7.0;) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; PetalBot;+https://webmaster.petalsearch.com/site/petalbot)", "expect" : { "name" : "PetalBot", @@ -480,6 +630,36 @@ "type" : "crawler" } }, + { + "desc" : "SemrushBot for Backlink Audit tool", + "ua" : "Mozilla/5.0 (compatible; SemrushBot-BA; +http://www.semrush.com/bot.html)", + "expect" : + { + "name" : "SemrushBot-BA", + "version" : "undefined", + "type" : "crawler" + } + }, + { + "desc" : "SemrushBot for On Page SEO Checker tool", + "ua" : "Mozilla/5.0 (compatible; SemrushBot-SI/0.97; +http://www.semrush.com/bot.html)", + "expect" : + { + "name" : "SemrushBot-SI", + "version" : "0.97", + "type" : "crawler" + } + }, + { + "desc" : "SemrushBot for ContentShake AI tool", + "ua" : "Mozilla/5.0 (compatible; SemrushBot-OCOB/1; +https://www.semrush.com/bot/)", + "expect" : + { + "name" : "SemrushBot-OCOB", + "version" : "1", + "type" : "crawler" + } + }, { "desc" : "SeznamBot", "ua" : "Mozilla/5.0 (compatible; SeznamBot/4.0-RC1; +http://napoveda.seznam.cz/seznambot-intro/)", @@ -490,6 +670,16 @@ "type" : "crawler" } }, + { + "desc" : "Sogou", + "ua" : "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", + "expect" : + { + "name" : "Sogou web spider", + "version" : "4.0", + "type" : "crawler" + } + }, { "desc" : "Teoma", "ua" : "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://sp.ask.com/docs/about/tech_crawling.html)", @@ -540,6 +730,16 @@ "type" : "crawler" } }, + { + "desc" : "Yahoo! Slurp", + "ua" : "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp) ", + "expect" : + { + "name" : "Yahoo! Slurp", + "version" : "undefined", + "type" : "crawler" + } + }, { "desc" : "YandexBot", "ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)", diff --git a/test/specs/browser-emails.json b/test/data/ua/extension/email.json similarity index 100% rename from test/specs/browser-emails.json rename to test/data/ua/extension/email.json diff --git a/test/specs/extension-device.json b/test/data/ua/extension/extra-devices.json similarity index 100% rename from test/specs/extension-device.json rename to test/data/ua/extension/extra-devices.json diff --git a/test/specs/browser-fetchers.json b/test/data/ua/extension/fetcher.json similarity index 54% rename from test/specs/browser-fetchers.json rename to test/data/ua/extension/fetcher.json index dfd76f1..fed25bc 100644 --- a/test/specs/browser-fetchers.json +++ b/test/data/ua/extension/fetcher.json @@ -9,6 +9,16 @@ "type" : "fetcher" } }, + { + "desc" : "Better Uptime Bot", + "ua" : "Better Uptime Bot Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36", + "expect" : + { + "name" : "Better Uptime Bot", + "version" : "undefined", + "type" : "fetcher" + } + }, { "desc" : "BingPreview", "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b", @@ -19,6 +29,16 @@ "type" : "fetcher" } }, + { + "desc" : "Bluesky", + "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app) Chrome/100.0.0.0 Safari/537.36", + "expect" : + { + "name" : "Bluesky", + "version" : "1.1", + "type" : "fetcher" + } + }, { "desc" : "ChatGPT-User", "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ChatGPT-User/1.0; +https://openai.com/bot", @@ -49,6 +69,16 @@ "type" : "fetcher" } }, + { + "desc" : "Google Image Proxy", + "ua" : "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)", + "expect" : + { + "name" : "GoogleImageProxy", + "version" : "undefined", + "type" : "fetcher" + } + }, { "desc" : "Google Read Aloud - Mobile agent", "ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36 (compatible; Google-Read-Aloud; +https://support.google.com/webmasters/answer/1061943)", @@ -69,6 +99,16 @@ "type" : "fetcher" } }, + { + "desc" : "Google Page Renderer", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 Google-PageRenderer Google (+https://developers.google.com/+/web/snippet/) ", + "expect" : + { + "name" : "Google-PageRenderer", + "version" : "undefined", + "type" : "fetcher" + } + }, { "desc" : "Google Publisher Center", "ua" : "GoogleProducer; (+https://developers.google.com/search/docs/crawling-indexing/google-producer)", @@ -99,6 +139,26 @@ "type" : "fetcher" } }, + { + "desc" : "MicrosoftPreview", + "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; MicrosoftPreview/2.0; +https://aka.ms/MicrosoftPreview) Chrome/W.X.Y.Z Safari/537.36", + "expect" : + { + "name" : "MicrosoftPreview", + "version" : "2.0", + "type" : "fetcher" + } + }, + { + "desc" : "Pinterestbot", + "ua" : "Mozilla/5.0 (compatible; Pinterestbot/1.0; +http://www.pinterest.com/bot.html)", + "expect" : + { + "name" : "Pinterestbot", + "version" : "1.0", + "type" : "fetcher" + } + }, { "desc" : "Rogerbot", "ua" : "Mozilla/5.0 (compatible; rogerBot/1.0; UrlCrawler; http://www.seomoz.org/dp/rogerbot)", @@ -109,6 +169,46 @@ "type" : "fetcher" } }, + { + "desc" : "SiteAuditBot", + "ua" : "Mozilla/5.0 (compatible; SiteAuditBot/0.97; +http://www.semrush.com/bot.html)", + "expect" : + { + "name" : "SiteAuditBot", + "version" : "0.97", + "type" : "fetcher" + } + }, + { + "desc" : "Snap URL Preview", + "ua" : "Snap URL Preview Service; bot; snapchat; https://developers.snap.com/robots ", + "expect" : + { + "name" : "Snap URL Preview", + "version" : "undefined", + "type" : "fetcher" + } + }, + { + "desc" : "SkypeUriPreview", + "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5 skype-url-preview@microsoft.com", + "expect" : + { + "name" : "SkypeUriPreview", + "version" : "0.5", + "type" : "fetcher" + } + }, + { + "desc" : "TelegramBot", + "ua" : "TelegramBot (like TwitterBot)", + "expect" : + { + "name" : "TelegramBot", + "version" : "undefined", + "type" : "fetcher" + } + }, { "desc" : "UptimeRobot", "ua" : "Mozilla/5.0 (compatible; UptimeRobot/2.0; http://www.uptimerobot.com/)", @@ -128,5 +228,15 @@ "version" : "undefined", "type" : "fetcher" } + }, + { + "desc" : "WhatsApp", + "ua" : "WhatsApp/2.23.20.0", + "expect" : + { + "name" : "WhatsApp", + "version" : "2.23.20.0", + "type" : "fetcher" + } } ] \ No newline at end of file diff --git a/test/data/ua/extension/inapp.json b/test/data/ua/extension/inapp.json new file mode 100644 index 0000000..5512465 --- /dev/null +++ b/test/data/ua/extension/inapp.json @@ -0,0 +1,32 @@ +[ + { + "desc" : "Slack on mac", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Slack/4.39.90 Chrome/127.0.6533.72 Electron/13.1.9 Safari/537.36", + "expect" : + { + "name" : "Slack", + "version" : "4.39.90", + "type" : "inapp" + } + }, + { + "desc" : "Yahoo! Japan on Android", + "ua" : "Mozilla/5.0 (Linux; Android 13; SH-M20 Build/TKQ1.220915.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.163 Mobile Safari/537.36 YJApp-ANDROID jp.co.yahoo.android.yjtop/3.187.0", + "expect" : + { + "name" : "Yahoo! Japan", + "version" : "3.187.0", + "type" : "inapp" + } + }, + { + "desc" : "Yahoo! Japan on iOS", + "ua" : "Mozilla/5.0 (iPad; CPU OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 YJApp-IOS jp.co.yahoo.ipn.appli/4.131.0", + "expect" : + { + "name" : "Yahoo! Japan", + "version" : "4.131.0", + "type" : "inapp" + } + } +] diff --git a/test/data/ua/extension/library.json b/test/data/ua/extension/library.json new file mode 100644 index 0000000..f691105 --- /dev/null +++ b/test/data/ua/extension/library.json @@ -0,0 +1,192 @@ +[ + { + "desc" : "Apache-HttpClient", + "ua" : "Apache-HttpClient/4.5.14 (Java/17.0.12)", + "expect" : + { + "name" : "Apache-HttpClient", + "version" : "4.5.14", + "type" : "library" + } + }, + { + "desc" : "Axios", + "ua" : "axios/1.7.2", + "expect" : + { + "name" : "axios", + "version" : "1.7.2", + "type" : "library" + } + }, + { + "desc" : "go-http-client", + "ua" : "go-http-client/1.1", + "expect" : + { + "name" : "go-http-client", + "version" : "1.1", + "type" : "library" + } + }, + { + "desc" : "got", + "ua" : "got/9.6.0 (https://github.com/sindresorhus/got)", + "expect" : + { + "name" : "got", + "version" : "9.6.0", + "type" : "library" + } + }, + { + "desc" : "GuzzleHttp", + "ua" : "GuzzleHttp/6.5.5 curl/7.70.0 PHP/7.4.22", + "expect" : + { + "name" : "GuzzleHttp", + "version" : "6.5.5", + "type" : "library" + } + }, + { + "desc" : "Java", + "ua" : "Java/1.6.0_14", + "expect" : + { + "name" : "Java", + "version" : "1.6.0_14", + "type" : "library" + } + }, + { + "desc" : "Java HTTPClient", + "ua" : "Java-http-client/11.0.6", + "expect" : + { + "name" : "Java-http-client", + "version" : "11.0.6", + "type" : "library" + } + }, + { + "desc" : "jsdom", + "ua" : "Mozilla/5.0 (unknown OS) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/11.12.0", + "expect" : + { + "name" : "jsdom", + "version" : "11.12.0", + "type" : "library" + } + }, + { + "desc" : "libwww-perl", + "ua" : "libwww-perl/6.05", + "expect" : + { + "name" : "libwww-perl", + "version" : "6.05", + "type" : "library" + } + }, + { + "desc" : "lua-resty-http", + "ua" : "lua-resty-http/0.07 (Lua)", + "expect" : + { + "name" : "lua-resty-http", + "version" : "0.07", + "type" : "library" + } + }, + { + "desc" : "Needle", + "ua" : "Needle/3.2.0 (Node.js v18.14.2; win32 x64)", + "expect" : + { + "name" : "Needle", + "version" : "3.2.0", + "type" : "library" + } + }, + { + "desc" : "OkHttp", + "ua" : "okhttp/3.2.0", + "expect" : + { + "name" : "okhttp", + "version" : "3.2.0", + "type" : "library" + } + }, + { + "desc" : "node-fetch", + "ua" : "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)", + "expect" : + { + "name" : "node-fetch", + "version" : "1.0", + "type" : "library" + } + }, + { + "desc" : "PHP-SOAP", + "ua" : "PHP-SOAP/7.4.33", + "expect" : + { + "name" : "PHP-SOAP", + "version" : "7.4.33", + "type" : "library" + } + }, + { + "desc" : "PostmanRuntime", + "ua" : "PostmanRuntime/7.26.5", + "expect" : + { + "name" : "PostmanRuntime", + "version" : "7.26.5", + "type" : "library" + } + }, + { + "desc" : "Python urllib", + "ua" : "Python-urllib/2.6", + "expect" : + { + "name" : "Python-urllib", + "version" : "2.6", + "type" : "library" + } + }, + { + "desc" : "Python requests", + "ua" : "python-requests/2.32", + "expect" : + { + "name" : "python-requests", + "version" : "2.32", + "type" : "library" + } + }, + { + "desc" : "Scrapy", + "ua" : "Scrapy/1.5.0 (+https://scrapy.org)", + "expect" : + { + "name" : "Scrapy", + "version" : "1.5.0", + "type" : "library" + } + }, + { + "desc" : "superagent", + "ua" : "node-superagent/5.0.2", + "expect" : + { + "name" : "node-superagent", + "version" : "5.0.2", + "type" : "library" + } + } +] diff --git a/test/specs/extension-mediaplayer.json b/test/data/ua/extension/mediaplayer.json similarity index 94% rename from test/specs/extension-mediaplayer.json rename to test/data/ua/extension/mediaplayer.json index d40ba04..d093048 100644 --- a/test/specs/extension-mediaplayer.json +++ b/test/data/ua/extension/mediaplayer.json @@ -24,9 +24,9 @@ "ua" : "AppleTV/3.0.2 (Macintosh; Intel Mac OS X 10.4.7) AppleWebKit/528.18", "expect" : { - "name" : "WebKit", - "version" : "528.18", - "major" : "528" + "name" : "AppleTV", + "version" : "3.0.2", + "major" : "3" } }, { @@ -109,16 +109,6 @@ "major" : "1" } }, - { - "desc" : "Dalvik", - "ua" : "Dalvik/1.2.0 (Linux; U; Android 2.2.1; GT-S5830L Build/FROYO)", - "expect" : - { - "name" : "Dalvik", - "version" : "1.2.0", - "major" : "1" - } - }, { "desc" : "NexPlayer", "ua" : "E97510d/ Player/NexPlayer 4.0", @@ -189,16 +179,6 @@ "major" : "3" } }, - { - "desc" : "Java", - "ua" : "Java/1.4.1_04", - "expect" : - { - "name" : "Java", - "version" : "1.4.1_04", - "major" : "1" - } - }, { "desc" : "LG Player", "ua" : "LG Player 1.0; Android", @@ -509,16 +489,6 @@ "major" : "3" } }, - { - "desc" : "Wget", - "ua" : "Wget/1.12 (darwin10.7.0)", - "expect" : - { - "name" : "Wget", - "version" : "1.12", - "major" : "1" - } - }, { "desc" : "Winamp", "ua" : "Winamp 2.81", diff --git a/test/data/ua/extension/vehicle.json b/test/data/ua/extension/vehicle.json new file mode 100644 index 0000000..7800051 --- /dev/null +++ b/test/data/ua/extension/vehicle.json @@ -0,0 +1,62 @@ +[ + { + "desc" : "BMW", + "ua" : "Mozilla/5.0 (Linux; Android 9; AFTLBT962E2) AppleWebKit/537.36 (KHTML, like Gecko) Silk/118.3.1 like Chrome/118.0.5993.155 Safari/537.36", + "expect" : + { + "vendor" : "BMW", + "model" : "undefined", + "type" : "undefined" + } + }, + { + "desc" : "BYD", + "ua" : "Mozilla/5.0 (Linux; Android 10; DiLink3.0 For BYD AUTO Build/QKQ1.200816.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.186 Safari/537.36", + "expect" : + { + "vendor" : "BYD", + "model" : "undefined", + "type" : "undefined" + } + }, + { + "desc" : "Jeep", + "ua" : "Mozilla/5.0 (Linux; Android 9; AFTLFT962X3) AppleWebKit/537.36 (KHTML, like Gecko) Silk/124.5.2 like Chrome/124.0.6367.248 Safari/537.36", + "expect" : + { + "vendor" : "Jeep", + "model" : "Wagooner", + "type" : "undefined" + } + }, + { + "desc" : "Rivian", + "ua" : "Dalvik/2.1.0 (Linux; U; Android 10; Rivian R1T Build/QQ3A.200605.002)", + "expect" : + { + "vendor" : "Rivian", + "model" : "R1T", + "type" : "undefined" + } + }, + { + "desc" : "Tesla", + "ua" : "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/79.0.3945.130 Chrome/79.0.3945.130 Safari/537.36 Tesla/2020.36.16-3e9e4e8dd287", + "expect" : + { + "vendor" : "Tesla", + "model" : "undefined", + "type" : "embedded" + } + }, + { + "desc" : "Volvo", + "ua" : "Mozilla/5.0 (VCC; 1.0; like Gecko) NetFront/4.2", + "expect" : + { + "vendor" : "Volvo", + "model" : "undefined", + "type" : "undefined" + } + } +] diff --git a/test/data/ua/os/aix.json b/test/data/ua/os/aix.json new file mode 100644 index 0000000..02ccda8 --- /dev/null +++ b/test/data/ua/os/aix.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "AIX", + "ua" : "Mozilla/5.0 (X11; U; AIX 000138384C00; en-US; rv:1.0.1) Gecko/20030213 Netscape/7.0", + "expect" : + { + "name" : "AIX", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/amigaos.json b/test/data/ua/os/amigaos.json new file mode 100644 index 0000000..398d9b2 --- /dev/null +++ b/test/data/ua/os/amigaos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "AmigaOS", + "ua" : "Mozilla/4.0 (compatible; AWEB 3.4 SE; AmigaOS)", + "expect" : + { + "name" : "AmigaOS", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/android-x86.json b/test/data/ua/os/android-x86.json new file mode 100644 index 0000000..e83d3ca --- /dev/null +++ b/test/data/ua/os/android-x86.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Android-x86", + "ua" : "Mozilla/5.0 (Linux; Android 7.1.2; Generic Android-x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 OPR/61.2.3076.56749", + "expect" : + { + "name" : "Android-x86", + "version" : "7.1.2" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/android.json b/test/data/ua/os/android.json new file mode 100644 index 0000000..7304e1e --- /dev/null +++ b/test/data/ua/os/android.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Android", + "ua" : "Mozilla/5.0 (Linux; U; Android 2.2.2; en-us; VM670 Build/FRG83G) AppleWebKit/533.1 (KHTML, like Gecko)", + "expect" : + { + "name" : "Android", + "version" : "2.2.2" + } + }, + { + "desc" : "MIUI", + "ua" : "Dalvik/2.1.0 (Linux; U; Android 9; Mi MIX 3 5G MIUI/V10.3.2.0.PEMEUVF)", + "expect" : + { + "name" : "Android", + "version" : "9" + } + }, + { + "desc" : "KTB-Nexus 5", + "ua" : "APP-My App/1.0 (Linux; Android 4.2.1; Nexus 5 Build/JOP40D)", + "expect" : + { + "name" : "Android", + "version" : "4.2.1" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/arch.json b/test/data/ua/os/arch.json new file mode 100644 index 0000000..0aad667 --- /dev/null +++ b/test/data/ua/os/arch.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Arch", + "ua" : "Uzbl (Webkit 1.1.10) (Arch Linux)", + "expect" : + { + "name" : "Arch", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/bada.json b/test/data/ua/os/bada.json new file mode 100644 index 0000000..1125641 --- /dev/null +++ b/test/data/ua/os/bada.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Bada", + "ua" : "Mozilla/5.0 (SAMSUNG; SAMSUNG-GT-S5253/S5253DDKC1; U; Bada/1.0; en-us) AppleWebKit/533.1 (KHTML, like Gecko) Dolfin/2.0 Mobile WQVGA SMM-MMS/1.2.0 OPN-B", + "expect" : + { + "name" : "Bada", + "version" : "1.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/beos.json b/test/data/ua/os/beos.json new file mode 100644 index 0000000..045e54f --- /dev/null +++ b/test/data/ua/os/beos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "BeOS", + "ua" : "Mozilla/5.0 (BeOS; U; BeOS BePC; en-US; rv:1.8.1.8pre) Gecko/20070926 SeaMonkey/1.1.5pre", + "expect" : + { + "name" : "BeOS", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/blackberry.json b/test/data/ua/os/blackberry.json new file mode 100644 index 0000000..1865ab6 --- /dev/null +++ b/test/data/ua/os/blackberry.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "BlackBerry", + "ua" : "BlackBerry9300/5.0.0.912 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/378", + "expect" : + { + "name" : "BlackBerry", + "version" : "5.0.0.912" + } + }, + { + "desc" : "BlackBerry 10", + "ua" : "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.3+ (KHTML, like Gecko) Version/10.0.9.386 Mobile Safari/537.3+", + "expect" : + { + "name" : "BlackBerry", + "version" : "10" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/centos.json b/test/data/ua/os/centos.json new file mode 100644 index 0000000..4fe25b0 --- /dev/null +++ b/test/data/ua/os/centos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "CentOS", + "ua" : "Konqueror/15.13 (CentOS Linux 7.4; cs-CZ;)", + "expect" : + { + "name" : "CentOS", + "version" : "7.4" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/chrome-os.json b/test/data/ua/os/chrome-os.json new file mode 100644 index 0000000..69bc878 --- /dev/null +++ b/test/data/ua/os/chrome-os.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Chrome OS", + "ua" : "Mozilla/5.0 (X11; CrOS x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.0.0 Safari/537.36", + "expect" : + { + "name" : "Chrome OS", + "version" : "undefined" + } + }, + { + "desc" : "Chromium OS", + "ua" : "Mozilla/5.0 (X11; CrOS x86_64 10575.58.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36", + "expect" : + { + "name" : "Chrome OS", + "version" : "10575.58.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/chromecast-android.json b/test/data/ua/os/chromecast-android.json new file mode 100644 index 0000000..c0969dd --- /dev/null +++ b/test/data/ua/os/chromecast-android.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Google Chromecast with Google TV", + "ua" : "Mozilla/5.0 (Linux; Android 12.0; Build/STTL.240206.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.0 Safari/537.36 CrKey/1.56.500000 DeviceType/AndroidTV", + "expect" : + { + "name" : "Chromecast Android", + "version" : "12.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/chromecast-fuchsia.json b/test/data/ua/os/chromecast-fuchsia.json new file mode 100644 index 0000000..5bfecf8 --- /dev/null +++ b/test/data/ua/os/chromecast-fuchsia.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Google Chromecast Nest Hub", + "ua" : "Mozilla/5.0 (Fuchsia) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 CrKey/1.56.500000", + "expect" : + { + "name" : "Chromecast Fuchsia", + "version" : "1.56.500000" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/chromecast-linux.json b/test/data/ua/os/chromecast-linux.json new file mode 100644 index 0000000..6082346 --- /dev/null +++ b/test/data/ua/os/chromecast-linux.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Google Chromecast Legacy Linux-Based", + "ua" : "Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.81 Safari/537.36 CrKey/1.42.183786", + "expect" : + { + "name" : "Chromecast Linux", + "version" : "1.42.183786" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/chromecast-smartspeaker.json b/test/data/ua/os/chromecast-smartspeaker.json new file mode 100644 index 0000000..eb6f15b --- /dev/null +++ b/test/data/ua/os/chromecast-smartspeaker.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Google Chromecast Mini Smart Speaker", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/SmartSpeaker", + "expect" : + { + "name" : "Chromecast SmartSpeaker", + "version" : "1.56.500000" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/contiki.json b/test/data/ua/os/contiki.json new file mode 100644 index 0000000..b8b0503 --- /dev/null +++ b/test/data/ua/os/contiki.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Contiki", + "ua" : "Contiki/1.0 (Commodore 64; http://dunkels.com/adam/contiki/)", + "expect" : + { + "name" : "Contiki", + "version" : "1.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/debian.json b/test/data/ua/os/debian.json new file mode 100644 index 0000000..4ae949a --- /dev/null +++ b/test/data/ua/os/debian.json @@ -0,0 +1,56 @@ +[ + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) (Debian)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (X11; Linux x86_64; Debian GNU/Linux 8.1 (jessie)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.0 Maxthon/1.0.5.3 Safari/537.36", + "expect" : + { + "name" : "Debian", + "version" : "8.1" + } + }, + { + "desc" : "Debian", + "ua" : "ELinks/0.12~pre5-4 (textmode; Debian; Linux 3.2.0-4-amd64 x86_64 192x47-2)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" + } + }, + { + "desc" : "Debian", + "ua" : "w3m/0.5.3+debian-19", + "expect" : + { + "name" : "debian", + "version" : "19" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.3) Gecko/2008092814 (Debian-3.0.1-1)", + "expect" : + { + "name" : "Debian", + "version" : "3.0.1-1" + } + }, + { + "desc" : "Debian", + "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux 2.6.24.4; X11) KHTML/3.5.9 (like Gecko) (Debian package 4:3.5.9.dfsg.1-2+b1)", + "expect" : + { + "name" : "Debian", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/deepin.json b/test/data/ua/os/deepin.json new file mode 100644 index 0000000..b41e2a3 --- /dev/null +++ b/test/data/ua/os/deepin.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Deepin", + "ua" : "Mozilla/5.0 (X11; Linux x86_64; Deepin 15.5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36 NFSBrowser/5.0.0.1886", + "expect" : + { + "name" : "Deepin", + "version" : "15.5" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/dragonfly.json b/test/data/ua/os/dragonfly.json new file mode 100644 index 0000000..f8f3c58 --- /dev/null +++ b/test/data/ua/os/dragonfly.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "DragonFly", + "ua" : "Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1) Gecko/20090720 Firefox/3.5.1", + "expect" : + { + "name" : "DragonFly", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/elementary-os.json b/test/data/ua/os/elementary-os.json new file mode 100644 index 0000000..1fd5db7 --- /dev/null +++ b/test/data/ua/os/elementary-os.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "elementary OS", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/604.1 (KHTML, like Gecko) Version/11.0 Safari/604.1 elementary OS/0.4 (Loki) Epiphany/3.18.11", + "expect" : + { + "name" : "elementary OS", + "version" : "0.4" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/fedora.json b/test/data/ua/os/fedora.json new file mode 100644 index 0000000..a7abe1f --- /dev/null +++ b/test/data/ua/os/fedora.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Fedora", + "ua" : "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0", + "expect" : + { + "name" : "Fedora", + "version" : "undefined" + } + }, + { + "desc" : "Fedora", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:2.0) Gecko/20110404 Fedora/16-dev Firefox/4.0", + "expect" : + { + "name" : "Fedora", + "version" : "16-dev" + } + }, + { + "desc" : "Fedora", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; sk; rv:1.9.0.4) Gecko/2008111217 Fedora/3.0.4-1.fc10 Firefox/3.0.4", + "expect" : + { + "name" : "Fedora", + "version" : "3.0.4-1.fc10" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/firefox-os.json b/test/data/ua/os/firefox-os.json new file mode 100644 index 0000000..faf081a --- /dev/null +++ b/test/data/ua/os/firefox-os.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Firefox OS", + "ua" : "Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0", + "expect" : + { + "name" : "Firefox OS", + "version" : "14.0" + } + }, + { + "desc" : "Firefox OS on Tablet", + "ua" : "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", + "expect" : + { + "name" : "Firefox OS", + "version" : "26.0" + } + }, + { + "desc" : "Firefox OS on TV", + "ua" : "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", + "expect" : + { + "name" : "Firefox OS", + "version" : "44.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/freebsd.json b/test/data/ua/os/freebsd.json new file mode 100644 index 0000000..74544a0 --- /dev/null +++ b/test/data/ua/os/freebsd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "FreeBSD", + "ua" : "Mozilla/5.0 (X11; U; FreeBSD x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16", + "expect" : + { + "name" : "FreeBSD", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/fuchsia.json b/test/data/ua/os/fuchsia.json new file mode 100644 index 0000000..0759cba --- /dev/null +++ b/test/data/ua/os/fuchsia.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Fuchsia", + "ua" : "Mozilla/5.0 (X11; Fuchsia x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3557.0 Safari/537.36", + "expect" : + { + "name" : "Fuchsia", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/gentoo.json b/test/data/ua/os/gentoo.json new file mode 100644 index 0000000..8fa207b --- /dev/null +++ b/test/data/ua/os/gentoo.json @@ -0,0 +1,39 @@ +[ + + { + "desc" : "Gentoo", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.16) Gecko/20080716 (Gentoo) Galeon/2.0.6", + "expect" : + { + "name" : "Gentoo", + "version" : "undefined" + } + }, + { + "desc" : "Gentoo", + "ua" : "Xombrero (X11; U; Gentoo Linux amd64; en-US) Webkit/2.8.5", + "expect" : + { + "name" : "Gentoo", + "version" : "amd64" + } + }, + { + "desc" : "Gentoo", + "ua" : "Xombrero/1.6.4 (Linux amd64; en; Gentoo)", + "expect" : + { + "name" : "Gentoo", + "version" : "undefined" + } + }, + { + "desc" : "Gentoo", + "ua" : "Links (2.8; Linux 3.17.2-gentoo-x86 i686; GNU C 4.8.2; x)", + "expect" : + { + "name" : "gentoo", + "version" : "x86" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/ghostbsd.json b/test/data/ua/os/ghostbsd.json new file mode 100644 index 0000000..5e36d81 --- /dev/null +++ b/test/data/ua/os/ghostbsd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "GhostBSD", + "ua" : "Mozilla/5.0 (X11; GhostBSD/10.3; x86_64; rv:50.0.1) Gecko/20100101 Firefox/50.0.1", + "expect" : + { + "name" : "GhostBSD", + "version" : "10.3" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/haiku.json b/test/data/ua/os/haiku.json new file mode 100644 index 0000000..7005087 --- /dev/null +++ b/test/data/ua/os/haiku.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Haiku", + "ua" : "Mozilla/5.0 (Macintosh; Intel Haiku R1 x86) AppleWebKit/602.1.1 (KHTML, like Gecko) WebPositive/1.2 Version/8.0 Safari/602.1.1", + "expect" : + { + "name" : "Haiku", + "version" : "R1" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/harmonyos.json b/test/data/ua/os/harmonyos.json new file mode 100644 index 0000000..1fa13ef --- /dev/null +++ b/test/data/ua/os/harmonyos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "HarmonyOS", + "ua" : "Mozilla/5.0 (Linux; Android 10; HarmonyOS; YAL-AL10; HMSCore 6.3.0.327; GMSCore 21.48.15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 HuaweiBrowser/12.0.3.310 Mobile Safari/537.36", + "expect" : + { + "name" : "HarmonyOS", + "version" : "10" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/hp-ux.json b/test/data/ua/os/hp-ux.json new file mode 100644 index 0000000..8414740 --- /dev/null +++ b/test/data/ua/os/hp-ux.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "HP-UX", + "ua" : "Mozilla/5.0 (X11; U; HP-UX 9000/785; es-ES; rv:1.0.1) Gecko/20020827 Netscape/7.0", + "expect" : + { + "name" : "HP-UX", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/hurd.json b/test/data/ua/os/hurd.json new file mode 100644 index 0000000..0170728 --- /dev/null +++ b/test/data/ua/os/hurd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Hurd", + "ua" : "Mozilla/5.0 (X11; Hurd 0.9 i386; en-US) libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/3.7.0 Safari/696.96", + "expect" : + { + "name" : "Hurd", + "version" : "0.9" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/ios.json b/test/data/ua/os/ios.json new file mode 100644 index 0000000..86ba8cb --- /dev/null +++ b/test/data/ua/os/ios.json @@ -0,0 +1,65 @@ +[ + { + "desc" : "iOS in App", + "ua" : "AppName/version CFNetwork/version Darwin/version", + "expect" : + { + "name" : "iOS", + "version" : "undefined" + } + }, + { + "desc" : "iOS with Chrome", + "ua" : "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3", + "expect" : + { + "name" : "iOS", + "version" : "5.1.1" + } + }, + { + "desc" : "iOS with Opera Mini", + "ua" : "Opera/9.80 (iPhone; Opera Mini/7.1.32694/27.1407; U; en) Presto/2.8.119 Version/11.10", + "expect" : + { + "name" : "iOS", + "version" : "undefined" + } + }, + { + "desc": "iOS with FaceBook Mobile App", + "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", + "expect": + { + "name" : "iOS", + "version" : "13.6.1" + } + }, + { + "desc": "iOS with Slack App", + "ua": "com.tinyspeck.chatlyio/23.04.10 (iPhone; iOS 16.4.1; Scale/3.00)", + "expect": + { + "name" : "iOS", + "version" : "16.4.1" + } + }, + { + "desc" : "iOS BE App", + "ua" : "APP-BE Test/1.0 (iPad; Apple; CPU iPhone OS 7_0_2 like Mac OS X)", + "expect" : + { + "name" : "iOS", + "version" : "7.0.2" + } + }, + { + "desc": "Apple HomePod", + "ua": "AppleCoreMedia/1.0.0.15D61 (HomePod; U; CPU OS 11_2_5 like Mac OS X; en_us)", + "expect" : + { + "name" : "iOS", + "version" : "11.2.5" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/joli.json b/test/data/ua/os/joli.json new file mode 100644 index 0000000..e9815fd --- /dev/null +++ b/test/data/ua/os/joli.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Joli", + "ua" : "Mozilla/5.0 (X11; Jolicloud Linux i686) AppleWebKit/537.6 (KHTML, like Gecko) Joli OS/1.2 Chromium/23.0.1240.0 Chrome/23.0.1240.0 Safari/537.6", + "expect" : + { + "name" : "Joli", + "version" : "1.2" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/kaios.json b/test/data/ua/os/kaios.json new file mode 100644 index 0000000..f59572d --- /dev/null +++ b/test/data/ua/os/kaios.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "KaiOS", + "ua" : "Mozilla/5.0 (Mobile; Nokia_8110_4G; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5", + "expect" : + { + "name" : "KAIOS", + "version" : "2.5" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/kubuntu.json b/test/data/ua/os/kubuntu.json new file mode 100644 index 0000000..2634256 --- /dev/null +++ b/test/data/ua/os/kubuntu.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Kubuntu", + "ua" : "Mozilla/5.0 (compatible; Konqueror/4.4; Linux 2.6.32-22-generic; X11; en_US) KHTML/4.4.3 (like Gecko) Kubuntu", + "expect" : + { + "name" : "Kubuntu", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/linpus.json b/test/data/ua/os/linpus.json new file mode 100644 index 0000000..40c8169 --- /dev/null +++ b/test/data/ua/os/linpus.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Linpus", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9b5pre) Gecko/2008032619 Linpus/3.0-0.49", + "expect" : + { + "name" : "Linpus", + "version" : "3.0-0.49" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/linspire.json b/test/data/ua/os/linspire.json new file mode 100644 index 0000000..4d2497b --- /dev/null +++ b/test/data/ua/os/linspire.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Linspire", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.4) Gecko/20060803 Firefox/1.5.0.4 Linspire/1.5.0.4", + "expect" : + { + "name" : "Linspire", + "version" : "1.5.0.4" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/linux.json b/test/data/ua/os/linux.json new file mode 100644 index 0000000..af78593 --- /dev/null +++ b/test/data/ua/os/linux.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Linux", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36", + "expect" : + { + "name" : "Linux", + "version" : "undefined" + } + }, + { + "desc" : "Linux", + "ua" : "Mozilla/5.0 (X11; U; Linux armv61; en-US; rv:1.9.1b2pre) Gecko/20081015 Fennec/1.0a1", + "expect" : + { + "name" : "Linux", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/macos.json b/test/data/ua/os/macos.json new file mode 100644 index 0000000..43f90db --- /dev/null +++ b/test/data/ua/os/macos.json @@ -0,0 +1,38 @@ +[ + { + "desc" : "Mac OS on PowerPC", + "ua" : "Mozilla/4.0 (compatible; MSIE 5.0b1; Mac_PowerPC)", + "expect" : + { + "name" : "macOS", + "version" : "undefined" + } + }, + { + "desc" : "Mac OS X on x86, x86_64, or aarch64 using Firefox", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "macOS", + "version" : "x.y" + } + }, + { + "desc" : "Mac OS X on PowerPC using Firefox", + "ua" : "Mozilla/5.0 (Macintosh; PPC Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "macOS", + "version" : "x.y" + } + }, + { + "desc" : "Mac OS", + "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36", + "expect" : + { + "name" : "macOS", + "version" : "10.6.8" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/maemo.json b/test/data/ua/os/maemo.json new file mode 100644 index 0000000..9d89849 --- /dev/null +++ b/test/data/ua/os/maemo.json @@ -0,0 +1,29 @@ +[ + { + "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" : "Nokia N900 Linux mobile, on the Maemo browser", + "ua" : "Mozilla/5.0(X11; U; Linux armv7l; fr-FR; rv:1.9.2a1pre) Gecko/20091127 Firefox/3.5 Maemo Browser 1.5.6 RX-51 N900", + "expect" : + { + "name" : "Maemo", + "version" : "undefined" + } + }, + { + "desc" : "Nokia N900 Linux mobile, on the Maemo browser", + "ua" : "Mozilla/5.0 (Linux; Maemo 5.0; Nokia N900; Build/4.0.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Mobile Safari/537.36", + "expect" : + { + "name" : "Maemo", + "version" : "5.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/mandriva.json b/test/data/ua/os/mandriva.json new file mode 100644 index 0000000..3dbccf7 --- /dev/null +++ b/test/data/ua/os/mandriva.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Mandriva", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.22) Gecko/20110907 Mandriva Linux/1.9.2.22-0.1mdv2010.2 (2010.2) Firefox/3.6.22", + "expect" : + { + "name" : "Mandriva", + "version" : "1.9.2.22-0.1mdv2010.2" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/manjaro.json b/test/data/ua/os/manjaro.json new file mode 100644 index 0000000..ede015f --- /dev/null +++ b/test/data/ua/os/manjaro.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Manjaro", + "ua" : "Mozilla/5.0 (X11; Manjaro 19.0.2; Arch; x64; rv:84.0) Gecko/20100101 Firefox/84.0", + "expect" : + { + "name" : "Manjaro", + "version" : "19.0.2" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/meego.json b/test/data/ua/os/meego.json new file mode 100644 index 0000000..a506cde --- /dev/null +++ b/test/data/ua/os/meego.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "MeeGo", + "ua" : "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", + "expect" : + { + "name" : "MeeGo", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/minix.json b/test/data/ua/os/minix.json new file mode 100644 index 0000000..d39a514 --- /dev/null +++ b/test/data/ua/os/minix.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Minix", + "ua" : "Mozilla/5.0 (X11; Original ; Minix 3.3 ; rv:3.0)", + "expect" : + { + "name" : "Minix", + "version" : "3.3" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/mint.json b/test/data/ua/os/mint.json new file mode 100644 index 0000000..e87641e --- /dev/null +++ b/test/data/ua/os/mint.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Mint", + "ua" : "Opera/9.80 (X11; Linux x86_64; Edition Linux Mint) Presto/2.12.388 Version/12.16", + "expect" : + { + "name" : "Mint", + "version" : "undefined" + } + }, + { + "desc" : "Mint", + "ua" : "Opera/9.64 (X11; Linux i686; U; Linux Mint; nb) Presto/2.1.1", + "expect" : + { + "name" : "Mint", + "version" : "undefined" + } + }, + { + "desc" : "Mint", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.5) Gecko/2008121622 Linux Mint/6 (Felicia) Firefox/3.0.4", + "expect" : + { + "name" : "Mint", + "version" : "6" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/morphos.json b/test/data/ua/os/morphos.json new file mode 100644 index 0000000..f255eeb --- /dev/null +++ b/test/data/ua/os/morphos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "MorphOS", + "ua" : "AmigaVoyager/3.4.4 (MorphOS/PPC native)", + "expect" : + { + "name" : "MorphOS", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/netbsd.json b/test/data/ua/os/netbsd.json new file mode 100644 index 0000000..3a7657a --- /dev/null +++ b/test/data/ua/os/netbsd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "NetBSD", + "ua" : "ELinks (0.4.3; NetBSD 3.0.2PATCH sparc64; 141x19)", + "expect" : + { + "name" : "NetBSD", + "version" : "3.0.2PATCH" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/netrange.json b/test/data/ua/os/netrange.json new file mode 100644 index 0000000..a7ff0a9 --- /dev/null +++ b/test/data/ua/os/netrange.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Netrange Smart TV", + "ua" : "Mozilla/5.0 (Linux; U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2207.0 LOEWE-SL410/5.2.0.0 HbbTV/1.4.1 (; LOEWE; SL410; LOH/5.2.0.0;;) FVC/3.0 (LOEWE; SL410;) CE-HTML/1.0 Config (L:deu,CC:DEU) NETRANGEMMH", + "expect" : + { + "name" : "NETRANGE", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/nettv.json b/test/data/ua/os/nettv.json new file mode 100644 index 0000000..2584e40 --- /dev/null +++ b/test/data/ua/os/nettv.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "NetTV 3.2.1", + "ua" : "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.2.1; en) Presto/2.6.33 Version/10.70", + "expect" : + { + "name" : "NETTV", + "version" : "3.2.1" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/nintendo.json b/test/data/ua/os/nintendo.json new file mode 100644 index 0000000..b8ac8a3 --- /dev/null +++ b/test/data/ua/os/nintendo.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Nintendo Switch", + "ua" : "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", + "expect" : + { + "name" : "Nintendo", + "version" : "Switch" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/openbsd.json b/test/data/ua/os/openbsd.json new file mode 100644 index 0000000..25164de --- /dev/null +++ b/test/data/ua/os/openbsd.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "OpenBSD", + "ua" : "Mozilla/5.0 (X11; U; OpenBSD i386; en-US; rv:1.9.1) Gecko/20090702 Firefox/3.5", + "expect" : + { + "name" : "OpenBSD", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/openharmony.json b/test/data/ua/os/openharmony.json new file mode 100644 index 0000000..b0606a1 --- /dev/null +++ b/test/data/ua/os/openharmony.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "OpenHarmony", + "ua" : "Mozilla/5.0 (Phone; OpenHarmony 4.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 ArkWeb/4.1.6.1 Mobile", + "expect" : + { + "name" : "OpenHarmony", + "version" : "4.1" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/os2.json b/test/data/ua/os/os2.json new file mode 100644 index 0000000..cb38c11 --- /dev/null +++ b/test/data/ua/os/os2.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "OS/2", + "ua" : "Links (2.1pre14; OS/2 1 i386; 80x33)", + "expect" : + { + "name" : "OS/2", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/palm.json b/test/data/ua/os/palm.json new file mode 100644 index 0000000..5fc831e --- /dev/null +++ b/test/data/ua/os/palm.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Palm OS", + "ua" : "Mozilla/4.76 [en] (PalmOS; U; WebPro3.0; Palm-Arz1)", + "expect" : + { + "name" : "Palm", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/pclinuxos.json b/test/data/ua/os/pclinuxos.json new file mode 100644 index 0000000..521b4be --- /dev/null +++ b/test/data/ua/os/pclinuxos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "PCLinuxOS", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101209 PCLinuxOS/1.9.2.13-1pclos2010 (2010) Firefox/3.6.13", + "expect" : + { + "name" : "PCLinuxOS", + "version" : "1.9.2.13-1pclos2010" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/pico.json b/test/data/ua/os/pico.json new file mode 100644 index 0000000..456a5fa --- /dev/null +++ b/test/data/ua/os/pico.json @@ -0,0 +1,26 @@ +[ + { + "desc": "Pico 4", + "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.8.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.38 Chrome/105.0.5195.68 VR Safari/537.36", + "expect": { + "name" : "PICO", + "version" : "5.8.2" + } + }, + { + "desc": "Pico 4", + "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0", + "expect": { + "name" : "PICO", + "version" : "5.4.0" + } + }, + { + "desc": "Pico Neo3 Link", + "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", + "expect": { + "name" : "Pico", + "version" : "5.8.4.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/plan9.json b/test/data/ua/os/plan9.json new file mode 100644 index 0000000..e3726fb --- /dev/null +++ b/test/data/ua/os/plan9.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Plan9", + "ua" : "NCSA_Mosaic/5.0 (X11;Plan 9 4.0)", + "expect" : + { + "name" : "Plan 9", + "version" : "4.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/playstation.json b/test/data/ua/os/playstation.json new file mode 100644 index 0000000..38cf97f --- /dev/null +++ b/test/data/ua/os/playstation.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "PlayStation 4", + "ua" : "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", + "expect" : + { + "name" : "PlayStation", + "version" : "4" + } + }, + { + "desc" : "PlayStation 5", + "ua" : "Mozilla/5.0 (PlayStation 5/SmartTV) AppleWebKit/605.1.15 (KHTML, like Gecko)", + "expect" : + { + "name" : "PlayStation", + "version" : "5" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/qnx.json b/test/data/ua/os/qnx.json new file mode 100644 index 0000000..2817e48 --- /dev/null +++ b/test/data/ua/os/qnx.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "QNX", + "ua" : "Mozilla/5.0 (Photon; U; QNX x86pc; en-US; rv:1.8.1.20) Gecko/20090127 BonEcho/2.0.0.20", + "expect" : + { + "name" : "QNX", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/raspbian.json b/test/data/ua/os/raspbian.json new file mode 100644 index 0000000..10fd9fb --- /dev/null +++ b/test/data/ua/os/raspbian.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Raspbian", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/72.0.3626.121 HeadlessChrome/72.0.3626.121 Safari/537.36", + "expect" : + { + "name" : "Raspbian", + "version" : "undefined" + } + }, + { + "desc" : "Raspbian", + "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15 Raspbian/9.0 (1:3.8.2.0-0rpi28) Epiphany/3.8.2", + "expect" : + { + "name" : "Raspbian", + "version" : "9.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/redhat.json b/test/data/ua/os/redhat.json new file mode 100644 index 0000000..89f3e25 --- /dev/null +++ b/test/data/ua/os/redhat.json @@ -0,0 +1,38 @@ +[ + { + "desc" : "RedHat", + "ua" : "Mozilla/5.0 (compatible; Konqueror/4.3; Linux) KHTML/4.3.4 (like Gecko) Red Hat Enterprise Linux/4.3.4-11.el6_1.4", + "expect" : + { + "name" : "Red Hat", + "version" : "4.3.4-11.el6_1.4" + } + }, + { + "desc" : "RedHat", + "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.13pre) Gecko/20070717 Red Hat/1.0.9-4.el4 SeaMonkey/1.0.9", + "expect" : + { + "name" : "Red Hat", + "version" : "1.0.9-4.el4" + } + }, + { + "desc" : "RedHat", + "ua" : "iTunes/4.7.1 (Linux; N; Red Hat; x86_64-linux; EN; utf8) SqueezeCenter, Squeezebox Server, Logitech Media Server/7.9.1/1522157629", + "expect" : + { + "name" : "Red Hat", + "version" : "undefined" + } + }, + { + "desc" : "RedHat", + "ua" : "curl/7.20.0 (x86_64-redhat-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5", + "expect" : + { + "name" : "redhat", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/rim-tablet-os.json b/test/data/ua/os/rim-tablet-os.json new file mode 100644 index 0000000..4451c3c --- /dev/null +++ b/test/data/ua/os/rim-tablet-os.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "RIM Tablet OS", + "ua" : "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+", + "expect" : + { + "name" : "RIM Tablet OS", + "version" : "2.1.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/risc-os.json b/test/data/ua/os/risc-os.json new file mode 100644 index 0000000..5442784 --- /dev/null +++ b/test/data/ua/os/risc-os.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "RISC OS", + "ua" : "Mozilla/1.10 [en] (Compatible; RISC OS 3.70; Oregano 1.10)", + "expect" : + { + "name" : "RISC OS", + "version" : "3.70" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/sabayon.json b/test/data/ua/os/sabayon.json new file mode 100644 index 0000000..d44f9e2 --- /dev/null +++ b/test/data/ua/os/sabayon.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Sabayon", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Sabayon Chrome/19.0.1084.46 Safari/536.5", + "expect" : + { + "name" : "Sabayon", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/sailfish.json b/test/data/ua/os/sailfish.json new file mode 100644 index 0000000..f96376b --- /dev/null +++ b/test/data/ua/os/sailfish.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Sailfish", + "ua" : "Mozilla/5.0 (Linux; U; Sailfish 3.0; Mobile; rv:45.0) Gecko/45.0 Firefox/45.0 SailfishBrowser/1.0", + "expect" : + { + "name" : "Sailfish", + "version" : "3.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/serenityos.json b/test/data/ua/os/serenityos.json new file mode 100644 index 0000000..748546e --- /dev/null +++ b/test/data/ua/os/serenityos.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "SerenityOS", + "ua" : "Mozilla/4.0 (SerenityOS; x86) LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb", + "expect" : + { + "name" : "SerenityOS", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/series40.json b/test/data/ua/os/series40.json new file mode 100644 index 0000000..1b02c15 --- /dev/null +++ b/test/data/ua/os/series40.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Series40", + "ua" : "Mozilla/5.0 (Series40; Nokia2055/03.20; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/2.2.0.0.34", + "expect" : + { + "name" : "Series40", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/slackware.json b/test/data/ua/os/slackware.json new file mode 100644 index 0000000..35f446e --- /dev/null +++ b/test/data/ua/os/slackware.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Slackware", + "ua" : "Mozilla/5.0 Slackware/13.37 (X11; U; Linux x86_64; en-US) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41", + "expect" : + { + "name" : "Slackware", + "version" : "13.37" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/solaris.json b/test/data/ua/os/solaris.json new file mode 100644 index 0000000..450e47d --- /dev/null +++ b/test/data/ua/os/solaris.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Solaris", + "ua" : "Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7) Gecko/20070606", + "expect" : + { + "name" : "Solaris", + "version" : "sun4u" + } + }, + { + "desc" : "Solaris", + "ua" : "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", + "expect" : + { + "name" : "Solaris", + "version" : "4.1.4" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/suse.json b/test/data/ua/os/suse.json new file mode 100644 index 0000000..9da3f35 --- /dev/null +++ b/test/data/ua/os/suse.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "OpenSUSE", + "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110420 SUSE/3.6.17-0.2.1 Firefox/3.6.17", + "expect" : + { + "name" : "SUSE", + "version" : "3.6.17-0.2.1" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/symbian.json b/test/data/ua/os/symbian.json new file mode 100644 index 0000000..0e61d02 --- /dev/null +++ b/test/data/ua/os/symbian.json @@ -0,0 +1,65 @@ +[ + { + "desc" : "Nokia 5250", + "ua" : "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba", + "expect" : + { + "name" : "Symbian", + "version" : "9.4" + } + }, + { + "desc" : "Nokia N79", + "ua" : "Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaN79-1/32.001; Profile/MIDP-2.1 Configuration/CLDC-1", + "expect" : + { + "name" : "Symbian", + "version" : "9.3" + } + }, + { + "desc" : "Nokia E71", + "ua" : "Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE71-1/110.07.127; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413", + "expect" : + { + "name" : "Symbian", + "version" : "9.2" + } + }, + { + "desc" : "Opera Mini on S60", + "ua" : "Opera/9.80 (Series 60; Opera Mini/7.1.32444/191.361; U; de) Presto/2.12.423 Version/12.16", + "expect" : + { + "name" : "Symbian", + "version" : "undefined" + } + }, + { + "desc" : "NokiaBrowser on Nokia C7", + "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaC7-00/024.001; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba", + "expect" : + { + "name" : "Symbian", + "version" : "3" + } + }, + { + "desc" : "Nokia 808 PureView", + "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.5 Nokia808PureView/113.010.1508; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/535.1 (KHTML, like Gecko) NokiaBrowser/8.3.2.21 Mobile Safari/535.1 3gpp-gba", + "expect" : + { + "name" : "Symbian", + "version" : "3" + } + }, + { + "desc" : "Nokia 808 PureView", + "ua" : "Mozilla/5.0 (Symbian; U; Nokia808 PureView; en-GB) AppleWebKit/534.3 (KHTML, like Gecko) Version/3.0 Mobile/1A543a Mobile Safari/534.3", + "expect" : + { + "name" : "Symbian", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/tizen.json b/test/data/ua/os/tizen.json new file mode 100644 index 0000000..4f9320d --- /dev/null +++ b/test/data/ua/os/tizen.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Tizen", + "ua" : "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", + "expect" : + { + "name" : "Tizen", + "version" : "2.3" + } + }, + { + "desc" : "Tizen", + "ua" : "Mozilla/5.0 (Linux; Tizen 2.3; SAMSUNG SM-Z130H) AppleWebKit/537.3 (KHTML, like Gecko) Version/2.3 Mobile Safari/537.3", + "expect" : + { + "name" : "Tizen", + "version" : "2.3" + } + }, + { + "desc" : "Tizen 6.0", + "ua" : "HbbTV/1.5.1 (+DRM;Samsung;SmartTV2021:UAU7000;T-KSU2EDEUC-1506.0;KantSU2e;urn:samsungtv:familyname:21_KANTSU2E_UHD_BASIC:2021;) Tizen/6.0 (+TVPLUS+SmartHubLink) Chrome/76 LaTivu_1.0.1_2021 RVID/17", + "expect" : + { + "name" : "Tizen", + "version" : "6.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/ubuntu-touch.json b/test/data/ua/os/ubuntu-touch.json new file mode 100644 index 0000000..e0aea5f --- /dev/null +++ b/test/data/ua/os/ubuntu-touch.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Ubuntu Touch", + "ua" : "Mozilla/5.0 (Linux; Ubuntu 16.04 like Android 4.4) AppleWebKit/537.36 Chromium/65.0.3325.151 Mobile Safari/537.36", + "expect" : + { + "name" : "Ubuntu Touch", + "version" : "16.04" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/ubuntu.json b/test/data/ua/os/ubuntu.json new file mode 100644 index 0000000..d3958f9 --- /dev/null +++ b/test/data/ua/os/ubuntu.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Ubuntu", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.22+ (KHTML, like Gecko) Chromium/17.0.963.56 Chrome/17.0.963.56 Safari/535.22+ Ubuntu/12.04 (3.4.1-0ubuntu1) Epiphany/3.4.1", + "expect" : + { + "name" : "Ubuntu", + "version" : "12.04" + } + }, + { + "desc" : "Ubuntu", + "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/31.0.1650.63 Chrome/31.0.1650.63 Safari/537.36", + "expect" : + { + "name" : "Ubuntu", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/unix.json b/test/data/ua/os/unix.json new file mode 100644 index 0000000..18e7332 --- /dev/null +++ b/test/data/ua/os/unix.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "UNIX", + "ua" : "Surf/0.4.1 (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)", + "expect" : + { + "name" : "Unix", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/watchos.json b/test/data/ua/os/watchos.json new file mode 100644 index 0000000..ec2c30b --- /dev/null +++ b/test/data/ua/os/watchos.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "watchOS", + "ua" : "server-bag [Watch OS,8.4,19S546,Watch3,4]", + "expect" : + { + "name" : "watchOS", + "version" : "8.4" + } + }, + { + "desc" : "watchOS", + "ua" : "atc/1.0 watchOS/7.4.1 model/Watch3,3 hwp/t8004 build/18T201 (6; dt:155)", + "expect" : + { + "name" : "watchOS", + "version" : "7.4.1" + } + }, + { + "desc" : "watchOS", + "ua" : "Watch4,3/5.3.8 (16U680)", + "expect" : + { + "name" : "watchOS", + "version" : "5.3.8" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/webos.json b/test/data/ua/os/webos.json new file mode 100644 index 0000000..c31cd3f --- /dev/null +++ b/test/data/ua/os/webos.json @@ -0,0 +1,65 @@ +[ + { + "desc" : "WebOS", + "ua" : "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.5; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0", + "expect" : + { + "name" : "webOS", + "version" : "3.0.5" + } + }, + { + "desc" : "WebOS", + "ua" : "Mozilla/5.0 (webOS/1.4.5; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pre/1.0", + "expect" : + { + "name" : "webOS", + "version" : "1.4.5" + } + }, + { + "desc" : "WebOS TV 5.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 4.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.34 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 3.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.2.1 Chrome/38.0.2125.122 Safari/537.36 WebAppManager", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 2.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/538.2 (KHTML, like Gecko) Large Screen WebAppManager Safari/538.2", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + }, + { + "desc" : "WebOS TV 1.x", + "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.41 (KHTML, like Gecko) Large Screen WebAppManager Safari/537.41", + "expect" : + { + "name" : "webOS", + "version" : "TV" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/windows-iot.json b/test/data/ua/os/windows-iot.json new file mode 100644 index 0000000..ff1d02c --- /dev/null +++ b/test/data/ua/os/windows-iot.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Windows IoT", + "ua" : "Mozilla/5.0 (Windows IoT 10.0; Android 6.0.1; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Mobile Safari/537.36 Edge/18.17763", + "expect" : + { + "name" : "Windows IoT", + "version" : "10.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/windows-mobile.json b/test/data/ua/os/windows-mobile.json new file mode 100644 index 0000000..5baf78c --- /dev/null +++ b/test/data/ua/os/windows-mobile.json @@ -0,0 +1,20 @@ +[ + { + "desc" : "Windows Mobile", + "ua" : "Mozilla/5.0 (ZTE-E_N72/N72V1.0.0B02;U;Windows Mobile/6.1;Profile/MIDP-2.0 Configuration/CLDC-1.1;320*240;CTC/2.0) IE/6.0 (compatible; MSIE 4.01; Windows CE; PPC)/UC Browser7.7.1.88", + "expect" : + { + "name" : "Windows Mobile", + "version" : "6.1" + } + }, + { + "desc" : "Windows Mobile", + "ua" : "Opera/9.80 (Windows Mobile; WCE; Opera Mobi/WMD-50433; U; en) Presto/2.4.13 Version/10.00", + "expect" : + { + "name" : "Windows Mobile", + "version" : "undefined" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/windows-phone.json b/test/data/ua/os/windows-phone.json new file mode 100644 index 0000000..a6a8b82 --- /dev/null +++ b/test/data/ua/os/windows-phone.json @@ -0,0 +1,29 @@ +[ + { + "desc" : "Windows Phone", + "ua" : "Opera/9.80 (Windows Phone; Opera Mini/7.6.8/35.7518; U; ru) Presto/2.8.119 Version/11.10", + "expect" : + { + "name" : "Windows Phone", + "version" : "undefined" + } + }, + { + "desc" : "Windows Phone OS", + "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; DELL; Venue Pro)", + "expect" : + { + "name" : "Windows Phone OS", + "version" : "7.0" + } + }, + { + "desc" : "Windows Phone 8", + "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; HTC; Windows Phone 8X by HTC)", + "expect" : + { + "name" : "Windows Phone", + "version" : "8.0" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/windows.json b/test/data/ua/os/windows.json new file mode 100644 index 0000000..39e9541 --- /dev/null +++ b/test/data/ua/os/windows.json @@ -0,0 +1,146 @@ +[ + { + "desc" : "Windows 95", + "ua" : "Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)", + "expect" : + { + "name" : "Windows", + "version" : "95" + } + }, + { + "desc" : "Windows 98", + "ua" : "Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)", + "expect" : + { + "name" : "Windows", + "version" : "98" + } + }, + { + "desc" : "Windows ME", + "ua" : "Mozilla/5.0 (Windows; U; Win 9x 4.90) Gecko/20020502 CS 2000 7.0/7.0", + "expect" : + { + "name" : "Windows", + "version" : "ME" + } + }, + { + "desc" : "Windows 2000", + "ua" : "Mozilla/3.0 (compatible; MSIE 3.0; Windows NT 5.0)", + "expect" : + { + "name" : "Windows", + "version" : "2000" + } + }, + { + "desc" : "Windows XP", + "ua" : "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 5.2)", + "expect" : + { + "name" : "Windows", + "version" : "XP" + } + }, + { + "desc" : "Windows Vista", + "ua" : "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; fr-FR)", + "expect" : + { + "name" : "Windows", + "version" : "Vista" + } + }, + { + "desc" : "Windows 7", + "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)", + "expect" : + { + "name" : "Windows", + "version" : "7" + } + }, + { + "desc" : "Windows 8", + "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Win64; x64; Trident/6.0; .NET4.0E; .NET4.0C)", + "expect" : + { + "name" : "Windows", + "version" : "8" + } + }, + { + "desc" : "Windows 10", + "ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0", + "expect" : + { + "name" : "Windows", + "version" : "10" + } + }, + { + "desc" : "WeChat Desktop for Windows Built-in Browser", + "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400", + "expect" : + { + "name" : "Windows", + "version" : "7" + } + }, + { + "desc" : "WeChat Desktop for Windows Built-in Browser major version in 4", + "ua" : "mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/81.0.4044.138 safari/537.36 nettype/wifi micromessenger/7.0.20.1781(0x6700143b) windowswechat", + "expect" : + { + "name" : "Windows", + "version" : "7" + } + }, + { + "desc" : "Windows RT", + "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0)", + "expect" : + { + "name" : "Windows", + "version" : "RT" + } + }, + { + "desc" : "Windows CE", + "ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)", + "expect" : + { + "name" : "Windows", + "version" : "CE" + } + }, + { + "desc" : "Windows NT on x86 or aarch64 CPU using Firefox", + "ua" : "Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "Windows", + "version" : "NT x" + } + }, + { + "desc" : "Windows NT on x64 CPU using Firefox", + "ua" : "Mozilla/5.0 (Windows NT x.y; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0", + "expect" : + { + "name" : "Windows", + "version" : "NT x" + } + }, + { + "desc" : "iTunes Windows Vista", + "ua" : "iTunes/10.7 (Windows; Microsoft Windows Vista Home Premium Edition Service Pack 1 (Build 6001)) AppleWebKit/536.26.9", + "expect" : + { + "name" : "Windows", + "version" : "Vista" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/xbox.json b/test/data/ua/os/xbox.json new file mode 100644 index 0000000..f8f9f67 --- /dev/null +++ b/test/data/ua/os/xbox.json @@ -0,0 +1,47 @@ +[ + { + "desc" : "Xbox 360", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox 360) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", + "expect" : + { + "name" : "Xbox", + "version" : "360" + } + }, + { + "desc" : "Xbox One", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19041", + "expect" : + { + "name" : "Xbox", + "version" : "One" + } + }, + { + "desc" : "Xbox X", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02", + "expect" : + { + "name" : "Xbox", + "version" : "X" + } + }, + { + "desc" : "Xbox Series X", + "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox Series X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02 ", + "expect" : + { + "name" : "Xbox", + "version" : "Series X" + } + }, + { + "desc" : "Xbox Series S", + "ua" : "Mozilla/5.0 (Compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Xbox; Xbox Series S)", + "expect" : + { + "name" : "Xbox", + "version" : "Series S" + } + } +] \ No newline at end of file diff --git a/test/data/ua/os/zenwalk.json b/test/data/ua/os/zenwalk.json new file mode 100644 index 0000000..230b5dd --- /dev/null +++ b/test/data/ua/os/zenwalk.json @@ -0,0 +1,11 @@ +[ + { + "desc" : "Zenwalk", + "ua" : "Flock/2.16 (Zenwalk 7.3; es_PR;)", + "expect" : + { + "name" : "Zenwalk", + "version" : "7.3" + } + } +] \ No newline at end of file diff --git a/test/playwright-test-main.spec.mjs b/test/e2e/browser.spec.mjs similarity index 85% rename from test/playwright-test-main.spec.mjs rename to test/e2e/browser.spec.mjs index db6e149..848694c 100644 --- a/test/playwright-test-main.spec.mjs +++ b/test/e2e/browser.spec.mjs @@ -2,7 +2,12 @@ import { test, expect } from '@playwright/test'; import path from 'path'; import url from 'url'; -const localHtml = `file://${path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '../')}/dist/ua-parser.html`; +const localHtml = `file://${path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '../../')}/dist/ua-parser.html`; +const browserMap = { + chromium: 'Chrome Headless', + firefox: 'Firefox', + webkit: 'Safari' +} test.describe('Custom navigator.userAgent tests', () => { @@ -42,48 +47,54 @@ test.describe('User-defined user-agent tests', () => { test.describe('withClientHints() tests', () => { - test('Detect custom Client Hints data', async ({ page }) => { - await page.addInitScript(() => { - Object.defineProperty(navigator, 'userAgentData', { - value: { - brands: [], - platform: '', - mobile: false, - getHighEntropyValues: () => { - return Promise.resolve({ - brands: [ - { - brand: 'Chromium', - version: '110' - }, - { - brand: 'Not(A:Brand', - version: '110' - }, - { - brand: 'New Browser', - version: '110' - } - ], - platform: 'New OS', - formFactors: 'New Form Factor' - }); + test('Detect custom Client Hints data', async ({ page, browserName }) => { + await page.addInitScript((browserName) => { + if (browserName == 'chromium') { + Object.defineProperty(navigator, 'userAgentData', { + value: { + brands: [], + platform: '', + mobile: false, + getHighEntropyValues: () => { + return Promise.resolve({ + brands: [ + { + brand: 'Chromium', + version: '110' + }, + { + brand: 'Not(A:Brand', + version: '110' + }, + { + brand: 'New Browser', + version: '110' + } + ], + platform: 'New OS', + formFactors: 'New Form Factor' + }); + } } - } - }); - }); + }); + } + }, browserName); await page.goto(localHtml); // @ts-ignore const uap = await page.evaluate(async () => await UAParser().withClientHints()); - expect(uap).toHaveProperty('browser.name', 'New Browser'); - expect(uap).toHaveProperty('os.name', 'New OS'); - expect(uap).toHaveProperty('device.type', undefined); + if (browserName == 'chromium') { + expect(uap).toHaveProperty('browser.name', 'New Browser'); + expect(uap).toHaveProperty('os.name', 'New OS'); + expect(uap).toHaveProperty('device.type', undefined); + } else { + expect(uap).toHaveProperty('browser.name', browserMap[browserName]); + } }); }); test.describe('withFeatureCheck() tests', () => { - test('Detect Brave', async ({ page }) => { + test('Detect Brave', async ({ page, browserName }) => { await page.addInitScript(() => { Object.defineProperty(navigator, 'brave', { value: { @@ -94,7 +105,7 @@ test.describe('withFeatureCheck() tests', () => { await page.goto(localHtml); // @ts-ignore let uap = await page.evaluate(() => UAParser()); - expect(uap).toHaveProperty('browser.name', 'Chrome Headless'); + expect(uap).toHaveProperty('browser.name', browserMap[browserName]); // @ts-ignore uap = await page.evaluate(() => UAParser().withFeatureCheck()); expect(uap).toHaveProperty('browser.name', 'Brave'); diff --git a/test/jazzer-fuzz-test.js b/test/fuzz/redos.js similarity index 87% rename from test/jazzer-fuzz-test.js rename to test/fuzz/redos.js index 8d87049..b046862 100644 --- a/test/jazzer-fuzz-test.js +++ b/test/fuzz/redos.js @@ -1,6 +1,6 @@ const { FuzzedDataProvider } = require('@jazzer.js/core'); -const { UAParser } = require('../src/main/ua-parser'); -const UA_MAX_LENGTH = 350; +const { UAParser } = require('../../dist/main'); +const UA_MAX_LENGTH = 500; module.exports.fuzz = function (buffer) { const data = new FuzzedDataProvider(buffer); diff --git a/test/specs/browser-libraries.json b/test/specs/browser-libraries.json deleted file mode 100644 index 1ebdcdc..0000000 --- a/test/specs/browser-libraries.json +++ /dev/null @@ -1,62 +0,0 @@ -[ - { - "desc" : "Axios", - "ua" : "axios/1.7.2", - "expect" : - { - "name" : "axios", - "version" : "1.7.2", - "type" : "library" - } - }, - { - "desc" : "Java", - "ua" : "Java/1.6.0_14", - "expect" : - { - "name" : "Java", - "version" : "1.6.0_14", - "type" : "library" - } - }, - { - "desc" : "jsdom", - "ua" : "Mozilla/5.0 (unknown OS) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/11.12.0", - "expect" : - { - "name" : "jsdom", - "version" : "11.12.0", - "type" : "library" - } - }, - { - "desc" : "Python urllib", - "ua" : "Python-urllib/2.6", - "expect" : - { - "name" : "Python-urllib", - "version" : "2.6", - "type" : "library" - } - }, - { - "desc" : "Python requests", - "ua" : "python-requests/2.32", - "expect" : - { - "name" : "python-requests", - "version" : "2.32", - "type" : "library" - } - }, - { - "desc" : "Scrapy", - "ua" : "Scrapy/1.5.0 (+https://scrapy.org)", - "expect" : - { - "name" : "Scrapy", - "version" : "1.5.0", - "type" : "library" - } - } -] diff --git a/test/specs/device-all.json b/test/specs/device-all.json deleted file mode 100644 index f0898b9..0000000 --- a/test/specs/device-all.json +++ /dev/null @@ -1,4489 +0,0 @@ -[ - { - "desc": "K", - "ua": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "K", - "type": "mobile" - } - }, - { - "desc": "Advan M4", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0; ADVAN M4 Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36 OPR/28.0.2254.119214", - "expect": { - "vendor": "ADVAN", - "model": "M4", - "type": "mobile" - } - }, - { - "desc": "Advan S40", - "ua": "Mozilla/5.0 (Linux; Android 7.0; ADVAN S40 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Mobile Safari/537.36 EdgA/79.0.309.58", - "expect": { - "vendor": "ADVAN", - "model": "S40", - "type": "mobile" - } - }, - { - "desc": "Advan Sketsa 2", - "ua": "Mozilla/5.0 (Linux; Android 11; ADVAN 1011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36", - "expect": { - "vendor": "ADVAN", - "model": "1011", - "type": "mobile" - } - }, - { - "desc": "ASUS Nexus 7", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "Nexus 7", - "type": "tablet" - } - }, - { - "desc": "ASUS Padfone", - "ua": "Mozilla/5.0 (Linux; Android 4.1.1; PadFone 2 Build/JRO03L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "PadFone", - "type": "tablet" - } - }, - { - "desc": "ASUS ZenPad 10", - "ua": "Mozilla/5.0 (Linux; Android 6.0; P00C Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "P00C", - "type": "tablet" - } - }, - { - "desc": "ASUS ZenPad Z8s", - "ua": "Mozilla/5.0 (Linux; Android 7.0; ASUS_P00J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Safari/537.36\n", - "expect": { - "vendor": "ASUS", - "model": "P00J", - "type": "tablet" - } - }, - { - "desc": "ASUS ROG", - "ua": "Mozilla/5.0 (Linux; Android 8.1; ZS600KL Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZS600KL", - "type": "mobile" - } - }, - { - "desc": "ASUS ROG II", - "ua": "Mozilla/5.0 (Linux; Android 9; ASUS_I001DA Build/PKQ1.190414.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "I001DA", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 2", - "ua": "Mozilla/5.0 (Linux; Android 5.0; ASUS ZenFone 2 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZenFone 2", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 3 Deluxe", - "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_Z016D Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.132 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "Z016D", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 5", - "ua": "Mozilla/5.0 (Linux; Android 8.0; ZE620KL Build/OPR1.170623.032) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZE620KL", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 7", - "ua": "Mozilla/5.0 (Linux; Android 10; ASUS_I002D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.81 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "I002D", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 7 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; ZS671KS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZS671KS", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Max Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; ZB602KL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "ZB602KL", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Max Pro (M1)", - "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X00TD Build/OPM1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "X00TD", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Max M2", - "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01AD) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "X01AD", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Max Pro M2", - "ua": "Mozilla/5.0 (Linux; Android 8.1; ASUS_X01BDA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.99 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "X01BDA", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone Go", - "ua": "Mozilla/5.0 (Linux; Android 6.0; ASUS_X009DA Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "X009DA", - "type": "mobile" - } - }, - { - "desc": "ASUS Zenfone 2 Laser", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ASUS_Z00ED) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "ASUS", - "model": "Z00ED", - "type": "mobile" - } - }, - { - "desc": "Acer Iconia A1-810", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; A1-810 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", - "expect": { - "vendor": "Acer", - "model": "A1-810", - "type": "tablet" - } - }, - { - "desc": "BlackBerry Priv", - "ua": "User-Agent: Mozilla/5.0 (Linux; Android 5.1.1; STV100-1 Build/LMY47V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/46.0.2490.76 Mobile Safari/537.36", - "expect": { - "vendor": "BlackBerry", - "model": "STV100-1", - "type": "mobile" - } - }, - { - "desc": "BlackBerry Keyone", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBB100-1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Mobile Safari/537.36", - "expect": { - "vendor": "BlackBerry", - "model": "BBB100-1", - "type": "mobile" - } - }, - { - "desc": "BlackBerry Key2", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BBF100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", - "expect": { - "vendor": "BlackBerry", - "model": "BBF100-1", - "type": "mobile" - } - }, - { - "desc": "BlackBerry Key2 LE", - "ua": "User-Agent: Mozilla/5.0 (Linux; Android 8.1.0; BBE100-1 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497 Mobile Safari/537.36", - "expect": { - "vendor": "BlackBerry", - "model": "BBE100-1", - "type": "mobile" - } - }, - { - "desc": "Blackview 4900Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; BV4900Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "BV4900Pro", - "type": "mobile" - } - }, - { - "desc": "Cat B15Q", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; B15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "Cat", - "model": "B15Q", - "type": "mobile" - } - }, - { - "desc": "Cat B35", - "ua": "Mozilla/5.0 (Mobile; CAT B35; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.1", - "expect": { - "vendor": "Cat", - "model": "B35", - "type": "mobile" - } - }, - { - "desc": "Cat S22 Flip", - "ua": "Mozilla/5.0 (Linux; Android 11; S22 FLIP Build/RKQ1.210416.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36", - "expect": { - "vendor": "Cat", - "model": "S22 FLIP", - "type": "mobile" - } - }, - { - "desc": "Cat S62 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; S62 Pro Build/RKQ1.210406.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.85 Mobile Safari/537.36 GSA/12.34.17.23.arm64", - "expect": { - "vendor": "Cat", - "model": "S62 Pro", - "type": "mobile" - } - }, - { - "desc": "Desktop (IE11 with Tablet string)", - "ua": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; GWX:MANAGED; rv:11.0) like Gecko", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "undefined" - } - }, - { - "desc": "Mobile (DuckDuckGo mobile browser)", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile DuckDuckGo/5 Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Energizer Energy 400", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Energy400 Build/MRA58K test-keys; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.158 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/172.0.0.66.93;]", - "expect": { - "vendor": "Energizer", - "model": "Energy400", - "type": "mobile" - } - }, - { - "desc": "Energizer Energy 400S", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Energy 400S Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.85 Mobile Safari/537.36", - "expect": { - "vendor": "Energizer", - "model": "Energy 400S", - "type": "mobile" - } - }, - { - "desc": "Energizer Ultimate 65G", - "ua": "Mozilla/5.0 (Linux; Android 14; Energizer Ultimate 65G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Energizer", - "model": "Ultimate 65G", - "type": "mobile" - } - }, - { - "desc": "Fairphone 1U", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; FP1U Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Fairphone", - "model": "FP1U", - "type": "mobile" - } - }, - { - "desc": "Fairphone 2", - "ua": "Mozilla/5.0 (Linux; Android 7.1.2; FP2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Fairphone", - "model": "FP2", - "type": "mobile" - } - }, - { - "desc": "Fairphone 3", - "ua": "Mozilla/5.0 (Linux; Android 9; FP3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", - "expect": { - "vendor": "Fairphone", - "model": "FP3", - "type": "mobile" - } - }, - { - "desc": "HTC Desire 820", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; HTC Desire 820 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", - "expect": { - "vendor": "HTC", - "model": "Desire 820", - "type": "mobile" - } - }, - { - "desc": "HTC Evo Shift 4G", - "ua": "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0", - "expect": { - "vendor": "Sprint", - "model": "APA7373KT", - "type": "mobile" - } - }, - { - "desc": "HTC Nexus 9", - "ua": "Mozilla/5.0 (Linux; Android 5.0; Nexus 9 Build/LRX21R) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Mobile Crosswalk/7.36.154.13 Safari/537.36", - "expect": { - "vendor": "HTC", - "model": "Nexus 9", - "type": "tablet" - } - }, - { - "desc": "Huawei Honor", - "ua": "Mozilla/5.0 (Linux; U; Android 2.3; xx-xx; U8860 Build/HuaweiU8860) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", - "expect": { - "vendor": "Huawei", - "model": "U8860", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L41) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L41", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-AL10", - "type": "mobile" - } - }, - { - "desc": "Huawei Nexus 6P", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC19V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537", - "expect": { - "vendor": "Huawei", - "model": "Nexus 6P", - "type": "mobile" - } - }, - { - "desc": "Huawei P10", - "ua": "Mozilla/5.0 (Linux; Android 7.0; VTR-L09 Build/HUAWEIVTR-L09; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "VTR-L09", - "type": "mobile" - } - }, - { - "desc": "Huawei Y3II", - "ua": "Mozilla/5.0 (Linux; U; Android 5.1; xx-xx; HUAWEI LUA-L03 Build/HUAWEILUA-L03) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LUA-L03", - "type": "mobile" - } - }, - { - "desc": "HUAWEI MediaPad M3 Lite 10", - "ua": "Mozilla/5.0 (Linux; Android 7.0; BAH-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BAH-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; BAH2-W19 Build/HUAWEIBAH2-W19; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BAH2-W19", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad M5", - "ua": "Mozilla/5.0 (Linux; Android 9; SHT-AL09 Build/HUAWEISHT-AL09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "SHT-AL09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T5", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; AGS2-L09 Build/HUAWEIAGS2-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/84.0.4147.125 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS2-L09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10", - "ua": "Mozilla/5.0 (Linux; Android 10; AGR-W09 Build/HUAWEIAGR-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGR-W09", - "type": "tablet" - } - }, - { - "desc": "HUAWEI MediaPad T10s", - "ua": "Mozilla/5.0 (Linux; Android 10; AGS3-W09 Build/HUAWEIAGS3-W09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGS3-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei MatePad T 10", - "ua": "Mozilla/5.0 (Linux; Android 10; AGR-L09; HMSCore 5.0.4.301) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.3.304 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AGR-L09", - "type": "tablet" - } - }, - { - "desc": "Huawei M3", - "ua": "Mozilla/5.0 (Linux; Android 7.0; BTV-W09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BTV-W09", - "type": "tablet" - } - }, - { - "desc": "Huawei Mate 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 8.0; BLA-L29 Build/HUAWEIBLA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3236.6 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BLA-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate X", - "ua": "Mozilla/5.0 (Linux; Android 9; TAH-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "TAH-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate X2", - "ua": "Mozilla/5.0 (Linux; Android 10; TET-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "TET-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 X", - "ua": "Mozilla/5.0 (Linux; Android 9; EVR-L29 Build/HUAWEIEVR-L29; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "EVR-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L09", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-AL00", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-AL10", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L0C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L0C", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; LYA-TL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LYA-TL00", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 50 Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; DCO-LX9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "DCO-LX9", - "type": "mobile" - } - }, - { - "desc": "Huawei P20 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "ANE-LX1", - "type": "mobile" - } - }, - { - "desc": "Huawei P20", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; EML-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "EML-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P20 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; CLT-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "CLT-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P30", - "ua": "Mozilla/5.0 (Linux; Android 9; ELE-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "ELE-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P30 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "VOG-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei P40", - "ua": "Mozilla/5.0 (Linux; Android 10; ANA-AN00 Build/HUAWEIANA-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/11.26 SP-engine/2.22.0 baiduboxapp/11.26.0.10 (Baidu; P1 10) NABar/1.0", - "expect": { - "vendor": "Huawei", - "model": "ANA-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei P40 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; ELS-AN00 Build/HUAWEIELS-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/6.0.0", - "expect": { - "vendor": "Huawei", - "model": "ELS-AN00", - "type": "mobile" - } - }, - { - "desc": "Huawei 30 Pro+", - "ua": "Mozilla/5.0 (Linux; Android 10; EBG-AN10 Build/HUAWEIEBG-AN10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36 EdgA/42.0.0.2741", - "expect": { - "vendor": "Huawei", - "model": "EBG-AN10", - "type": "mobile" - } - }, - { - "desc": "Huawei 30S", - "ua": "Mozilla/5.0 (Linux; Android 10; CDY-AN90 Build/HUAWEICDY-AN90; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 mailapp/5.8.0", - "expect": { - "vendor": "Huawei", - "model": "CDY-AN90", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L21", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L61", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L71) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L71", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YAL-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YAL-L61D", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YALE-L61A", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L61D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YALE-L61D", - "type": "mobile" - } - }, - { - "desc": "Huawei Nova 5T", - "ua": "Mozilla/5.0 (Linux; Android 10; YALE-L71A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "YALE-L71A", - "type": "mobile" - } - }, - { - "desc": "Huawei Enjoy10e", - "ua": "Dalvik/2.1.0 (Linux; U; Android 10; MED-AL00 Build/HUAWEIMED-AL00)", - "expect": { - "vendor": "Huawei", - "model": "MED-AL00", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 6A", - "ua": "Mozilla/5.0 (Linux; Android 7.0; DLI-L22 Build/HONORDLI-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/252.0.0.22.355;]", - "expect": { - "vendor": "Honor", - "model": "DLI-L22", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 7", - "ua": "Mozilla/5.0 (Linux; Android 6.0; PLK-L01 Build/HONORPLK-L01; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "PLK-L01", - "type": "mobile" - } - }, - { - "desc": "Huawei 10 Lite", - "ua": "Mozilla/5.0 (Linux; Android 9; HRY-LX1 Build/HONORHRY-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", - "expect": { - "vendor": "Honor", - "model": "HRY-LX1", - "type": "mobile" - } - }, - { - "desc": "Huawei Y7 2018", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; LDN-L01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "LDN-L01", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 8X", - "ua": "Mozilla/5.0 (Linux; Android 9; JSN-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "JSN-L21", - "type": "mobile" - } - }, - { - "desc": "Huawei Y6 2019", - "ua": "Mozilla/5.0 (Linux; Android 9; MRD-LX1N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "MRD-LX1N", - "type": "mobile" - } - }, - { - "desc": "Huawei Y9 2019", - "ua": "Mozilla/5.0 (Linux; Android 9; JKM-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "JKM-LX2", - "type": "mobile" - } - }, - { - "desc": "Huawei Y5", - "ua": "Mozilla/5.0 (Linux; Android 9; AMN-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "AMN-LX3", - "type": "mobile" - } - }, - { - "desc": "Huawei Y7p", - "ua": "Mozilla/5.0 (Linux; Android 9; ART-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "ART-L29", - "type": "mobile" - } - }, - { - "desc": "Huawei Mate 20 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SNE-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "SNE-LX1", - "type": "mobile" - } - }, - { - "desc": "Huawei P10 Lite", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; WAS-LX1A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "WAS-LX1A", - "type": "mobile" - } - }, - { - "desc": "Huawei Y5 Lite 2018", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; DRA-LX5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "DRA-LX5", - "type": "mobile" - } - }, - { - "desc": "Huawei Honor 8C", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; BKK-LX2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Huawei", - "model": "BKK-LX2", - "type": "mobile" - } - }, - { - "desc": "IMO FEEL A2", - "ua": "Mozilla/5.0 (Linux; Android 5.1; IMO FEEL A2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/49.0.2623.105 Mobile Safari/537.36", - "expect": { - "vendor": "IMO", - "model": "FEEL A2", - "type": "mobile" - } - }, - { - "desc": "IMO Q2", - "ua": "Mozilla/5.0 (Linux; Android 5.1; IMO Q2 Build/LMY47D; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/65.0.3325.109 Mobile Safari/537.36 GSA/7.22.24.21.arm", - "expect": { - "vendor": "IMO", - "model": "Q2", - "type": "mobile" - } - }, - { - "desc": "IMO S2", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; IMO S2 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.162 Mobile Safari/537.36", - "expect": { - "vendor": "IMO", - "model": "S2", - "type": "mobile" - } - }, - { - "desc": "IMO Tab X9", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; id-id; IMO TAB X9 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", - "expect": { - "vendor": "IMO", - "model": "TAB X9", - "type": "tablet" - } - }, - { - "desc": "Infinix Hot 7 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; Infinix X625C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X625C", - "type": "mobile" - } - }, - { - "desc": "Infinix Hot 10T", - "ua": "Mozilla/5.0 (Linux; Android 11; Infinix X689C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X689C", - "type": "mobile" - } - }, - { - "desc": "Infinix Hot 11s", - "ua": "Mozilla/5.0 (Linux; Android 11; Infinix X6812 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X6812", - "type": "mobile" - } - }, - { - "desc": "Infinix Smart 5", - "ua": "Mozilla/5.0 (Linux; Android 10; Infinix X657C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X657C", - "type": "mobile" - } - }, - { - "desc": "Infinix Zero 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; Infinix X6815B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Infinix", - "model": "X6815B", - "type": "mobile" - } - }, - { - "desc": "Apple Desktop", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15", - "expect": { - "vendor": "Apple", - "model": "Macintosh", - "type": "undefined" - } - }, - { - "desc": "Apple Watch", - "ua": "atc/1.0 watchOS/7.3.3 model/Watch4,2 hwp/t8006 build/18S830 (6; dt:191)", - "expect": { - "vendor": "Apple", - "model": "watch", - "type": "wearable" - } - }, - { - "desc": "iPad using UCBrowser", - "ua": "Mozilla/5.0 (iPad; U; CPU OS 11_2 like Mac OS X; zh-CN; iPad5,3) AppleWebKit/534.46 (KHTML, like Gecko) UCBrowser/3.0.1.776 U3/ Mobile/10A403 Safari/7543.48.3", - "expect": { - "vendor": "Apple", - "model": "iPad", - "type": "tablet" - } - }, - { - "desc": "iPad Air", - "ua": "Mozilla/5.0 (iPad; CPU OS 12_4_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPad4,1;FBMD/iPad;FBSN/iOS;FBSV/12.4.5;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPad", - "type": "tablet" - } - }, - { - "desc": "iPad using Facebook Browser", - "ua": "Mozilla/5.0 (iPad; CPU OS 14_4_2 like Mac OS X) WebKit/8610 (KHTML, like Gecko) Mobile/18D70 [FBAN/FBIOS;FBDV/iPad7,11;FBMD/iPad;FBSN/iOS;FBSV/14.4.2;FBSS/2;FBID/tablet;FBLC/en_US;FBOP/5]", - "expect": { - "vendor": "Apple", - "model": "iPad", - "type": "tablet" - } - }, - { - "desc": "iPod", - "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53", - "expect": { - "vendor": "Apple", - "model": "iPod touch", - "type": "mobile" - } - }, - { - "desc": "JVC LT-43V55LFA Smart TV", - "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB211 VSTVB MB200 HbbTV/1.2.1 (; JVC; MB211; 3.19.4.2; _TV_NT72563_2017 SmartTvA/3.0.0", - "expect": { - "vendor": "JVC", - "model": "MB211", - "type": "smarttv" - } - }, - { - "desc": "JVC LT-43V65LUA Smart TV", - "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 OPR/40.0.2207.0 OMI/4.9.0.237.DOM3-OPT.245 Model/Vestel-MB130 VSTVB MB100 HbbTV/1.2.1 (; JVC; MB130; 5.7.20.0; _TV_G10_2017;) SmartTvA/3.0.0", - "expect": { - "vendor": "JVC", - "model": "MB130", - "type": "smarttv" - } - }, - { - "desc": "Kobo eReader", - "ua": "Mozilla/5.0 (Unknown; Linux) AppleWebKit/538.1 (KHTML, like Gecko) Kobo eReader Safari/538.1", - "expect": { - "vendor": "Kobo", - "model": "eReader", - "type": "tablet" - } - }, - { - "desc": "Kobo Touch", - "ua": "Mozilla/5.0 (Linux; U; Android 2.0; en-us;) AppleWebKit/538.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/538.1 (Kobo Touch 0377/4.20.14622)", - "expect": { - "vendor": "Kobo", - "model": "Touch", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab 2", - "ua": "Mozilla/5.0 (Linux; Android 5.0.1; Lenovo TAB 2 A7-30HC Build/LRX21M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.157 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TAB 2 A7", - "type": "tablet" - } - }, - { - "desc": "Lenovo Phone", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Lenovo PB2-650M Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.105 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/311.0.0.44.117;]", - "expect": { - "vendor": "Lenovo", - "model": "PB2-650M", - "type": "mobile" - } - }, - { - "desc": "Lenovo Tab 3 Pro", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Lenovo YT3-X90F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "YT3-X90F", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab 4", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Lenovo TB-X304F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TB-X304F", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab 4", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Lenovo TAB 2 A7-30HC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TAB 2 A7", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab 7 Essential", - "ua": "Mozilla/5.0 (Linux; Android 7.0; Lenovo TB-7304X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TB-7304X", - "type": "tablet" - } - }, - { - "desc": "Lenovo Tab M10", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 9; Lenovo TB-X606F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 YaBrowser/20.9.4.99.01 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "TB-X606F", - "type": "tablet" - } - }, - { - "desc": "Lenovo IdeaTab S6000", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; IdeaTab S6000-H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 YaBrowser/18.11.1.1011.01 Safari/537.36", - "expect": { - "vendor": "Lenovo", - "model": "IdeaTab S6000-H", - "type": "tablet" - } - }, - { - "desc": "LG V40 ThinQ", - "ua": "Mozilla/5.0 (Linux; Android 9; LM-V405) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-V405", - "type": "mobile" - } - }, - { - "desc": "LG K30", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; LM-X410.F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-X410.F", - "type": "mobile" - } - }, - { - "desc": "LG K30", - "ua": "Mozilla/5.0 (Linux; Android 9; LM-X410.FGN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-X410.FGN", - "type": "mobile" - } - }, - { - "desc": "LG K40", - "ua": "Mozilla/5.0 (Linux; Android 10; LM-X420) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-X420", - "type": "mobile" - } - }, - { - "desc": "LG Stylo 4", - "ua": "Mozilla/5.0 (Linux; Android 10; LM-Q710(FGN)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "LM-Q710(FGN)", - "type": "mobile" - } - }, - { - "desc": "LG Stylo 5", - "ua": "Mozilla/5.0 (Linux; Android 9; LM-Q720) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-Q720", - "type": "mobile" - } - }, - { - "desc": "LG G7 ThinQ", - "ua": "Mozilla/5.0 (Linux; Android 9; LM-G710VM Build/PKQ1.181105.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-G710VM", - "type": "mobile" - } - }, - { - "desc": "LG K20", - "ua": "Mozilla/5.0 (Android 13; Mobile; LG-M255; rv:111.0) Gecko/111.0 Firefox/111.0", - "expect": { - "vendor": "LG", - "model": "M255", - "type": "mobile" - } - }, - { - "desc": "LG K500", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; LG-K500 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "K500", - "type": "mobile" - } - }, - { - "desc": "LG Nexus 4", - "ua": "Mozilla/5.0 (Linux; Android 4.2.1; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", - "expect": { - "vendor": "LG", - "model": "Nexus 4", - "type": "mobile" - } - }, - { - "desc": "LG Nexus 4", - "ua": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; Google Nexus 4 - 4.3 - API 18 - 768x1280 Build/JLS36G) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "LG", - "model": "Nexus 4", - "type": "mobile" - } - }, - { - "desc": "LG Nexus 5", - "ua": "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", - "expect": { - "vendor": "LG", - "model": "Nexus 5", - "type": "mobile" - } - }, - { - "desc": "LG Wing", - "ua": "Mozilla/5.0 (Linux; Android 10; LM-F100N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LM-F100N", - "type": "mobile" - } - }, - { - "desc": "LG Smart TV", - "ua": "Mozilla/5.0 (DirectFB; U; Linux mips; en) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) LG Browser (; LG NetCast.TV-2011)", - "expect": { - "vendor": "LG", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "LG Smart TV", - "ua": "Mozilla/5.0 (Linux; NetCast; U) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/53.0.2785 34 Safari/537.31 SmartTV/8.5", - "expect": { - "vendor": "LG", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "LG Android TV", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; LG Android TV Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", - "expect": { - "vendor": "LG", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "Loewe Smart TV", - "ua": "Mozilla/5.0 (Linux; U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2207.0 LOEWE-SL410/5.2.0.0 HbbTV/1.4.1 (; LOEWE; SL410; LOH/5.2.0.0;;) FVC/3.0 (LOEWE; SL410;) CE-HTML/1.0 Config (L:deu,CC:DEU) NETRANGEMMH", - "expect": { - "vendor": "LOEWE", - "model": "SL410", - "type": "smarttv" - } - }, - { - "desc": "Meizu M5 Note", - "ua": "Mozilla/5.0 (Linux; Android 6.0; M5 Note Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043024 Safari/537.36 MicroMessenger/6.5.7.1040 NetType/WIFI Language/zh_CN", - "expect": { - "vendor": "Meizu", - "model": "M5 Note", - "type": "mobile" - } - }, - { - "desc": "Micromax Bharat 2 Plus", - "ua": "Mozilla/5.0 (Linux; U; Android 7.0; en-US; Micromax Q402Plus Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.12.9.1226 Mobile Safari/537.36", - "expect": { - "vendor": "Micromax", - "model": "Q402Plus", - "type": "mobile" - } - }, - { - "desc": "Micromax Canvas Infinity", - "ua": "Mozilla/5.0 (Linux; U; Android 7.1.2; en-US; Micromax HS2 Build/N2G47H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/13.2.0.1296 (SpeedMode) U4/1.0 UCWEB/2.0 Mobile Safari/534.30", - "expect": { - "vendor": "Micromax", - "model": "HS2", - "type": "mobile" - } - }, - { - "desc": "Micromax In 1b", - "ua": "Mozilla/5.0 (Linux; U; Android 10; Micromax E7533 Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36 OPR/54.0.2254.56148", - "expect": { - "vendor": "Micromax", - "model": "E7533", - "type": "mobile" - } - }, - { - "desc": "Microsoft Lumia 950", - "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", - "expect": { - "vendor": "Microsoft", - "model": "Lumia 950", - "type": "mobile" - } - }, - { - "desc": "Microsoft Surface Duo", - "ua": "Dalvik/2.1.0 (Linux; U; Android 10; Surface Duo Build/2020.1014.61)", - "expect": { - "vendor": "Microsoft", - "model": "Surface Duo", - "type": "tablet" - } - }, - { - "desc": "Motorola Moto X", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; XT1097 Build/KXE21.187-38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.109 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "XT1097", - "type": "mobile" - } - }, - { - "desc": "Motorola Moto Z3 Play", - "ua": "Mozilla/5.0 (Linux; Android 9; Moto Z3 Play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "Moto Z3 Play", - "type": "mobile" - } - }, - { - "desc": "Meizu M3S", - "ua": "Mozilla/5.0 (X11; Linux; Android 5.1; MZ-M3s Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrom/45.0.2454.94 Mobile Safari/537.36", - "expect": { - "vendor": "Meizu", - "model": "M3s", - "type": "mobile" - } - }, - { - "desc": "Microsoft Lumia 950", - "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", - "expect": { - "vendor": "Microsoft", - "model": "Lumia 950", - "type": "mobile" - } - }, - { - "desc": "Motorola Nexus 6", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.20 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "Nexus 6", - "type": "mobile" - } - }, - { - "desc": "Motorola Droid RAZR 4G", - "ua": "Mozilla/5.0 (Linux; U; Android 2.3; xx-xx; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", - "expect": { - "vendor": "Motorola", - "model": "DROID RAZR 4G", - "type": "mobile" - } - }, - { - "desc": "Motorola RAZR 2019", - "ua": "Mozilla/5.0 (Linux; Android 9; motorola razr) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.1 Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "razr", - "type": "mobile" - } - }, - { - "desc": "iPhone", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPhone SE", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPhone SE using Facebook App", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone8,4;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPhone 11 Pro Max", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone12,5;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPhone XS", - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone11,2;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/3;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "iPod touch", - "ua": "Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53", - "expect": { - "vendor": "Apple", - "model": "iPod touch", - "type": "mobile" - } - }, - { - "desc": "itel A25", - "ua": "Mozilla/5.0 (Linux; Android 9; itel L5002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.130 Mobile Safari/537.36 OPR/63.3.3216.58675", - "expect": { - "vendor": "itel", - "model": "L5002", - "type": "mobile" - } - }, - { - "desc": "itel A50", - "ua": "Mozilla/5.0 (Linux; U; Android 14; itel A667L Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Mobile Safari/537.36 OPR/83.1.2254.73239", - "expect": { - "vendor": "itel", - "model": "A667L", - "type": "mobile" - } - }, - { - "desc": "itel KidPad 1", - "ua": "Mozilla/5.0 (Linux; Android 10; Itel W7001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.101 Mobile Safari/537.36", - "expect": { - "vendor": "itel", - "model": "W7001", - "type": "tablet" - } - }, - { - "desc": "itel Pad One", - "ua": "Mozilla/5.0 (Linux; Android 12; itel P10001L Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.172 Safari/537.36", - "expect": { - "vendor": "itel", - "model": "P10001L", - "type": "tablet" - } - }, - { - "desc": "itel RS4", - "ua": "Mozilla/5.0 (Linux; Android 13; itel S666LN Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.165 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/468.1.0.56.78;]", - "expect": { - "vendor": "itel", - "model": "S666LN", - "type": "mobile" - } - }, - { - "desc": "itel Vision 2S", - "ua": "Mozilla/5.0 (Linux; Android 11; itel P651L Build/RP1A.201005.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.76 Mobile Safari/537.36", - "expect": { - "vendor": "itel", - "model": "P651L", - "type": "mobile" - } - }, - { - "desc": "Moto X", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2; xx-xx; XT1058 Build/13.9.0Q2.X-70-GHOST-ATT_LE-2) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Motorola", - "model": "XT1058", - "type": "mobile" - } - }, - { - "desc": "Motorola Moto g(6) Play", - "ua": "Mozilla/5.0 (Linux; Android 9; moto g(6) play) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "moto g(6) play", - "type": "mobile" - } - }, - { - "desc": "Motorola Moto g(7) Supra", - "ua": "Mozilla/5.0 (Linux; Android 9; moto g(7) supra Build/PCOS29.114-134-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/73.0.3683.90 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "moto g(7) supra", - "type": "mobile" - } - }, - { - "desc": "Motorola Moto E", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; Moto E (4) Build/NDQS26.69-64-11-7; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "Motorola", - "model": "Moto E (4)", - "type": "mobile" - } - }, - { - "desc": "Nokia3xx", - "ua": "Nokia303/14.87 CLDC-1.1", - "expect": { - "vendor": "Nokia", - "model": "303", - "type": "mobile" - } - }, - { - "desc": "Nokia 3.2", - "ua": "Mozilla/5.0 (Linux; Android 10; Nokia 3.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36", - "expect": { - "vendor": "Nokia", - "model": "3.2", - "type": "mobile" - } - }, - { - "desc": "Nokia 7", - "ua": "Mozilla/5.0 (Linux; Android 11; Nokia 7.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Nokia", - "model": "7.2", - "type": "mobile" - } - }, - { - "desc": "Nokia N9", - "ua": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", - "expect": { - "vendor": "Nokia", - "model": "N9", - "type": "mobile" - } - }, - { - "desc": "Nokia 2720 Flip", - "ua": "Mozilla/5.0 (Mobile; Nokia_2720_Flip; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.2", - "expect": { - "vendor": "Nokia", - "model": "2720 Flip", - "type": "mobile" - } - }, - { - "desc": "Nothing 1", - "ua": "Mozilla/5.0 (Linux; Android 13; A063) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36", - "expect": { - "vendor": "Nothing", - "model": "A063", - "type": "mobile" - } - }, - { - "desc": "Nothing 2", - "ua": "Mozilla/5.0 (Linux; Android 14; A065 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.53 Mobile Safari/537.36", - "expect": { - "vendor": "Nothing", - "model": "A065", - "type": "mobile" - } - }, - { - "desc": "Nothing 2a", - "ua": "Mozilla/5.0 (Linux; Android 14; A142 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.71 Mobile Safari/537.36", - "expect": { - "vendor": "Nothing", - "model": "A142", - "type": "mobile" - } - }, - { - "desc": "Oculus Quest", - "ua": "Mozilla/5.0 (Linux; Android 10; Quest) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", - "expect": { - "vendor": "Facebook", - "model": "Quest", - "type": "xr" - } - }, - { - "desc": "Oculus Quest 2", - "ua": "Mozilla/5.0 (Linux; Android 10; Quest 2) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/15.0.0.0.22.280317669 SamsungBrowser/4.0 Chrome/89.0.4389.90 VR Safari/537.36", - "expect": { - "vendor": "Facebook", - "model": "Quest 2", - "type": "xr" - } - }, - { - "desc": "Oculus Quest 3", - "ua": "Mozilla/5.0 (X11; Linux x86_64; Quest 3) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/31.4.0.6.51.566757996 Chrome/120.0.6099.283 VR Safari/537.36", - "expect": { - "vendor": "Facebook", - "model": "Quest 3", - "type": "xr" - } - }, - { - "desc": "Oculus Quest Pro", - "ua": "Mozilla/5.0 (X11; Linux x86_64; Quest Pro) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/24.4.0.22.60.426469926 SamsungBrowser/4.0 Chrome/106.0.5249.181 VR Safari/537.36", - "expect": { - "vendor": "Facebook", - "model": "Quest Pro", - "type": "xr" - } - }, - { - "desc": "Issue #747", - "ua": "python-requests/2.25.1", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "undefined" - } - }, - { - "desc": "OnePlus One", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; A0001 Build/KTU84Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A0001", - "type": "mobile" - } - }, - { - "desc": "OnePlus One", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; OnePlus One A0001 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A0001", - "type": "mobile" - } - }, - { - "desc": "OnePlus 2", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; ONE A2003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A2003", - "type": "mobile" - } - }, - { - "desc": "OnePlus 3", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ONEPLUS A3000 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A3000", - "type": "mobile" - } - }, - { - "desc": "OnePlus 6", - "ua": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6003) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A6003", - "type": "mobile" - } - }, - { - "desc": "OnePlus 6T", - "ua": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6010) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "A6010", - "type": "mobile" - } - }, - { - "desc": "OnePlus 7T Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; HD1913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.57 Mobile Safari/537.36 EdgA/110.0.1587.66", - "expect": { - "vendor": "undefined", - "model": "HD1913", - "type": "mobile" - } - }, - { - "desc": "OnePlus 8T", - "ua": "Mozilla/5.0 (Linux; Android 11; KB2005) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "KB2005", - "type": "mobile" - } - }, - { - "desc": "OnePlus 8 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; IN2025) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.119 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "IN2025", - "type": "mobile" - } - }, - { - "desc": "OnePlus 10RT", - "ua": "Mozilla/5.0 (Linux; Android 13; CPH2413) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "CPH2413", - "type": "mobile" - } - }, - { - "desc": "OnePlus Nord N100", - "ua": "Mozilla/5.0 (Linux; Android 10; BE2015 Build/QKQ1.200719.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "BE2015", - "type": "mobile" - } - }, - { - "desc": "OnePlus Nord N10 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; BE2029) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", - "expect": { - "vendor": "OnePlus", - "model": "BE2029", - "type": "mobile" - } - }, - { - "desc": "OPPO Pad", - "ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; OPD2101 Build/TP1A.220905.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "OPD2101", - "type": "tablet" - } - }, - { - "desc": "OPPO Neo", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; R831T Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 OppoBrowser/3.3.2 Mobile Safari/534.30", - "expect": { - "vendor": "OPPO", - "model": "R831T", - "type": "mobile" - } - }, - { - "desc": "OPPO R7s", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; OPPO R7s Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/7.1 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "R7s", - "type": "mobile" - } - }, - { - "desc": "OPPO A3s", - "ua": "Mozilla/5.0 (Linux; Android 8.1; CPH1803 Build/OPM1.171019.026; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "CPH1803", - "type": "mobile" - } - }, - { - "desc": "OPPO A12", - "ua": "Mozilla/5.0 (Linux; Android 9; CPH2083) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "CPH2083", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno", - "ua": "Mozilla/5.0 (Linux; Android 9; PCAT00 Build/PKQ1.190101.001; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PCAT00", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno3 Pro 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; PCLM50) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.117 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PCLM50", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno4 SE", - "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PEAM00 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PEAM00", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno4 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; PDPM00 Build/QKQ1.200216.002; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PDPM00", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno4 Pro 5G", - "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; PDNT00 Build/QKQ1.200216.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PDNT00", - "type": "mobile" - } - }, - { - "desc": "OPPO Reno5 A", - "ua": "Mozilla/5.0 (Linux; Android 11; A101OP) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "A101OP", - "type": "mobile" - } - }, - { - "desc": "OPPO Find X", - "ua": "Mozilla/5.0 (Linux; Android 8.1; PAFM00 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "PAFM00", - "type": "mobile" - } - }, - { - "desc": "OPPO Find 7a", - "ua": "Mozilla/5.0 (Linux; U; Android 4.3; xx-xx; X9007 Build/JLS36C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "OPPO", - "model": "X9007", - "type": "mobile" - } - }, - { - "desc": "OPPO F5", - "ua": "ozilla/5.0 (Linux; Android 7.1.1; CPH1723) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "OPPO", - "model": "CPH1723", - "type": "mobile" - } - }, - { - "desc": "Realme C1", - "ua": "Mozilla/5.0 (Linux; Android 8.1; RMX1811 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX1811", - "type": "mobile" - } - }, - { - "desc": "Realme C2", - "ua": "Mozilla/5.0 (Linux; Android 9; RMX1941) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX1941", - "type": "mobile" - } - }, - { - "desc": "Realme Narzo 20", - "ua": "Mozilla/5.0 (Linux; U; Android 10; xx-xx; RMX2193 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX2193", - "type": "mobile" - } - }, - { - "desc": "Realme 2 Pro", - "ua": "Mozilla/5.0 (Linux; Android 9; RMX1801) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX1801", - "type": "mobile" - } - }, - { - "desc": "Realme 3 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; RMX1851) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX1851", - "type": "mobile" - } - }, - { - "desc": "Realme 8", - "ua": "Mozilla/5.0 (Linux; Android 12; RMX3085) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX3085", - "type": "mobile" - } - }, - { - "desc": "Realme 9 Pro", - "ua": "Mozilla/5.0 (Linux; Android 13; RMX3471) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX3471", - "type": "mobile" - } - }, - { - "desc": "Realme GT Master", - "ua": "Mozilla/5.0 (Linux; Android 13; RMX3363) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Realme", - "model": "RMX3363", - "type": "mobile" - } - }, - { - "desc": "Panasonic T31", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; Panasonic T31 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.170 Mobile Safari/537.36 ", - "expect": { - "vendor": "Panasonic", - "model": "T31", - "type": "mobile" - } - }, - { - "desc": "Panasonic TX-32CSW514 SmartTV", - "ua": "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", - "expect": { - "vendor": "Panasonic", - "model": "VIERA 2015", - "type": "smarttv" - } - }, - { - "desc": "Panasonic TX-40FXW724 SmartTV", - "ua": "HbbTV/1.4.1 (+DRM;Panasonic;SmartTV2018mid;3.024;4301-0003 0002-0000;SmartTV2018;)", - "expect": { - "vendor": "Panasonic", - "model": "SmartTV2018mid", - "type": "smarttv" - } - }, - { - "desc": "Panasonic TX-43HXW904 SmartTV", - "ua": "HbbTV/1.5.1 (+DRM;Panasonic;SmartTV2020mid;3.326;4301-0003 0008-0000;com.panasonic.SmartTV2020mid;)", - "expect": { - "vendor": "Panasonic", - "model": "SmartTV2020mid", - "type": "smarttv" - } - }, - { - "desc": "Panasonic DMR-HST130 SAT receiver", - "ua": "HbbTV/1.1.1 (+PVR;Panasonic;DIGA WebKit M8658;3.420;;)", - "expect": { - "vendor": "Panasonic", - "model": "DIGA WebKit M8658", - "type": "smarttv" - } - }, - { - "desc": "Philips SmartTV", - "ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60", - "expect": { - "vendor": "Philips", - "model": "", - "type": "smarttv" - } - }, - { - "desc": "Philips 32PFL6606K/02 SmartTV (2011)", - "ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70", - "expect": { - "vendor": "Philips", - "model": "", - "type": "smarttv" - } - }, - { - "desc": "Philips 32PFL6606K/02 SmartTV (2013)", - "ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70", - "expect": { - "vendor": "Philips", - "model": "", - "type": "smarttv" - } - }, - { - "desc": "Philips 32PHS5301/12 SmartTV (2016)", - "ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 OPR/29.0.1803.0 OMI/4.5.23.37.MOT2.13 HbbTV/1.2.1 (;Philips;32PHS5301/12;;_TV_MT5800;) Firmware/TPM161E_012.002.045.001 en", - "expect": { - "vendor": "Philips", - "model": "32PHS5301/12", - "type": "smarttv" - } - }, - { - "desc": "Pico 4", - "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.8.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.38 Chrome/105.0.5195.68 VR Safari/537.36", - "expect": { - "vendor": "PICO", - "model": "4", - "type": "xr" - } - }, - { - "desc": "Pico 4", - "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0", - "expect": { - "vendor": "PICO", - "model": "4", - "type": "xr" - } - }, - { - "desc": "Pico Neo3 Link", - "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", - "expect": { - "vendor": "Pico", - "model": "Neo3 Link", - "type": "xr" - } - }, - { - "desc": "Polytron Prime 7 Pro", - "ua": "Mozilla/5.0 (Linux; U; Android 7.0; POLYTRON_P552 Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/64.0.3282.137 Mobile Safari/537.36 OPR/50.0.2254.149182", - "expect": { - "vendor": "POLYTRON", - "model": "P552", - "type": "mobile" - } - }, - { - "desc": "Polytron Rocket T1", - "ua": "Mozilla/5.0 (Linux; U; Android 5.0; en-US; POLYTRON R2501 Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/13.1.2.1293 Mobile Safari/537.36", - "expect": { - "vendor": "POLYTRON", - "model": "R2501", - "type": "mobile" - } - }, - { - "desc": "Polytron Rocket T6", - "ua": "Mozilla/5.0 (Linux; Android 7.0; POLYTRON R2509) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.92 Mobile Safari/537.36", - "expect": { - "vendor": "POLYTRON", - "model": "R2509", - "type": "mobile" - } - }, - { - "desc": "Polytron Zap 6 Posh", - "ua": "Mozilla/5.0 (Linux; U; Android 5.1; in-ID; POLYTRON_4G501 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.10.0.1163 UCTurbo/1.9.9.900 Mobile Safari/537.36", - "expect": { - "vendor": "POLYTRON", - "model": "4G501", - "type": "mobile" - } - }, - { - "desc": "Roku", - "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", - "expect": { - "vendor": "Roku", - "model": "", - "type": "smarttv" - } - }, - { - "desc": "Roku", - "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Roku/DVP-8.10 (468.10E04145A)", - "expect": { - "vendor": "Roku", - "model": "DVP-8.10", - "type": "smarttv" - } - }, - { - "desc": "Roku", - "ua": "Roku4640X/DVP-7.70 (297.70E04154A)", - "expect": { - "vendor": "Roku", - "model": "DVP-7.70", - "type": "smarttv" - } - }, - { - "desc": "Xiaomi TV", - "ua": "Mozilla/5.0 (Linux; Android 10; MiTV-MOOQ0 Build/QTG3.200305.006; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.61 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MiTV-MOOQ0", - "type": "smarttv" - } - }, - { - "desc": "Kindle Fire HD", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", - "expect": { - "vendor": "Amazon", - "model": "KFTT", - "type": "tablet" - } - }, - { - "desc": "Kindle Fire HD", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true", - "expect": { - "vendor": "Amazon", - "model": "KFTT", - "type": "tablet" - } - }, - { - "desc": "Echo Show 5", - "ua": "Mozilla/5.0 (Linux; Android 5.1; AEORK Build/LVY48F; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "AEORK", - "type": "tablet" - } - }, - { - "desc": "Echo Show 8", - "ua": "Mozilla/5.0 (Linux; Android 7.1; AEOCH) AppleWebKit/537.36 (KHTML, like Gecko) Silk/77.2.21 like Chrome/77.0.3865.92 Mobile Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "AEOCH", - "type": "tablet" - } - }, - { - "desc": "Echo Show 8", - "ua": "Mozilla/5.0 (Linux; Android 7.1.2; AEOCW) AppleWebKit/537.36 (KHTML, like Gecko) Silk/106.3.3 like Chrome/106.0.5249.170 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "AEOCW", - "type": "tablet" - } - }, - { - "desc": "Echo Show 15", - "ua": "Mozilla/5.0 (Linux; Android 9; AEOHY) AppleWebKit/537.36 (KHTML, like Gecko) Silk/112.6.3 like Chrome/112.0.5615.213 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "AEOHY", - "type": "tablet" - } - }, - { - "desc": "Echo Dot", - "ua": "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AEOBC Build/LVY48F)", - "expect": { - "vendor": "Amazon", - "model": "AEOBC", - "type": "embedded" - } - }, - { - "desc": "Samsung Galaxy A21s", - "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-A217F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.0 Chrome/75.0.3770.143 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A217F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A31", - "ua": "Mozilla/5.0 (Linux; Android 10; SM-A315G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A315G", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A50", - "ua": "Mozilla/5.0 (Linux; Android 9; SM-A505F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.105 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A505F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A50s", - "ua": "Mozilla/5.0 (Linux; Android 11; SM-A507FN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A507FN", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A52s", - "ua": "Mozilla/5.0 (Linux; Android 13; SM-A528B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A528B", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy A80", - "ua": "Mozilla/5.0 (Linux; Android 9; SM-A805F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.112 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-A805F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Fold", - "ua": "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-F900U Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.2 Chrome/67.0.3396.87 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-F900U", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Z Flip", - "ua": "Mozilla/5.0 (Linux; Android 10; SM-F700N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-F700N", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Z Fold2", - "ua": "Mozilla/5.0 (Linux; Android 10; SM-F916B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-F916B", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S10E", - "ua": "Mozilla/5.0 (Linux; Android 9; SM-G970F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G970F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S20 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; SCG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SCG01", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Note 10+", - "ua": "Mozilla/5.0 (Linux; Android 9; SM-N976V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.89 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-N976V", - "type": "mobile" - } - }, - { - "desc": "Samsung SM-C5000", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; SM-C5000 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 wkbrowser 4.1.35 3065", - "expect": { - "vendor": "Samsung", - "model": "SM-C5000", - "type": "mobile" - } - }, - { - "desc": "Samsung C8", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; SM-C7108) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-C7108", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Note 8", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; GT-N5100 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "GT-N5100", - "type": "tablet" - } - }, - { - "desc": "Samsung SM-T231", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T231 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T231", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab 6 Lite", - "ua": "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-P610) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/12.0 Chrome/79.0.3945.136 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-P610", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab A 9.7", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; SM-P550 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.90 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-P550", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab A 10.1", - "ua": " Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-T515) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/13.0 Chrome/83.0.4103.106 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T515", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab S7", - "ua": "Mozilla/5.0 (Linux; Android 10; SM-T870) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T870", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab S8", - "ua": "Mozilla/5.0 (Linux; Android 12; SM-X706B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-X706B", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab S", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T700 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T700", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Tab Pro 10.1", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-T520 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-T520", - "type": "tablet" - } - }, - { - "desc": "Samsung Galaxy Watch", - "ua": "Mozilla/5.0 (Linux; Tizen 5.5; SAMSUNG SM-R805W) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.0 Chrome/69.0.3497.106 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-R805W", - "type": "wearable" - } - }, - { - "desc": "Samsung Galaxy Watch Active 2", - "ua": "Mozilla/5.0 (Linux; Tizen 5.5; SAMSUNG SM-R820) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.0 Chrome/69.0.3497.106 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-R820", - "type": "wearable" - } - }, - { - "desc": "Samsung Galaxy Watch4", - "ua": "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-R875U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.2. Chrome/102.0.5005.125 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-R875U", - "type": "wearable" - } - }, - { - "desc": "Samsung Galaxy Watch5 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; SAMSUNG SM-R925U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.2. Chrome/111.0.5563.116 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-R925U", - "type": "wearable" - } - }, - { - "desc": "Samsung Note 10.1", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-P605) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-P605", - "type": "tablet" - } - }, - { - "desc": "Samsung SmartTV2011", - "ua": "HbbTV/1.1.1 (;;;;;) Maple;2011", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2011", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV2012", - "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2012", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV2014", - "ua": "HbbTV/1.1.1 (;Samsung;SmartTV2014;T-NT14UDEUC-1060.4;;) WebKit", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2014", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV", - "ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV", - "ua": "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", - "expect": { - "vendor": "Samsung", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "Samsung SmartTV HBBTV", - "ua": "HbbTV/1.5.1 (+DRM;Samsung;SmartTV2021:UAU7000;T-KSU2EDEUC-1506.0;KantSU2e;urn:samsungtv:familyname:21_KANTSU2E_UHD_BASIC:2021;) Tizen/6.0 (+TVPLUS+SmartHubLink) Chrome/76 LaTivu_1.0.1_2021 RVID/17", - "expect": { - "vendor": "Samsung", - "model": "SmartTV2021:UAU7000", - "type": "smarttv" - } - }, - { - "desc": "Sharp AQUOS-TVX19B", - "ua": "Mozilla/5.0 (Linux; Android 9; AQUOS-TVX19B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "AQUOS-TVX19B", - "type": "smarttv" - } - }, - { - "desc": "Sharp Aquos B10", - "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-A01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SH-A01", - "type": "mobile" - } - }, - { - "desc": "Sharp Aquos L2", - "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02 Build/S4045) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SH-L02", - "type": "mobile" - } - }, - { - "desc": "Sharp Aquos L2", - "ua": "Mozilla/5.0 (Linux; Android 7.0; SH-L02) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SH-L02", - "type": "mobile" - } - }, - { - "desc": "Sharp Aquos R2", - "ua": "Mozilla/5.0 (Linux; Android 8.0; SHV42) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.92 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SHV42", - "type": "mobile" - } - }, - { - "desc": "Smartfren Andromax L", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Andromax B26D2H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Smartfren", - "model": "Andromax B26D2H", - "type": "mobile" - } - }, - { - "desc": "Smartfren Andromax G2", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Smartfren Andromax AD9A1H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.83 Mobile Safari/537.36", - "expect": { - "vendor": "Smartfren", - "model": "Andromax AD9A1H", - "type": "mobile" - } - }, - { - "desc": "Smartfren New Andromax I", - "ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; id-id; New Andromax-i Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Smartfren", - "model": "New Andromax-i", - "type": "mobile" - } - }, - { - "desc": "SONY Xperia 1 III", - "ua": "Mozilla/5.0 (Linux; Android 11; A101SO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "A101SO", - "type": "mobile" - } - }, - { - "desc": "Sony G8141 (Xperia XZ1)", - "ua": "Mozilla/5.0 (Linux; Android 9; SO-01K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "SO-01K", - "type": "mobile" - } - }, - { - "desc": "Sony G8141 (Xperia XZ Premium)", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; G8141) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "G8141", - "type": "mobile" - } - }, - { - "desc": "Sony C5303 (Xperia SP)", - "ua": "Mozilla/5.0 (Linux; Android 4.3; C5303 Build/12.1.A.1.205) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.93 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "C5303", - "type": "mobile" - } - }, - { - "desc": "Sony SO-02F (Xperia Z1 F)", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; SO-02F Build/14.1.H.2.119) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "SO-02F", - "type": "mobile" - } - }, - { - "desc": "Sony D6653 (Xperia Z3)", - "ua": "Mozilla/5.0 (Linux; Android 4.4; D6653 Build/23.0.A.0.376) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "D6653", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia SOL25 (ZL2)", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4; SOL25 Build/17.1.1.C.1.64) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Sony", - "model": "SOL25", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia SP", - "ua": "Mozilla/5.0 (Linux; Android 4.3; C5302 Build/12.1.A.1.201) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "C5302", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia L4", - "ua": "Mozilla/5.0 (Linux; Android 9; XQ-AD51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "XQ-AD51", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia 1ii", - "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AT51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "XQ-AT51", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia 1ii", - "ua": "Mozilla/5.0 (Linux; Android 10; SOG01) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "SOG01", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia 10ii", - "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AU52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "XQ-AU52", - "type": "mobile" - } - }, - { - "desc": "Sony Xperia Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; XQ-AQ52) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.185 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "XQ-AQ52", - "type": "mobile" - } - }, - { - "desc": "Sony SGP521 (Xperia Z2 Tablet)", - "ua": "Mozilla/5.0 (Linux; Android 4.4; SGP521 Build/17.1.A.0.432) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" - } - }, - { - "desc": "Sony Xperia Z2 Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SGP561) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.99 Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" - } - }, - { - "desc": "Sony Tablet S", - "ua": "Mozilla/5.0 (Linux; U; Android 3.1; Sony Tablet S Build/THMAS10000) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13", - "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" - } - }, - { - "desc": "Sony Tablet Z LTE", - "ua": "Mozilla/5.0 (Linux; U; Android 4.1; SonySGP321 Build/10.2.C.0.143) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30", - "expect": { - "vendor": "Sony", - "model": "Xperia Tablet", - "type": "tablet" - } - }, - { - "desc": "Sony BRAVIA 4K GB ATV3", - "ua": "Mozilla/5.0 (Linux; Andr0id 9; BRAVIA 4K GB ATV3 Build/PTT1.190515.001.S38) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.0.180.DIA5.104 Model/Sony-BRAVIA-4K-GB-ATV3", - "expect": { - "vendor": "Sony", - "model": "BRAVIA 4K GB ATV3", - "type": "smarttv" - } - }, - { - "desc": "Sony BRAVIA 4K GB ATV3", - "ua": "Mozilla/5.0 (Linux; Android 9; BRAVIA 4K GB ATV3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Sony", - "model": "BRAVIA 4K GB ATV3", - "type": "smarttv" - } - }, - { - "desc": "Sony Bravia 4k UR2", - "ua": "Mozilla/5.0 (Linux: Andr0id 9: BRAVIA 4K UR2 Build/PTT1.190515.001.S104) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 OPR/46.0.2207.0 OMI/4.13.5.431.DIA5HBBTV.250 Model/Sony-BRAVIA-4K-UR2", - "expect": { - "vendor": "Sony", - "model": "BRAVIA 4K UR2", - "type": "smarttv" - } - }, - { - "desc": "TCL 10 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; T790Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 EdgA/114.0.1823.43", - "expect": { - "vendor": "TCL", - "model": "T790Y", - "type": "mobile" - } - }, - { - "desc": "TCL 10 5G UW", - "ua": "Mozilla/5.0 (Linux; Android 10; T790S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T790S", - "type": "mobile" - } - }, - { - "desc": "TCL 10 Plus", - "ua": "Mozilla/5.0 (Linux; Android 11; T782H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Mobile Safari/537.36 OPR/64.3.3282.60839", - "expect": { - "vendor": "TCL", - "model": "T782H", - "type": "mobile" - } - }, - { - "desc": "TCL 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; T799B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T799B", - "type": "mobile" - } - }, - { - "desc": "TCL 10 SE", - "ua": "Mozilla/5.0 (Linux; Android 10; T766H_RU) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T766H", - "type": "mobile" - } - }, - { - "desc": "TCL 10 TabMax", - "ua": "Mozilla/5.0 (Linux; Android 11; 9296Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9296Q", - "type": "tablet" - } - }, - { - "desc": "TCL 10 TabMax 4G", - "ua": "Mozilla/5.0 (Linux; Android 10; 9295G_EEA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9295G", - "type": "tablet" - } - }, - { - "desc": "TCL 10 TabMax WiFi", - "ua": "Mozilla/5.0 (Linux; Android 10; 9296G_TR) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9296G", - "type": "tablet" - } - }, - { - "desc": "TCL 10L", - "ua": "Mozilla/5.0 (Linux; Android 10; T770B Build/QKQ1.200329.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 GSA/11.41.10.23.arm64", - "expect": { - "vendor": "TCL", - "model": "T770B", - "type": "mobile" - } - }, - { - "desc": "TCL 10L", - "ua": "Mozilla/5.0 (Linux; Android 11; T770H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T770H", - "type": "mobile" - } - }, - { - "desc": "TCL 20 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; T781) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T781", - "type": "mobile" - } - }, - { - "desc": "TCL 20 Pro 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T810S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Mobile Safari/537.36 EdgA/113.0.1774.63", - "expect": { - "vendor": "TCL", - "model": "T810S", - "type": "mobile" - } - }, - { - "desc": "TCL 20 SE", - "ua": "Mozilla/5.0 (Linux; Android 11; T671H Build/RKQ1.201112.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.73 Mobile Safari/537.36 GoogleApp/13.9.7.23.arm64", - "expect": { - "vendor": "TCL", - "model": "T671H", - "type": "mobile" - } - }, - { - "desc": "TCL 20 XE", - "ua": "Mozilla/5.0 (Linux; Android 11; 5087Z) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "5087Z", - "type": "mobile" - } - }, - { - "desc": "TCL 20B", - "ua": "Mozilla/5.0 (Linux; Android 11; 6159K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "6159K", - "type": "mobile" - } - }, - { - "desc": "TCL 205", - "ua": "Mozilla/5.0 (Linux; Android 11; 4187D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "4187D", - "type": "mobile" - } - }, - { - "desc": "TCL 20E", - "ua": "Mozilla/5.0 (Linux; Android 11; 6125A) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/18.0 Chrome/99.0.4844.88 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "6125A", - "type": "mobile" - } - }, - { - "desc": "TCL 20L", - "ua": "Mozilla/5.0 (Linux; Android 11; T774H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.59 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T774H", - "type": "mobile" - } - }, - { - "desc": "TCL 20L Plus", - "ua": "Mozilla/5.0 (Linux; Android 11; T775H Build/RKQ1.210107.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T775H", - "type": "mobile" - } - }, - { - "desc": "TCL 20R 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; T767H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36 OPR/71.3.3718.67322", - "expect": { - "vendor": "TCL", - "model": "T767H", - "type": "mobile" - } - }, - { - "desc": "TCL 20S", - "ua": "Mozilla/5.0 (Linux; Android 11; T773O) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T773O", - "type": "mobile" - } - }, - { - "desc": "TCL 20Y", - "ua": "Mozilla/5.0 (Linux; Android 11; 6156D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.134 Mobile Safari/537.36 OPR/70.3.3653.66287", - "expect": { - "vendor": "TCL", - "model": "6156D", - "type": "mobile" - } - }, - { - "desc": "TCL 30 V 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; T781S Build/RKQ1.210614.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/369.0.0.5.110;]", - "expect": { - "vendor": "TCL", - "model": "T781S", - "type": "mobile" - } - }, - { - "desc": "TCL 30 XE 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T767W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/416.0.0.35.85;]", - "expect": { - "vendor": "TCL", - "model": "T767W", - "type": "mobile" - } - }, - { - "desc": "TCL 305", - "ua": "Mozilla/5.0 (Linux; arm; Android 11; 6102D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.167 YaBrowser/22.7.6.96.00 SA/3 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "6102D", - "type": "mobile" - } - }, - { - "desc": "TCL 306", - "ua": "Mozilla/5.0 (Linux; Android 12; 6102H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.141 Mobile Safari/537.36[FBAN/EMA;FBLC/it_IT;FBAV/332.0.0.22.108;]", - "expect": { - "vendor": "TCL", - "model": "6102H", - "type": "mobile" - } - }, - { - "desc": "TCL 30", - "ua": "Mozilla/5.0 (Linux; Android 12; T676H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T676H", - "type": "mobile" - } - }, - { - "desc": "TCL 30+", - "ua": "Mozilla/5.0 (Linux; Android 12; T676J) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T676J", - "type": "mobile" - } - }, - { - "desc": "TCL 30 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T776H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T776H", - "type": "mobile" - } - }, - { - "desc": "TCL 30 LE", - "ua": "Mozilla/5.0 (Linux; Android 12; 4188V Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36[FBAN/EMA;FBLC/en_US;FBAV/352.0.0.14.108;]", - "expect": { - "vendor": "TCL", - "model": "4188V", - "type": "mobile" - } - }, - { - "desc": "TCL 30 SE", - "ua": "Mozilla/5.0 (Linux; Android 12; 6165H Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/396.1.0.28.104;]", - "expect": { - "vendor": "TCL", - "model": "6165H", - "type": "mobile" - } - }, - { - "desc": "TCL 30E", - "ua": "Mozilla/5.0 (Linux; Android 12; 6127I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "6127I", - "type": "mobile" - } - }, - { - "desc": "TCL 40 NxtPaper", - "ua": "Mozilla/5.0 (Linux; Android 13; T612B Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.53 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T612B", - "type": "mobile" - } - }, - { - "desc": "TCL A3", - "ua": "Mozilla/5.0 (Linux; Android 11; A509DL Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Mobile Safari/537.36 GSA/13.18.7.23.arm64", - "expect": { - "vendor": "TCL", - "model": "A509DL", - "type": "mobile" - } - }, - { - "desc": "TCL A30", - "ua": "Mozilla/5.0 (Linux; Android 11; 5102L Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.136 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/413.0.0.30.104;]", - "expect": { - "vendor": "TCL", - "model": "5102L", - "type": "mobile" - } - }, - { - "desc": "TCL 40 SE", - "ua": "Mozilla/5.0 (Linux; Android 13; T610K Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T610K", - "type": "mobile" - } - }, - { - "desc": "TCL 40 XE 5G", - "ua": "Mozilla/5.0 (Linux; Android 13; T609DL Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.136 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/466.1.0.57.85;]", - "expect": { - "vendor": "TCL", - "model": "T609DL", - "type": "mobile" - } - }, - { - "desc": "TCL 403", - "ua": "Mozilla/5.0 (Linux; Android 12; T431D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T431D", - "type": "mobile" - } - }, - { - "desc": "TCL 405", - "ua": "Mozilla/5.0 (Linux; Android 12; T506D Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]", - "expect": { - "vendor": "TCL", - "model": "T506D", - "type": "mobile" - } - }, - { - "desc": "TCL 408", - "ua": "Mozilla/5.0 (Linux; U; Android 12; T507U Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/105.0.5195.136 Mobile Safari/537.36 OPR/75.0.2254.68857", - "expect": { - "vendor": "TCL", - "model": "T507U", - "type": "mobile" - } - }, - { - "desc": "TCL 40R 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T771K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 EdgA/114.0.1823.37", - "expect": { - "vendor": "TCL", - "model": "T771K", - "type": "mobile" - } - }, - { - "desc": "TCL Ion X", - "ua": "Mozilla/5.0 (Linux; Android 12; T430W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.60 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T430W", - "type": "mobile" - } - }, - { - "desc": "TCL NxtPaper 11", - "ua": "Mozilla/5.0 (Linux; Android 13; 9466X Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.179 Safari/537.36 [FB_IAB/FB4A;FBAV/473.0.0.41.81;]", - "expect": { - "vendor": "TCL", - "model": "9466X", - "type": "tablet" - } - }, - { - "desc": "TCL Stylus 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; T779W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.2 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "T779W", - "type": "mobile" - } - }, - { - "desc": "TCL Tab 8 4G", - "ua": "Mozilla/5.0 (Linux; Android 10; 9048S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9048S", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 8 LE", - "ua": "Mozilla/5.0 (Linux; Android 12; 9137W Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9137W", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10 FHD 4G", - "ua": "Mozilla/5.0 (Linux; Android 11; 9060G Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.196 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9060G", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10 HD 4G", - "ua": "Mozilla/5.0 (Linux; Android 11; 9060X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9060X", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10 LTE", - "ua": "Mozilla/5.0 (Linux; Android 13; 8196G Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.162 Safari/537.36 [FB_IAB/FB4A;FBAV/471.0.0.35.80;]", - "expect": { - "vendor": "TCL", - "model": "8196G", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10 WiFi", - "ua": "Mozilla/5.0 (Linux; Android 13; 8496G Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.61 Safari/537.36 [FB_IAB/FB4A;FBAV/474.0.0.52.74;]", - "expect": { - "vendor": "TCL", - "model": "8496G", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10L", - "ua": "Mozilla/5.0 (Linux; Android 11; 8491X_EEA Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.105 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "8491X", - "type": "tablet" - } - }, - { - "desc": "TCL Tab 10s 4G", - "ua": "Mozilla/5.0 (Linux; Android 11; 9080G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "9080G", - "type": "tablet" - } - }, - { - "desc": "TCL Xess P17AA", - "ua": "Mozilla/5.0 (Linux; Android 5.1; TCL Xess P17AA Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Safari/537.36", - "expect": { - "vendor": "TCL", - "model": "Xess P17AA", - "type": "tablet" - } - }, - { - "desc": "Tecno KC8", - "ua": "Mozilla/5.0 (Linux; Android 10; TECNO KC8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TECNO", - "model": "KC8", - "type": "mobile" - } - }, - { - "desc": "Tecno Spark 8C", - "ua": "Mozilla/5.0 (Linux; Android 11; TECNO KG5n) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "TECNO", - "model": "KG5n", - "type": "mobile" - } - }, - { - "desc": "Tesla", - "ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1", - "expect": { - "vendor": "Tesla", - "model": "undefined", - "type": "embedded" - } - }, - { - "desc": "Tesla", - "ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chromium/79.0.3945.130 Chrome/79.0.3945.130 Safari/537.36 Tesla/2020.16.2.1-e99c70fff409", - "expect": { - "vendor": "Tesla", - "model": "undefined", - "type": "embedded" - } - }, - { - "desc": "TechniSAT Digit ISIO S SAT receiver", - "ua": "Opera/9.80 (Linux sh4; U; HbbTV/1.1.1 (;;;;;); CE-HTML; TechniSat Digit ISIO S; de) Presto/2.9.167 Version/11.50", - "expect": { - "vendor": "TechniSat", - "model": "Digit ISIO S", - "type": "smarttv" - } - }, - { - "desc": "TechniSAT MultyVision SmartTV", - "ua": "Opera/9.80 (Linux i686; U; HbbTV/1.1.1 (;;;;;); CE-HTML; TechniSat MultyVision ISIO; de) Presto/2.9.167 Version/11.50", - "expect": { - "vendor": "TechniSat", - "model": "MultyVision ISIO", - "type": "smarttv" - } - }, - { - "desc": "Ulefone Armor", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Armor Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.107 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Armor", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 6.0; Armor) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 YaBrowser/20.4.2.101.00 SA/1 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Armor", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor 8 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; Armor 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.1.3922.71199", - "expect": { - "vendor": "Ulefone", - "model": "Armor 8 Pro", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor 12 5G", - "ua": "Mozilla/5.0 (Linux; Android 11; Armor 12 5G Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.166 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Armor 12 5G", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor 20WT", - "ua": "Mozilla/5.0 (Linux; Android 12; Armor 20WT) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/22.0 Chrome/111.0.5563.116 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Armor 20WT", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor Pad", - "ua": "Mozilla/5.0 (Linux; Android 12; Armor Pad Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/431.0.0.30.108;]", - "expect": { - "vendor": "Ulefone", - "model": "Armor Pad", - "type": "mobile" - } - }, - { - "desc": "Ulefone Armor X5 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; Armor X5 Pro Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/430.0.0.23.113;]", - "expect": { - "vendor": "Ulefone", - "model": "Armor X5 Pro", - "type": "mobile" - } - }, - { - "desc": "Ulefone Power Armor 14 Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor14 Pro Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.138 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Power Armor14 Pro", - "type": "mobile" - } - }, - { - "desc": "Ulefone Power Armor 18T", - "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor 18T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Ulefone", - "model": "Power Armor 18T", - "type": "mobile" - } - }, - { - "desc": "Ulefone Power Armor 19T", - "ua": "Mozilla/5.0 (Linux; Android 12; Power Armor 19T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.192 Mobile Safari/537.36 OPR/74.3.3922.71982", - "expect": { - "vendor": "Ulefone", - "model": "Power Armor 19T", - "type": "mobile" - } - }, - { - "desc": "Xiaomi 2201117TG", - "ua": "Mozilla/5.0 (Linux; Android 11; 2201117TG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.98 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "2201117TG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi M2004J19C", - "ua": "Mozilla/5.0 (Linux; Android 11; M2004J19C Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.77 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2004J19C", - "type": "mobile" - } - }, - { - "desc": "Xiaomi M2006C3MNG", - "ua": "Mozilla/5.0 (Linux; Android 11; M2006C3MNG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.85 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2006C3MNG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi 21061119DG", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; 21061119DG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 YaBrowser/23.3.7.24.00 SA/3 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "21061119DG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi 2013023", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; en-US; 2013023 Build/HM2013023) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/10.0.1.512 U3/0.8.0 Mobile Safari/533.1", - "expect": { - "vendor": "Xiaomi", - "model": "2013023", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Hongmi Note 1W", - "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-CN; HM NOTE 1W Build/JDQ39) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.7.9.439 U3/0.8.0 Mobile Safari/533.1", - "expect": { - "vendor": "Xiaomi", - "model": "HM NOTE 1W", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 3C", - "ua": "Mozilla/5.0 (Linux; U; Android 4.3; zh-CN; MI 3C Build/JLS36C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.7.9.439 U3/0.8.0 Mobile Safari/533.1", - "expect": { - "vendor": "Xiaomi", - "model": "MI 3C", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 5", - "ua": "Mozilla/5.0 (Linux; Android 7.0; MI 5 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.83 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI 5", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 6", - "ua": "Mozilla/5.0 (Linux; Android 7.1; MI 6 Build/NMF26X; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.125 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI 6", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 10 Pro", - "ua": "Linux; U; Android 13; Mi 10 Pro Build/TKQ1.221114.001", - "expect": { - "vendor": "Xiaomi", - "model": "Mi 10 Pro", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 5s Plus", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; MI 5s Plus Build/MXB48T) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/8.7.1", - "expect": { - "vendor": "Xiaomi", - "model": "MI 5s Plus", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi A1", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Mi A1 Build/OPR1.170623.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi A1", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi Note", - "ua": "Mozilla/5.0 (Linux; Android 4.4.4; MI NOTE LTE Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI NOTE LTE", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi One Plus", - "ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; MI-ONE Plus Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", - "expect": { - "vendor": "Xiaomi", - "model": "MI-ONE Plus", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi Max 3", - "ua": "Mozilla/5.0 (Linux; Android 9; MI MAX 3 Build/PKQ1.181007.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI MAX 3", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi A1", - "ua": "Mozilla/5.0 (Linux; Android 9; Mi A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.101 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi A1", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi A2 Lite", - "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2 Lite) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.62 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi A2 Lite", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi 9 SE", - "ua": "Mozilla/5.0 (Linux; Android 9; Mi 9 SE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi 9 SE", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi A2", - "ua": "Mozilla/5.0 (Linux; Android 9; Mi A2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Mi A2", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Mi CC9", - "ua": "Mozilla/5.0 (Linux; U; Android 11; zh-cn; MI CC 9 Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.116 Mobile Safari/537.36 XiaoMi/MiuiBrowser/15.5.18", - "expect": { - "vendor": "Xiaomi", - "model": "MI CC 9", - "type": "mobile" - } - }, - { - "desc": "Xiaomi MI PAD 2", - "ua": "Mozilla/5.0 (Linux; Android 5.1; MI PAD 2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Safari/537.36 [FB_IAB/FB4A;FBAV/137.0.0.24.91;]", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD 2", - "type": "tablet" - } - }, - { - "desc": "Xiaomi MI PAD 4 PLUS", - "ua": "Mozilla/5.0 (Linux; Android 8.1; MI PAD 4 PLUS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "MI PAD 4 PLUS", - "type": "tablet" - } - }, - { - "desc": "Xiaomi POCO X2", - "ua": "Mozilla/5.0 (Linux; Android 10; POCO X2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "POCO X2", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO X3 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; M2102J20SI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2102J20SI", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO X3 Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; M2102J20SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2102J20SG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO X3 NFC", - "ua": "Mozilla/5.0 (Linux; Android 12; M2007J20CG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2007J20CG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO M2 Pro", - "ua": "Mozilla/5.0 (Linux; arm_64; Android 11; POCO M2 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 YaBrowser/22.11.7.42.00 SA/3 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "POCO M2 Pro", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCO M3", - "ua": "Mozilla/5.0 (Linux; Android 10; M2010J19CI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2010J19CI", - "type": "mobile" - } - }, - { - "desc": "Xiaomi POCOPHONE F1", - "ua": "Mozilla/5.0 (Linux; Android 10; POCOPHONE F1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "POCOPHONE F1", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi 4A", - "ua": "Mozilla/5.0 (Linux; Android 6.0; Redmi 4A Build/MMB29M; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi 4A", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi 10C", - "ua": "Mozilla/5.0 (Linux; Android 12; 220333QAG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "220333QAG", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi K30 5G", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 5G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi K30 5G", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi K30 Pro", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi K30 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi K30 Pro", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi Note 3", - "ua": "Mozilla/5.0 (Linux; Android 6.0.1; Redmi Note 3 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.116 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 3", - "type": "mobile" - } - }, - { - "desc": "Xiaomi Redmi Note 9 Pro Max", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9 Pro Max) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.99 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 9 Pro Max", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 9S", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 9S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 9S", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 10 5G", - "ua": "Mozilla/5.0 (Linux; Android 12; M2103K19C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2103K19C", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 13; M2101K6P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2101K6P", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 10 Pro", - "ua": "Mozilla/5.0 (Linux; Android 12; M2101K6G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "M2101K6G", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 8", - "ua": "Mozilla/5.0 (Linux; Android 10; Redmi Note 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Xiaomi", - "model": "Redmi Note 8", - "type": "mobile" - } - }, - { - "desc": "XiaoMi Redmi Note 12 Turbo", - "ua": "Mozilla/5.0 (Linux; Android 13; 23049RAD8C; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/16.7.1.1", - "expect": { - "vendor": "Xiaomi", - "model": "23049RAD8C", - "type": "mobile" - } - }, - { - "desc": "ZTE Blade A6", - "ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE BLADE A0620 Build/NMF26F; ru-ru) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.2.0.50586AP", - "expect": { - "vendor": "ZTE", - "model": "BLADE A0620", - "type": "mobile" - } - }, - { - "desc": "PlayStation 4", - "ua": "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", - "expect": { - "vendor": "Sony", - "model": "PlayStation 4", - "type": "console" - } - }, - { - "desc": "PlayStation 5", - "ua": "Mozilla/5.0 (Playstation; Playstation 5/1.05) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15", - "expect": { - "vendor": "Sony", - "model": "Playstation 5", - "type": "console" - } - }, - { - "desc": "PlayStation Vita", - "ua": "Mozilla/5.0 (PlayStation Vita 3.52) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2", - "expect": { - "vendor": "Sony", - "model": "PlayStation Vita", - "type": "console" - } - }, - { - "desc": "Nintendo Switch", - "ua": "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", - "expect": { - "vendor": "Nintendo", - "model": "Switch", - "type": "console" - } - }, - { - "desc": "Nintendo WiiU", - "ua": "Mozilla/5.0 (Nintendo WiiU) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.4.2.9 NintendoBrowser/4.2.0.11146.EU", - "expect": { - "vendor": "Nintendo", - "model": "WiiU", - "type": "console" - } - }, - { - "desc": "Nintendo Wii", - "ua": "Opera/9.10 (Nintendo Wii; U; ; 1621; en)", - "expect": { - "vendor": "Nintendo", - "model": "Wii", - "type": "console" - } - }, - { - "desc": "Nintendo 3DS", - "ua": "Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7610.EU", - "expect": { - "vendor": "Nintendo", - "model": "3DS", - "type": "console" - } - }, - { - "desc": "Nintendo 3DS", - "ua": "Mozilla/5.0 (New Nintendo 3DS like iPhone) AppleWebKit/536.30 (KHTML, like Gecko) NX/3.0.0.5.15 Mobile NintendoBrowser/1.3.10126.EU", - "expect": { - "vendor": "Nintendo", - "model": "3DS", - "type": "console" - } - }, - { - "desc": "Galaxy Nexus", - "ua": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", - "expect": { - "vendor": "Samsung", - "model": "Galaxy Nexus", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy C9 Pro", - "ua": "Mozilla/5.0 (Linux; Android 6.0; SAMSUNG SM-C900F Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.2 Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-C900F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S5", - "ua": "Mozilla/5.0 (Linux; Android 5.0; SM-G900F Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.78 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G900F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy J7 Prime", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; SM-G610F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G610F", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S6", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-G920I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G920I", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy S6 Edge", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; SM-G925I Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.135 Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-G925I", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Note 5 Chrome", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SM-N920C Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.91 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-N920C", - "type": "mobile" - } - }, - { - "desc": "Samsung Galaxy Note 5 Samsung Browser", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SAMSUNG SM-N920C Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "Samsung", - "model": "SM-N920C", - "type": "mobile" - } - }, - { - "desc": "Google Chromecast with Google TV", - "ua": "Mozilla/5.0 (Linux; Android 12.0; Build/STTL.240206.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.0 Safari/537.36 CrKey/1.56.500000 DeviceType/AndroidTV", - "expect": { - "vendor": "Google", - "model": "Chromecast AndroidTV", - "type": "smarttv" - } - }, - { - "desc": "Google Chromecast Mini Smart Speaker", - "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/SmartSpeaker", - "expect": { - "vendor": "Google", - "model": "Chromecast SmartSpeaker", - "type": "smarttv" - } - }, - { - "desc": "Google Chromecast Third Generation", - "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast", - "expect": { - "vendor": "Google", - "model": "Chromecast Third Generation", - "type": "smarttv" - } - }, - { - "desc": "Google Chromecast Nest Hub", - "ua": "Mozilla/5.0 (Fuchsia) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 CrKey/1.56.500000", - "expect": { - "vendor": "Google", - "model": "Chromecast Nest Hub", - "type": "smarttv" - } - }, - { - "desc": "Google Chromecast", - "ua": "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.84 Safari/537.36 CrKey/1.22.79313", - "expect": { - "vendor": "Google", - "model": "Chromecast", - "type": "smarttv" - } - }, - { - "desc": "Google Pixel C", - "ua": "Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel C", - "type": "tablet" - } - }, - { - "desc": "Google Pixel C", - "ua": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel C", - "type": "tablet" - } - }, - { - "desc": "Google Pixel", - "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel Build/NDE63V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel", - "type": "mobile" - } - }, - { - "desc": "Google Pixel XL", - "ua": "Mozilla/5.0 (Linux; Android 7.1; Pixel XL Build/NDE63X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel XL", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 2", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 2", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 2 XL", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; Pixel 2 XL Build/OPM1.171019.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 2 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 2 XL", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 2 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 2 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3 XL", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL Build/PD1A.180720.030) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3 XL", - "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3a", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3a", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 3a XL", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 3a XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 3a XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 4", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 4", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 4a", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 4a", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 4 XL", - "ua": "Mozilla/5.0 (Linux; Android 10; Pixel 4 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 4 XL", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 5", - "ua": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.120 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 5", - "type": "mobile" - } - }, - { - "desc": "Google Pixel 7", - "ua": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Google", - "model": "Pixel 7", - "type": "mobile" - } - }, - { - "desc": "Generic Android Device", - "ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)", - "expect": { - "vendor": "Generic", - "model": "Android 6.0.1" - } - }, - { - "desc": "Android Phone Unidentified Vendor (docomo F-04K)", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-04K Build/V15R060P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36", - "expect": { - "model": "F-04K", - "type": "mobile" - } - }, - { - "desc": "docomo SH-02M", - "ua": "Mozilla/5.0 (Linux; Android 9; SH-02M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36", - "expect": { - "vendor": "Sharp", - "model": "SH-02M", - "type": "mobile" - } - }, - { - "desc": "Android Tablet Unidentified Vendor (docomo F-02K)", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; F-02K Build/V44R059G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36", - "expect": { - "model": "F-02K", - "type": "tablet" - } - }, - { - "desc": "Android Tablet Unidentified Vendor (docomo d-02K)", - "ua": "Mozilla/5.0 (Linux; Android 9; d-02K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Safari/537.36", - "expect": { - "model": "d-02K", - "type": "tablet" - } - }, - { - "desc": "LG VK Series Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.0.2; VK700 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.84 Safari/537.36", - "expect": { - "vendor": "LG", - "model": "VK700", - "type": "tablet" - } - }, - { - "desc": "LG LK Series Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.0.1; LGLK430 Build/LRX21Y) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/38.0.2125.102 Safari/537.36", - "expect": { - "vendor": "LG", - "model": "LK430", - "type": "tablet" - } - }, - { - "desc": "Amazon Alexa Echo Show", - "ua": "AlexaWebMediaPlayer/1.0.200641.0 (Linux;Android 5.1.1)", - "expect": { - "vendor": "Amazon", - "model": "Alexa", - "type": "tablet" - } - }, - { - "desc": "Amazon Kindle Fire Tablet", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI Build/KTU84M) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFSAWI", - "type": "tablet" - } - }, - { - "desc": "Amazon Kindle Fire Tablet", - "ua": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; KFSAWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/3.66 like Chrome/39.0.2171.93 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFSAWI", - "type": "tablet" - } - }, - { - "desc": "Amazon Kindle Fire Tablet", - "ua": "Mozilla/5.0 (Linux; Android 9; KFMAWI Build/PS7312; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFMAWI", - "type": "tablet" - } - }, - { - "desc": "Amazon Fire TV", - "ua": "Mozilla/5.0 (Linux; Android 4.2.2; AFTB Build/JDQ39) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.173 Mobile Safari/537.22", - "expect": { - "vendor": "Amazon", - "model": "B", - "type": "smarttv" - } - }, - { - "desc": "Amazon Fire TV", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; AFTT) AppleWebKit/537.36 (KHTML, like Gecko) Silk/86.3.20 like Chrome/86.0.4240.198 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "T", - "type": "smarttv" - } - }, - { - "desc": "Amazon Fire TV", - "ua": "Mozilla/5.0 (Linux; Android 9; AFTKA Build/PS7633.3445N; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.160 Mobile Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KA", - "type": "smarttv" - } - }, - { - "desc": "Android TV", - "ua": "Mozilla/5.0 (Linux; Android 10; 2020/2021 UHD Android TV Build/QTG3.201102.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "Amazon Fire 7", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/80.5.3 like Chrome/80.0.3987.162 Safari/537.36", - "expect": { - "vendor": "Amazon", - "model": "KFAUWI", - "type": "tablet" - } - }, - { - "desc": "FaceBook Mobile App", - "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", - "expect": { - "vendor": "Apple", - "model": "iPhone12,1", - "type": "mobile" - } - }, - { - "desc": "Issue #519", - "ua": "ios/iPhone/14.2/SOME_CUSTOM_APP_VERSION", - "expect": { - "vendor": "Apple", - "model": "iPhone", - "type": "mobile" - } - }, - { - "desc": "Issue #454", - "ua": "Mosamzilla/5.0 (Windows; U; Win98; en-US; rv:1.7.5) Gecko/20050603 Netscape/8.0.2", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "undefined" - } - }, - { - "desc": "Alcatel", - "ua": "Mozilla/5.0 (Linux; Android 4.4.2; ALCATEL A564C Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36", - "expect": { - "vendor": "ALCATEL", - "model": "A564C", - "type": "mobile" - } - }, - { - "desc": "Alcatel Go Flip", - "ua": "Mozilla/5.0 (Mobile; ALCATEL4044T; rv:37.0) Gecko/37.0 Firefox/37.0 KaiOS/1.0", - "expect": { - "vendor": "ALCATEL", - "model": "4044T", - "type": "mobile" - } - }, - { - "desc": "Jolla", - "ua": "Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0", - "expect": { - "vendor": "Jolla", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Xbox One", - "ua": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; Xbox; Xbox One)", - "expect": { - "vendor": "Microsoft", - "model": "Xbox One", - "type": "console" - } - }, - { - "desc": "Xbox", - "ua": "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)", - "expect": { - "vendor": "Microsoft", - "model": "Xbox", - "type": "console" - } - }, - { - "desc": "Nvidia Shield Tablet", - "ua": "Mozilla/5.0 (Linux; Android 5.1.1; SHIELD Tablet Build/LVY48E; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.19 Safari/537.36", - "expect": { - "vendor": "Nvidia", - "model": "SHIELD Tablet", - "type": "tablet" - } - }, - { - "desc": "Ouya", - "ua": "Mozilla/5.0 (Linux; Android 4.1.2; OUYA Console Build/JZO54L-OUYA) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.84 Safari/537.36", - "expect": { - "vendor": "OUYA", - "model": "undefined", - "type": "console" - } - }, - { - "desc": "Vivo S1 Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; vivo 1920) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Vivo", - "model": "1920", - "type": "mobile" - } - }, - { - "desc": "Vivo Y52s", - "ua": "Mozilla/5.0 (Linux; Android 10; V2057A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.10 SP-engine/2.28.0 baiduboxapp/12.10.0.10 (Baidu; P1 10) NABar/1.0", - "expect": { - "vendor": "Vivo", - "model": "V2057A", - "type": "mobile" - } - }, - { - "desc": "Vivo X60", - "ua": "Mozilla/5.0 (Linux; Android 11; V2046A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/8.8.71.0", - "expect": { - "vendor": "Vivo", - "model": "V2046A", - "type": "mobile" - } - }, - { - "desc": "Vivo Y79A", - "ua": "Mozilla/5.0 (Linux; Android 7.1.2; vivo Y79A Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", - "expect": { - "vendor": "Vivo", - "model": "Y79A", - "type": "mobile" - } - }, - { - "desc": "Vivo Y93", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; vivo 1814) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Vivo", - "model": "1814", - "type": "mobile" - } - }, - { - "desc": "Vivo Y97", - "ua": "Mozilla/5.0 (Linux; Android 8.1.0; V1813T Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.0.14.0", - "expect": { - "vendor": "Vivo", - "model": "V1813T", - "type": "mobile" - } - }, - { - "desc": "Vivo iQOO Pro", - "ua": "Mozilla/5.0 (Linux; Android 11; V1916A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.1.10.6", - "expect": { - "vendor": "Vivo", - "model": "V1916A", - "type": "mobile" - } - }, - { - "desc": "Vivo 1906 (Y11)", - "ua": "Mozilla/5.0 (Linux; Android 11; vivo 1906) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", - "expect": { - "vendor": "Vivo", - "model": "1906", - "type": "mobile" - } - }, - { - "desc": "Unknown Mobile using Firefox", - "ua": "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Firefox", - "ua": "Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown Mobile using Focus for Android", - "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Mobile Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Focus for Android", - "ua": "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Safari/537.36", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown Device using Focus for Android with GeckoView", - "ua": "Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Mobile using Firefox OS", - "ua": "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - }, - { - "desc": "Unknown Tablet using Firefox OS", - "ua": "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "tablet" - } - }, - { - "desc": "Unknown TV using Firefox OS", - "ua": "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "smarttv" - } - }, - { - "desc": "PDA with Windows CE", - "ua": "Mozilla/4.0 (PDA; Windows CE/1.0.1) NetFront/3.0", - "expect": { - "vendor": "undefined", - "model": "undefined", - "type": "mobile" - } - } -] \ No newline at end of file diff --git a/test/specs/os-all.json b/test/specs/os-all.json deleted file mode 100644 index b93dc33..0000000 --- a/test/specs/os-all.json +++ /dev/null @@ -1,1322 +0,0 @@ -[ - { - "desc" : "Windows 95", - "ua" : "Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)", - "expect" : - { - "name" : "Windows", - "version" : "95" - } - }, - { - "desc" : "Windows 98", - "ua" : "Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)", - "expect" : - { - "name" : "Windows", - "version" : "98" - } - }, - { - "desc" : "Windows ME", - "ua" : "Mozilla/5.0 (Windows; U; Win 9x 4.90) Gecko/20020502 CS 2000 7.0/7.0", - "expect" : - { - "name" : "Windows", - "version" : "ME" - } - }, - { - "desc" : "Windows 2000", - "ua" : "Mozilla/3.0 (compatible; MSIE 3.0; Windows NT 5.0)", - "expect" : - { - "name" : "Windows", - "version" : "2000" - } - }, - { - "desc" : "Windows XP", - "ua" : "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 5.2)", - "expect" : - { - "name" : "Windows", - "version" : "XP" - } - }, - { - "desc" : "Windows Vista", - "ua" : "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; fr-FR)", - "expect" : - { - "name" : "Windows", - "version" : "Vista" - } - }, - { - "desc" : "Windows 7", - "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)", - "expect" : - { - "name" : "Windows", - "version" : "7" - } - }, - { - "desc" : "Windows 8", - "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Win64; x64; Trident/6.0; .NET4.0E; .NET4.0C)", - "expect" : - { - "name" : "Windows", - "version" : "8" - } - }, - { - "desc" : "Windows 10", - "ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0", - "expect" : - { - "name" : "Windows", - "version" : "10" - } - }, - { - "desc" : "WeChat Desktop for Windows Built-in Browser", - "ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400", - "expect" : - { - "name" : "Windows", - "version" : "7" - } - }, - { - "desc" : "WeChat Desktop for Windows Built-in Browser major version in 4", - "ua" : "mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/81.0.4044.138 safari/537.36 nettype/wifi micromessenger/7.0.20.1781(0x6700143b) windowswechat", - "expect" : - { - "name" : "Windows", - "version" : "7" - } - }, - { - "desc" : "Windows RT", - "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0)", - "expect" : - { - "name" : "Windows", - "version" : "RT" - } - }, - { - "desc" : "Windows CE", - "ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)", - "expect" : - { - "name" : "Windows", - "version" : "CE" - } - }, - { - "desc" : "Windows Mobile", - "ua" : "Mozilla/5.0 (ZTE-E_N72/N72V1.0.0B02;U;Windows Mobile/6.1;Profile/MIDP-2.0 Configuration/CLDC-1.1;320*240;CTC/2.0) IE/6.0 (compatible; MSIE 4.01; Windows CE; PPC)/UC Browser7.7.1.88", - "expect" : - { - "name" : "Windows Mobile", - "version" : "6.1" - } - }, - { - "desc" : "Windows Mobile", - "ua" : "Opera/9.80 (Windows Mobile; WCE; Opera Mobi/WMD-50433; U; en) Presto/2.4.13 Version/10.00", - "expect" : - { - "name" : "Windows Mobile", - "version" : "undefined" - } - }, - { - "desc" : "Windows Phone", - "ua" : "Opera/9.80 (Windows Phone; Opera Mini/7.6.8/35.7518; U; ru) Presto/2.8.119 Version/11.10", - "expect" : - { - "name" : "Windows Phone", - "version" : "undefined" - } - }, - { - "desc" : "Windows Phone OS", - "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; DELL; Venue Pro)", - "expect" : - { - "name" : "Windows Phone OS", - "version" : "7.0" - } - }, - { - "desc" : "Windows Phone 8", - "ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; HTC; Windows Phone 8X by HTC)", - "expect" : - { - "name" : "Windows Phone", - "version" : "8.0" - } - }, - { - "desc" : "Windows NT on x86 or aarch64 CPU using Firefox", - "ua" : "Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0", - "expect" : - { - "name" : "Windows", - "version" : "NT x" - } - }, - { - "desc" : "Windows NT on x64 CPU using Firefox", - "ua" : "Mozilla/5.0 (Windows NT x.y; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0", - "expect" : - { - "name" : "Windows", - "version" : "NT x" - } - }, - { - "desc" : "BlackBerry", - "ua" : "BlackBerry9300/5.0.0.912 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/378", - "expect" : - { - "name" : "BlackBerry", - "version" : "5.0.0.912" - } - }, - { - "desc" : "BlackBerry 10", - "ua" : "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.3+ (KHTML, like Gecko) Version/10.0.9.386 Mobile Safari/537.3+", - "expect" : - { - "name" : "BlackBerry", - "version" : "10" - } - }, - { - "desc" : "Tizen", - "ua" : "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1", - "expect" : - { - "name" : "Tizen", - "version" : "2.3" - } - }, - { - "desc" : "Tizen", - "ua" : "Mozilla/5.0 (Linux; Tizen 2.3; SAMSUNG SM-Z130H) AppleWebKit/537.3 (KHTML, like Gecko) Version/2.3 Mobile Safari/537.3", - "expect" : - { - "name" : "Tizen", - "version" : "2.3" - } - }, - { - "desc" : "Tizen 6.0", - "ua" : "HbbTV/1.5.1 (+DRM;Samsung;SmartTV2021:UAU7000;T-KSU2EDEUC-1506.0;KantSU2e;urn:samsungtv:familyname:21_KANTSU2E_UHD_BASIC:2021;) Tizen/6.0 (+TVPLUS+SmartHubLink) Chrome/76 LaTivu_1.0.1_2021 RVID/17", - "expect" : - { - "name" : "Tizen", - "version" : "6.0" - } - }, - { - "desc" : "Android", - "ua" : "Mozilla/5.0 (Linux; U; Android 2.2.2; en-us; VM670 Build/FRG83G) AppleWebKit/533.1 (KHTML, like Gecko)", - "expect" : - { - "name" : "Android", - "version" : "2.2.2" - } - }, - { - "desc" : "HarmonyOS", - "ua" : "Mozilla/5.0 (Linux; Android 10; HarmonyOS; YAL-AL10; HMSCore 6.3.0.327; GMSCore 21.48.15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.105 HuaweiBrowser/12.0.3.310 Mobile Safari/537.36", - "expect" : - { - "name" : "HarmonyOS", - "version" : "10" - } - }, - { - "desc" : "Sailfish", - "ua" : "Mozilla/5.0 (Linux; U; Sailfish 3.0; Mobile; rv:45.0) Gecko/45.0 Firefox/45.0 SailfishBrowser/1.0", - "expect" : - { - "name" : "Sailfish", - "version" : "3.0" - } - }, - { - "desc" : "WebOS", - "ua" : "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.5; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0", - "expect" : - { - "name" : "webOS", - "version" : "3.0.5" - } - }, - { - "desc" : "WebOS", - "ua" : "Mozilla/5.0 (webOS/1.4.5; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pre/1.0", - "expect" : - { - "name" : "webOS", - "version" : "1.4.5" - } - }, - { - "desc" : "WebOS TV 5.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 WebAppManager", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "WebOS TV 4.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.34 Safari/537.36 WebAppManager", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "WebOS TV 3.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.2.1 Chrome/38.0.2125.122 Safari/537.36 WebAppManager", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "WebOS TV 2.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/538.2 (KHTML, like Gecko) Large Screen WebAppManager Safari/538.2", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "WebOS TV 1.x", - "ua" : "Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.41 (KHTML, like Gecko) Large Screen WebAppManager Safari/537.41", - "expect" : - { - "name" : "webOS", - "version" : "TV" - } - }, - { - "desc" : "QNX", - "ua" : "Mozilla/5.0 (Photon; U; QNX x86pc; en-US; rv:1.8.1.20) Gecko/20090127 BonEcho/2.0.0.20", - "expect" : - { - "name" : "QNX", - "version" : "x86pc" - } - }, - { - "desc" : "Bada", - "ua" : "Mozilla/5.0 (SAMSUNG; SAMSUNG-GT-S5253/S5253DDKC1; U; Bada/1.0; en-us) AppleWebKit/533.1 (KHTML, like Gecko) Dolfin/2.0 Mobile WQVGA SMM-MMS/1.2.0 OPN-B", - "expect" : - { - "name" : "Bada", - "version" : "1.0" - } - }, - { - "desc" : "RIM Tablet OS", - "ua" : "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+", - "expect" : - { - "name" : "RIM Tablet OS", - "version" : "2.1.0" - } - }, - { - "desc" : "Nokia N900 Linux mobile, on the Fennec browser", - "ua" : "Mozilla/5.0 (Maemo; Linux armv7l; rv:10.0) Gecko/20100101 Firefox/10.0 Fennec/10.0", - "expect" : - { - "name" : "Maemo", - "version" : "undefined" - } - }, - { - "desc" : "MeeGo", - "ua" : "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", - "expect" : - { - "name" : "MeeGo", - "version" : "undefined" - } - }, - { - "desc" : "Symbian", - "ua" : "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba", - "expect" : - { - "name" : "Symbian", - "version" : "9.4" - } - }, - { - "desc" : "Symbian", - "ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaC7-00/024.001; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba", - "expect" : - { - "name" : "Symbian", - "version" : "5.2" - } - }, - { - "desc" : "Series40", - "ua" : "Mozilla/5.0 (Series40; Nokia2055/03.20; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/2.2.0.0.34", - "expect" : - { - "name" : "Series40", - "version" : "undefined" - } - }, - { - "desc" : "Firefox OS", - "ua" : "Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0", - "expect" : - { - "name" : "Firefox OS", - "version" : "14.0" - } - }, - { - "desc" : "Firefox OS on Tablet", - "ua" : "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0", - "expect" : - { - "name" : "Firefox OS", - "version" : "26.0" - } - }, - { - "desc" : "Firefox OS on TV", - "ua" : "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0", - "expect" : - { - "name" : "Firefox OS", - "version" : "44.0" - } - }, - { - "desc" : "Google Chromecast with Google TV", - "ua" : "Mozilla/5.0 (Linux; Android 12.0; Build/STTL.240206.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.0 Safari/537.36 CrKey/1.56.500000 DeviceType/AndroidTV", - "expect" : - { - "name" : "Chromecast Android", - "version" : "12.0" - } - }, - { - "desc" : "Google Chromecast Nest Hub", - "ua" : "Mozilla/5.0 (Fuchsia) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 CrKey/1.56.500000", - "expect" : - { - "name" : "Chromecast Fuchsia", - "version" : "1.56.500000" - } - }, - { - "desc" : "Google Chromecast Mini Smart Speaker", - "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/SmartSpeaker", - "expect" : - { - "name" : "Chromecast SmartSpeaker", - "version" : "1.56.500000" - } - }, - { - "desc" : "Google Chromecast Legacy Linux-Based", - "ua" : "Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.81 Safari/537.36 CrKey/1.42.183786", - "expect" : - { - "name" : "Chromecast Linux", - "version" : "1.42.183786" - } - }, - { - "desc" : "Nintendo Switch", - "ua" : "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/606.4 (KHTML, like Gecko) NF/6.0.1.15.4 NintendoBrowser/5.1.0.20393", - "expect" : - { - "name" : "Nintendo", - "version" : "Switch" - } - }, - { - "desc" : "PlayStation 4", - "ua" : "Mozilla/5.0 (PlayStation 4 3.00) AppleWebKit/537.73 (KHTML, like Gecko)", - "expect" : - { - "name" : "PlayStation", - "version" : "4" - } - }, - { - "desc" : "PlayStation 5", - "ua" : "Mozilla/5.0 (PlayStation 5/SmartTV) AppleWebKit/605.1.15 (KHTML, like Gecko)", - "expect" : - { - "name" : "PlayStation", - "version" : "5" - } - }, - { - "desc": "Pico 4", - "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.8.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.38 Chrome/105.0.5195.68 VR Safari/537.36", - "expect": { - "name" : "PICO", - "version" : "5.8.2" - } - }, - { - "desc": "Pico 4", - "ua": "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0", - "expect": { - "name" : "PICO", - "version" : "5.4.0" - } - }, - { - "desc": "Pico Neo3 Link", - "ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36", - "expect": { - "name" : "Pico", - "version" : "5.8.4.0" - } - }, - { - "desc" : "Xbox 360", - "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox 360) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "expect" : - { - "name" : "Xbox", - "version" : "360" - } - }, - { - "desc" : "Xbox One", - "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One; WebView/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19041", - "expect" : - { - "name" : "Xbox", - "version" : "One" - } - }, - { - "desc" : "Xbox X", - "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02", - "expect" : - { - "name" : "Xbox", - "version" : "X" - } - }, - { - "desc" : "Xbox Series X", - "ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox Series X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 Edge/20.02 ", - "expect" : - { - "name" : "Xbox", - "version" : "Series X" - } - }, - { - "desc" : "Xbox Series S", - "ua" : "Mozilla/5.0 (Compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Xbox; Xbox Series S)", - "expect" : - { - "name" : "Xbox", - "version" : "Series S" - } - }, - { - "desc" : "Mint", - "ua" : "Opera/9.80 (X11; Linux x86_64; Edition Linux Mint) Presto/2.12.388 Version/12.16", - "expect" : - { - "name" : "Mint", - "version" : "undefined" - } - }, - { - "desc" : "Mint", - "ua" : "Opera/9.64 (X11; Linux i686; U; Linux Mint; nb) Presto/2.1.1", - "expect" : - { - "name" : "Mint", - "version" : "undefined" - } - }, - { - "desc" : "Mint", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.5) Gecko/2008121622 Linux Mint/6 (Felicia) Firefox/3.0.4", - "expect" : - { - "name" : "Mint", - "version" : "6" - } - }, - { - "desc" : "Ubuntu", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.22+ (KHTML, like Gecko) Chromium/17.0.963.56 Chrome/17.0.963.56 Safari/535.22+ Ubuntu/12.04 (3.4.1-0ubuntu1) Epiphany/3.4.1", - "expect" : - { - "name" : "Ubuntu", - "version" : "12.04" - } - }, - { - "desc" : "Ubuntu", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/31.0.1650.63 Chrome/31.0.1650.63 Safari/537.36", - "expect" : - { - "name" : "Ubuntu", - "version" : "undefined" - } - }, - { - "desc" : "Kubuntu", - "ua" : "Mozilla/5.0 (compatible; Konqueror/4.4; Linux 2.6.32-22-generic; X11; en_US) KHTML/4.4.3 (like Gecko) Kubuntu", - "expect" : - { - "name" : "Kubuntu", - "version" : "undefined" - } - }, - { - "desc" : "Debian", - "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko) (Debian)", - "expect" : - { - "name" : "Debian", - "version" : "undefined" - } - }, - { - "desc" : "Debian", - "ua" : "Mozilla/5.0 (X11; Linux x86_64; Debian GNU/Linux 8.1 (jessie)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.0 Maxthon/1.0.5.3 Safari/537.36", - "expect" : - { - "name" : "Debian", - "version" : "8.1" - } - }, - { - "desc" : "Debian", - "ua" : "ELinks/0.12~pre5-4 (textmode; Debian; Linux 3.2.0-4-amd64 x86_64 192x47-2)", - "expect" : - { - "name" : "Debian", - "version" : "undefined" - } - }, - { - "desc" : "Debian", - "ua" : "w3m/0.5.3+debian-19", - "expect" : - { - "name" : "debian", - "version" : "19" - } - }, - { - "desc" : "Debian", - "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.3) Gecko/2008092814 (Debian-3.0.1-1)", - "expect" : - { - "name" : "Debian", - "version" : "3.0.1-1" - } - }, - { - "desc" : "Debian", - "ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux 2.6.24.4; X11) KHTML/3.5.9 (like Gecko) (Debian package 4:3.5.9.dfsg.1-2+b1)", - "expect" : - { - "name" : "Debian", - "version" : "undefined" - } - }, - { - "desc" : "OpenSUSE", - "ua" : "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110420 SUSE/3.6.17-0.2.1 Firefox/3.6.17", - "expect" : - { - "name" : "SUSE", - "version" : "3.6.17-0.2.1" - } - }, - { - "desc" : "Gentoo", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.16) Gecko/20080716 (Gentoo) Galeon/2.0.6", - "expect" : - { - "name" : "Gentoo", - "version" : "undefined" - } - }, - { - "desc" : "Gentoo", - "ua" : "Xombrero (X11; U; Gentoo Linux amd64; en-US) Webkit/2.8.5", - "expect" : - { - "name" : "Gentoo", - "version" : "amd64" - } - }, - { - "desc" : "Gentoo", - "ua" : "Xombrero/1.6.4 (Linux amd64; en; Gentoo)", - "expect" : - { - "name" : "Gentoo", - "version" : "undefined" - } - }, - { - "desc" : "Gentoo", - "ua" : "Links (2.8; Linux 3.17.2-gentoo-x86 i686; GNU C 4.8.2; x)", - "expect" : - { - "name" : "gentoo", - "version" : "x86" - } - }, - { - "desc" : "Arch", - "ua" : "Uzbl (Webkit 1.1.10) (Arch Linux)", - "expect" : - { - "name" : "Arch", - "version" : "undefined" - } - }, - { - "desc" : "Slackware", - "ua" : "Mozilla/5.0 Slackware/13.37 (X11; U; Linux x86_64; en-US) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41", - "expect" : - { - "name" : "Slackware", - "version" : "13.37" - } - }, - { - "desc" : "Fedora", - "ua" : "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0", - "expect" : - { - "name" : "Fedora", - "version" : "undefined" - } - }, - { - "desc" : "Fedora", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:2.0) Gecko/20110404 Fedora/16-dev Firefox/4.0", - "expect" : - { - "name" : "Fedora", - "version" : "16-dev" - } - }, - { - "desc" : "Fedora", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; sk; rv:1.9.0.4) Gecko/2008111217 Fedora/3.0.4-1.fc10 Firefox/3.0.4", - "expect" : - { - "name" : "Fedora", - "version" : "3.0.4-1.fc10" - } - }, - { - "desc" : "Mandriva", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.22) Gecko/20110907 Mandriva Linux/1.9.2.22-0.1mdv2010.2 (2010.2) Firefox/3.6.22", - "expect" : - { - "name" : "Mandriva", - "version" : "1.9.2.22-0.1mdv2010.2" - } - }, - { - "desc" : "Chrome OS", - "ua" : "Mozilla/5.0 (X11; CrOS x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.0.0 Safari/537.36", - "expect" : - { - "name" : "Chrome OS", - "version" : "undefined" - } - }, - { - "desc" : "Chromium OS", - "ua" : "Mozilla/5.0 (X11; CrOS x86_64 10575.58.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36", - "expect" : - { - "name" : "Chrome OS", - "version" : "10575.58.0" - } - }, - { - "desc" : "Fuchsia", - "ua" : "Mozilla/5.0 (X11; Fuchsia x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3557.0 Safari/537.36", - "expect" : - { - "name" : "Fuchsia", - "version" : "undefined" - } - }, - { - "desc" : "Solaris", - "ua" : "Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7) Gecko/20070606", - "expect" : - { - "name" : "Solaris", - "version" : "sun4u" - } - }, - { - "desc" : "FreeBSD", - "ua" : "Mozilla/5.0 (X11; U; FreeBSD x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16", - "expect" : - { - "name" : "FreeBSD", - "version" : "undefined" - } - }, - { - "desc" : "OpenBSD", - "ua" : "Mozilla/5.0 (X11; U; OpenBSD i386; en-US; rv:1.9.1) Gecko/20090702 Firefox/3.5", - "expect" : - { - "name" : "OpenBSD", - "version" : "undefined" - } - }, - { - "desc" : "NetBSD", - "ua" : "ELinks (0.4.3; NetBSD 3.0.2PATCH sparc64; 141x19)", - "expect" : - { - "name" : "NetBSD", - "version" : "3.0.2PATCH" - } - }, - { - "desc" : "DragonFly", - "ua" : "Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1) Gecko/20090720 Firefox/3.5.1", - "expect" : - { - "name" : "DragonFly", - "version" : "undefined" - } - }, - { - "desc" : "iOS in App", - "ua" : "AppName/version CFNetwork/version Darwin/version", - "expect" : - { - "name" : "iOS", - "version" : "undefined" - } - }, - { - "desc" : "iOS with Chrome", - "ua" : "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3", - "expect" : - { - "name" : "iOS", - "version" : "5.1.1" - } - }, - { - "desc" : "iOS with Opera Mini", - "ua" : "Opera/9.80 (iPhone; Opera Mini/7.1.32694/27.1407; U; en) Presto/2.8.119 Version/11.10", - "expect" : - { - "name" : "iOS", - "version" : "undefined" - } - }, - { - "desc": "iOS with FaceBook Mobile App", - "ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]", - "expect": - { - "name" : "iOS", - "version" : "13.6.1" - } - }, - { - "desc": "iOS with Slack App", - "ua": "com.tinyspeck.chatlyio/23.04.10 (iPhone; iOS 16.4.1; Scale/3.00)", - "expect": - { - "name" : "iOS", - "version" : "16.4.1" - } - }, - { - "desc" : "watchOS", - "ua" : "server-bag [Watch OS,8.4,19S546,Watch3,4]", - "expect" : - { - "name" : "watchOS", - "version" : "8.4" - } - }, - { - "desc" : "watchOS", - "ua" : "atc/1.0 watchOS/7.4.1 model/Watch3,3 hwp/t8004 build/18T201 (6; dt:155)", - "expect" : - { - "name" : "watchOS", - "version" : "7.4.1" - } - }, - { - "desc" : "watchOS", - "ua" : "Watch4,3/5.3.8 (16U680)", - "expect" : - { - "name" : "watchOS", - "version" : "5.3.8" - } - }, - { - "desc" : "Mac OS on PowerPC", - "ua" : "Mozilla/4.0 (compatible; MSIE 5.0b1; Mac_PowerPC)", - "expect" : - { - "name" : "macOS", - "version" : "undefined" - } - }, - { - "desc" : "Mac OS X on x86, x86_64, or aarch64 using Firefox", - "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", - "expect" : - { - "name" : "macOS", - "version" : "x.y" - } - }, - { - "desc" : "Mac OS X on PowerPC using Firefox", - "ua" : "Mozilla/5.0 (Macintosh; PPC Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0", - "expect" : - { - "name" : "macOS", - "version" : "x.y" - } - }, - { - "desc" : "Mac OS", - "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36", - "expect" : - { - "name" : "macOS", - "version" : "10.6.8" - } - }, - { - "desc" : "Haiku", - "ua" : "Mozilla/5.0 (Macintosh; Intel Haiku R1 x86) AppleWebKit/602.1.1 (KHTML, like Gecko) WebPositive/1.2 Version/8.0 Safari/602.1.1", - "expect" : - { - "name" : "Haiku", - "version" : "R1" - } - }, - { - "desc" : "KaiOS", - "ua" : "Mozilla/5.0 (Mobile; Nokia_8110_4G; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5", - "expect" : - { - "name" : "KAIOS", - "version" : "2.5" - } - }, - { - "desc" : "iTunes Windows Vista", - "ua" : "iTunes/10.7 (Windows; Microsoft Windows Vista Home Premium Edition Service Pack 1 (Build 6001)) AppleWebKit/536.26.9", - "expect" : - { - "name" : "Windows", - "version" : "Vista" - } - }, - { - "desc" : "iOS BE App", - "ua" : "APP-BE Test/1.0 (iPad; Apple; CPU iPhone OS 7_0_2 like Mac OS X)", - "expect" : - { - "name" : "iOS", - "version" : "7.0.2" - } - }, - { - "desc" : "KTB-Nexus 5", - "ua" : "APP-My App/1.0 (Linux; Android 4.2.1; Nexus 5 Build/JOP40D)", - "expect" : - { - "name" : "Android", - "version" : "4.2.1" - } - }, - { - "desc" : "Solaris", - "ua" : "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)", - "expect" : - { - "name" : "Solaris", - "version" : "4.1.4" - } - }, - { - "desc" : "Raspbian", - "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/72.0.3626.121 HeadlessChrome/72.0.3626.121 Safari/537.36", - "expect" : - { - "name" : "Raspbian", - "version" : "undefined" - } - }, - { - "desc" : "Raspbian", - "ua" : "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15 Raspbian/9.0 (1:3.8.2.0-0rpi28) Epiphany/3.8.2", - "expect" : - { - "name" : "Raspbian", - "version" : "9.0" - } - }, - { - "desc" : "AIX", - "ua" : "Mozilla/5.0 (X11; U; AIX 000138384C00; en-US; rv:1.0.1) Gecko/20030213 Netscape/7.0", - "expect" : - { - "name" : "AIX", - "version" : "undefined" - } - }, - { - "desc" : "Plan9", - "ua" : "NCSA_Mosaic/5.0 (X11;Plan 9 4.0)", - "expect" : - { - "name" : "Plan 9", - "version" : "4.0" - } - }, - { - "desc" : "Minix", - "ua" : "Mozilla/5.0 (X11; Original ; Minix 3.3 ; rv:3.0)", - "expect" : - { - "name" : "Minix", - "version" : "3.3" - } - }, - { - "desc" : "BeOS", - "ua" : "Mozilla/5.0 (BeOS; U; BeOS BePC; en-US; rv:1.8.1.8pre) Gecko/20070926 SeaMonkey/1.1.5pre", - "expect" : - { - "name" : "BeOS", - "version" : "undefined" - } - }, - { - "desc" : "OS/2", - "ua" : "Links (2.1pre14; OS/2 1 i386; 80x33)", - "expect" : - { - "name" : "OS/2", - "version" : "undefined" - } - }, - { - "desc" : "AmigaOS", - "ua" : "Mozilla/4.0 (compatible; AWEB 3.4 SE; AmigaOS)", - "expect" : - { - "name" : "AmigaOS", - "version" : "undefined" - } - }, - { - "desc" : "MorphOS", - "ua" : "AmigaVoyager/3.4.4 (MorphOS/PPC native)", - "expect" : - { - "name" : "MorphOS", - "version" : "undefined" - } - }, - { - "desc" : "UNIX", - "ua" : "Surf/0.4.1 (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)", - "expect" : - { - "name" : "Unix", - "version" : "undefined" - } - }, - { - "desc" : "Joli", - "ua" : "Mozilla/5.0 (X11; Jolicloud Linux i686) AppleWebKit/537.6 (KHTML, like Gecko) Joli OS/1.2 Chromium/23.0.1240.0 Chrome/23.0.1240.0 Safari/537.6", - "expect" : - { - "name" : "Joli", - "version" : "1.2" - } - }, - { - "desc" : "CentOS", - "ua" : "Konqueror/15.13 (CentOS Linux 7.4; cs-CZ;)", - "expect" : - { - "name" : "CentOS", - "version" : "7.4" - } - }, - { - "desc" : "PCLinuxOS", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101209 PCLinuxOS/1.9.2.13-1pclos2010 (2010) Firefox/3.6.13", - "expect" : - { - "name" : "PCLinuxOS", - "version" : "1.9.2.13-1pclos2010" - } - }, - { - "desc" : "RedHat", - "ua" : "Mozilla/5.0 (compatible; Konqueror/4.3; Linux) KHTML/4.3.4 (like Gecko) Red Hat Enterprise Linux/4.3.4-11.el6_1.4", - "expect" : - { - "name" : "Red Hat", - "version" : "4.3.4-11.el6_1.4" - } - }, - { - "desc" : "RedHat", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.13pre) Gecko/20070717 Red Hat/1.0.9-4.el4 SeaMonkey/1.0.9", - "expect" : - { - "name" : "Red Hat", - "version" : "1.0.9-4.el4" - } - }, - { - "desc" : "RedHat", - "ua" : "iTunes/4.7.1 (Linux; N; Red Hat; x86_64-linux; EN; utf8) SqueezeCenter, Squeezebox Server, Logitech Media Server/7.9.1/1522157629", - "expect" : - { - "name" : "Red Hat", - "version" : "undefined" - } - }, - { - "desc" : "RedHat", - "ua" : "curl/7.20.0 (x86_64-redhat-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5", - "expect" : - { - "name" : "redhat", - "version" : "undefined" - } - }, - { - "desc" : "RISC OS", - "ua" : "Mozilla/1.10 [en] (Compatible; RISC OS 3.70; Oregano 1.10)", - "expect" : - { - "name" : "RISC OS", - "version" : "3.70" - } - }, - { - "desc" : "Zenwalk", - "ua" : "Flock/2.16 (Zenwalk 7.3; es_PR;)", - "expect" : - { - "name" : "Zenwalk", - "version" : "7.3" - } - }, - { - "desc" : "Hurd", - "ua" : "Mozilla/5.0 (X11; Hurd 0.9 i386; en-US) libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/3.7.0 Safari/696.96", - "expect" : - { - "name" : "Hurd", - "version" : "0.9" - } - }, - { - "desc" : "Linux", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36", - "expect" : - { - "name" : "Linux", - "version" : "x86_64" - } - }, - { - "desc" : "Deepin", - "ua" : "Mozilla/5.0 (X11; Linux x86_64; Deepin 15.5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36 NFSBrowser/5.0.0.1886", - "expect" : - { - "name" : "Deepin", - "version" : "15.5" - } - }, - { - "desc" : "Palm OS", - "ua" : "Mozilla/4.76 [en] (PalmOS; U; WebPro3.0; Palm-Arz1)", - "expect" : - { - "name" : "Palm", - "version" : "undefined" - } - }, - { - "desc" : "Panasonic Viera", - "ua" : "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)", - "expect" : - { - "name" : "VIERA", - "version" : "undefined" - } - }, - { - "desc" : "Netrange Smart TV", - "ua" : "Mozilla/5.0 (Linux; U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36 OPR/46.0.2207.0 LOEWE-SL410/5.2.0.0 HbbTV/1.4.1 (; LOEWE; SL410; LOH/5.2.0.0;;) FVC/3.0 (LOEWE; SL410;) CE-HTML/1.0 Config (L:deu,CC:DEU) NETRANGEMMH", - "expect" : - { - "name" : "NETRANGE", - "version" : "undefined" - } - }, - { - "desc" : "NetTV 3.2.1", - "ua" : "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.2.1; en) Presto/2.6.33 Version/10.70", - "expect" : - { - "name" : "NETTV", - "version" : "3.2.1" - } - }, - { - "desc" : "HP-UX", - "ua" : "Mozilla/5.0 (X11; U; HP-UX 9000/785; es-ES; rv:1.0.1) Gecko/20020827 Netscape/7.0", - "expect" : - { - "name" : "HP-UX", - "version" : "undefined" - } - }, - { - "desc" : "Contiki", - "ua" : "Contiki/1.0 (Commodore 64; http://dunkels.com/adam/contiki/)", - "expect" : - { - "name" : "Contiki", - "version" : "1.0" - } - }, - { - "desc" : "Linpus", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9b5pre) Gecko/2008032619 Linpus/3.0-0.49", - "expect" : - { - "name" : "Linpus", - "version" : "3.0-0.49" - } - }, - { - "desc" : "Manjaro", - "ua" : "Mozilla/5.0 (X11; Manjaro 19.0.2; Arch; x64; rv:84.0) Gecko/20100101 Firefox/84.0", - "expect" : - { - "name" : "Manjaro", - "version" : "19.0.2" - } - }, - { - "desc" : "elementary OS", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/604.1 (KHTML, like Gecko) Version/11.0 Safari/604.1 elementary OS/0.4 (Loki) Epiphany/3.18.11", - "expect" : - { - "name" : "elementary OS", - "version" : "0.4" - } - }, - { - "desc" : "GhostBSD", - "ua" : "Mozilla/5.0 (X11; GhostBSD/10.3; x86_64; rv:50.0.1) Gecko/20100101 Firefox/50.0.1", - "expect" : - { - "name" : "GhostBSD", - "version" : "10.3" - } - }, - { - "desc" : "Android-x86", - "ua" : "Mozilla/5.0 (Linux; Android 7.1.2; Generic Android-x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 OPR/61.2.3076.56749", - "expect" : - { - "name" : "Android-x86", - "version" : "7.1.2" - } - }, - { - "desc" : "Sabayon", - "ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Sabayon Chrome/19.0.1084.46 Safari/536.5", - "expect" : - { - "name" : "Sabayon", - "version" : "undefined" - } - }, - { - "desc" : "Linspire", - "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.4) Gecko/20060803 Firefox/1.5.0.4 Linspire/1.5.0.4", - "expect" : - { - "name" : "Linspire", - "version" : "1.5.0.4" - } - }, - { - "desc" : "SerenityOS", - "ua" : "Mozilla/4.0 (SerenityOS; x86) LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb", - "expect" : - { - "name" : "SerenityOS", - "version" : "undefined" - } - }, - { - "desc" : "OpenHarmony", - "ua" : "Mozilla/5.0 (Phone; OpenHarmony 4.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 ArkWeb/4.1.6.1 Mobile", - "expect" : - { - "name" : "OpenHarmony", - "version" : "4.1" - } - } -] diff --git a/test/dts-test.ts b/test/static/dts-lint.ts similarity index 91% rename from test/dts-test.ts rename to test/static/dts-lint.ts index 39bb4a3..bcfc262 100644 --- a/test/dts-test.ts +++ b/test/static/dts-lint.ts @@ -1,6 +1,6 @@ import { expectType } from 'tsd'; -import { UAParser, IResult, IBrowser, ICPU, IEngine, IDevice, IOS } from "../src/main/ua-parser"; -import { isAppleSilicon, isChromeFamily } from "../src/helpers/ua-parser-helpers"; +import { UAParser, IResult, IBrowser, ICPU, IEngine, IDevice, IOS } from "../../src/main/ua-parser"; +import { isAppleSilicon, isChromeFamily } from "../../src/helpers/ua-parser-helpers"; const uastring = 'Mozilla/5.0 (X11; MyCustomOS; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0'; const extensions = { diff --git a/test/mocha-test-es6.mjs b/test/unit/es6.mjs similarity index 88% rename from test/mocha-test-es6.mjs rename to test/unit/es6.mjs index 69a334e..8e26908 100644 --- a/test/mocha-test-es6.mjs +++ b/test/unit/es6.mjs @@ -1,5 +1,5 @@ -import { UAParser } from '../src/main/ua-parser.mjs'; -import { CPU, Device, Engine } from '../src/enums/ua-parser-enums.mjs'; +import { UAParser } from '../../src/main/ua-parser.mjs'; +import { CPU, Device, Engine } from '../../src/enums/ua-parser-enums.mjs'; import * as assert from 'assert'; describe('Returns', () => { diff --git a/test/mocha-test-extension.js b/test/unit/extensions.js similarity index 65% rename from test/mocha-test-extension.js rename to test/unit/extensions.js index 246bf35..9f1fa96 100644 --- a/test/mocha-test-extension.js +++ b/test/unit/extensions.js @@ -3,30 +3,34 @@ const assert = require('assert'); const parseJS = require('@babel/parser').parse; const traverse = require('@babel/traverse').default; const safe = require('safe-regex'); -const { UAParser } = require('../src/main/ua-parser'); -const clis = require('./specs/browser-clis.json'); -const crawlers = require('./specs/browser-crawlers.json'); -const emails = require('./specs/browser-emails.json'); -const fetchers = require('./specs/browser-fetchers.json'); -const libraries = require('./specs/browser-libraries.json'); -const { Bots, CLIs, Crawlers, Emails, Fetchers, Libraries } = require('../src/extensions/ua-parser-extensions'); +const { UAParser } = require('../../src/main/ua-parser'); +const { Bots, CLIs, Crawlers, Emails, Fetchers, InApps, Libraries, Vehicles } = require('../../src/extensions/ua-parser-extensions'); describe('Extensions', () => { [ - ['CLIs', clis, CLIs], - ['Crawlers', crawlers, Crawlers], - ['Emails', emails, Emails], - ['Fetchers', fetchers, Fetchers], - ['Libraries', libraries, Libraries] + ['CLIs', 'cli', CLIs], + ['Crawlers', 'crawler', Crawlers], + ['Emails', 'email', Emails], + ['Fetchers', 'fetcher', Fetchers], + ['InApps', 'inapp', InApps], + ['Libraries', 'library', Libraries], + ['Vehicles', 'vehicle', Vehicles] ] - .forEach((list) => { - describe(list[0], () => { - list[1].forEach((agent) => { - it(`Can detect ${agent.desc}`, () => { - let browser = UAParser(agent.ua, list[2]).browser; - assert.strictEqual(String(browser.name), agent.expect.name); - assert.strictEqual(String(browser.version), agent.expect.version); - assert.strictEqual(String(browser.type), agent.expect.type); + .forEach(([desc, path, ext]) => { + const tests = require(`../data/ua/extension/${path}.json`); + describe(desc, () => { + tests.forEach((test) => { + it(`Can detect ${test.desc}: "${test.ua}"`, () => { + const { browser, device } = UAParser(test.ua, ext); + if ('browser' in ext) { + assert.strictEqual(String(browser.name), test.expect.name); + assert.strictEqual(String(browser.version), test.expect.version); + assert.strictEqual(String(browser.type), test.expect.type); + } else if ('device' in ext) { + assert.strictEqual(String(device.vendor), test.expect.vendor); + assert.strictEqual(String(device.model), test.expect.model); + assert.strictEqual(String(device.type), test.expect.type); + } }); }); }); @@ -48,6 +52,21 @@ describe('Extensions', () => { assert.deepEqual(libraryParser.setUA(axios).getBrowser(), {name: "axios", version: "1.3.5", major: "1", type: "library"}); assert.deepEqual(libraryParser.setUA(jsdom).getBrowser(), {name: "jsdom", version: "20.0.3", major: "20", type: "library"}); assert.deepEqual(libraryParser.setUA(scrapy).getBrowser(), {name: "Scrapy", version: "1.5.0", major: "1", type: "library"}); + + // Bluesky + const bluesky = 'Mozilla/5.0 (compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app)'; + assert.deepEqual(new UAParser(bluesky, Bots).getBrowser(), { + name: 'Bluesky', + version: '1.1', + major: '1', + type: 'fetcher' + }); + + const whatsapp = "WhatsApp/2.0 A"; + assert.deepEqual(new UAParser(whatsapp, Fetchers).getOS(), { + name : 'Android', + version : undefined + }); }); describe('Merge', () => { diff --git a/test/mocha-test-helpers.js b/test/unit/helpers.js similarity index 90% rename from test/mocha-test-helpers.js rename to test/unit/helpers.js index d6170bc..127133b 100644 --- a/test/mocha-test-helpers.js +++ b/test/unit/helpers.js @@ -1,7 +1,7 @@ const assert = require('assert'); -const { UAParser } = require('../src/main/ua-parser'); -const { getDeviceVendor, isAppleSilicon, isAIBot, isBot, isChromeFamily } = require('../src/helpers/ua-parser-helpers'); -const { Bots, Emails } = require('../src/extensions/ua-parser-extensions'); +const { UAParser } = require('../../src/main/ua-parser'); +const { getDeviceVendor, isAppleSilicon, isAIBot, isBot, isChromeFamily } = require('../../src/helpers/ua-parser-helpers'); +const { Bots, Emails } = require('../../src/extensions/ua-parser-extensions'); describe('getDeviceVendor', () => { it('Can guess the device vendor from a model name', () => { @@ -9,13 +9,11 @@ describe('getDeviceVendor', () => { const modelSM = 'SM-A605G'; const modelRedmi = 'Redmi Note 8'; const modelNexus = 'Nexus 6P'; - const modelQuest = 'Quest 3'; const modelAquos = 'AQUOS-TVX19B'; assert.equal(getDeviceVendor(modelSM), 'Samsung'); assert.equal(getDeviceVendor(modelRedmi), 'Xiaomi'); assert.equal(getDeviceVendor(modelNexus), 'Huawei'); - assert.equal(getDeviceVendor(modelQuest), 'Facebook'); assert.equal(getDeviceVendor(modelAquos), 'Sharp'); }); }); @@ -40,11 +38,13 @@ describe('isAIBot', () => { const claudeBot = 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)'; const firefox = 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0'; const searchGPT = 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; OAI-SearchBot/1.0; +https://openai.com/searchbot'; + const semrushAI = 'Mozilla/5.0 (compatible; SemrushBot-OCOB/1; +https://www.semrush.com/bot/)'; assert.equal(isAIBot(UAParser(claudeBot, Bots)), true); assert.equal(isAIBot(claudeBot), true); assert.equal(isAIBot(firefox), false); assert.equal(isAIBot(searchGPT), true); + assert.equal(isAIBot(semrushAI), true); }); }); diff --git a/test/mocha-test.js b/test/unit/main.js similarity index 62% rename from test/mocha-test.js rename to test/unit/main.js index 68213ac..3f01d19 100644 --- a/test/mocha-test.js +++ b/test/unit/main.js @@ -4,45 +4,21 @@ var assert = require('assert'); var requirejs = require('requirejs'); var parseJS = require('@babel/parser').parse; var traverse = require('@babel/traverse').default; -var {UAParser} = require('../src/main/ua-parser'); -var browsers = require('./specs/browser-all.json'); -var cpus = require('./specs/cpu-all.json'); -var devices = require('./specs/device-all.json'); -var engines = require('./specs/engine-all.json'); -var os = require('./specs/os-all.json'); +var {UAParser} = require('../../src/main/ua-parser'); +var browsers = require('../data/ua/browser/browser-all.json'); +var cpus = require('../data/ua/cpu/cpu-all.json'); +var devices = readJsonFiles('test/data/ua/device'); +var engines = require('../data/ua/engine/engine-all.json'); +var os = readJsonFiles('test/data/ua/os'); +var { Headers } = require('node-fetch'); -var parser = new UAParser(); -var methods = [ - { - title : 'getBrowser', - label : 'browser', - list : browsers, - properties : ['name', 'major', 'version', 'type'] - }, - { - title : 'getCPU', - label : 'cpu', - list : cpus, - properties : ['architecture'] - }, - { - title : 'getDevice', - label : 'device', - list : devices, - properties : ['model', 'type', 'vendor'] - }, - { - title : 'getEngine', - label : 'engine', - list : engines, - properties : ['name', 'version'] - }, - { - title : 'getOS', - label : 'os', - list : os, - properties : ['name', 'version'] -}]; +function readJsonFiles(dir) { + var list = []; + fs.readdirSync(dir).forEach(function (file) { + list.push(...JSON.parse(fs.readFileSync(`${dir}/${file}`, 'utf-8'))); + }); + return list; +}; 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'; @@ -57,26 +33,50 @@ describe('UAParser.setUA method does not throw with undefined ua argument', func assert.doesNotThrow(() => new UAParser().setUA(undefined).getResult()); }); -for (var i in methods) { - describe(methods[i]['title'], function () { - for (var j in methods[i]['list']) { - if (!!methods[i]['list'][j].ua) { - describe('[' + methods[i]['list'][j].desc + ']', function () { - describe('"' + methods[i]['list'][j].ua + '"', function () { - var expect = methods[i]['list'][j].expect; - var result = parser.setUA(methods[i]['list'][j].ua).getResult()[methods[i]['label']]; - - methods[i]['properties'].forEach(function(m) { - it('should return ' + methods[i]['label'] + ' ' + m + ': ' + expect[m], function () { - assert.strictEqual(result[m], expect[m] != 'undefined' ? expect[m] : undefined); - }); +describe('UAParser get*() methods', () => { + [ + { + title : 'getBrowser()', + label : 'browser', + list : browsers + }, + { + title : 'getCPU()', + label : 'cpu', + list : cpus + }, + { + title : 'getDevice()', + label : 'device', + list : devices + }, + { + title : 'getEngine()', + label : 'engine', + list : engines + }, + { + title : 'getOS()', + label : 'os', + list : os + } + ] + .forEach(method => { + describe(`[${method.title}]`, () => { + method.list.forEach(unit => { + describe(`[${unit.desc}]: "${unit.ua}"`, () => { + const actual = UAParser(unit.ua)[method.label]; + Object.entries(unit.expect).forEach(entry => { + const [key, val] = entry; + it(`Should return ${key}: ${val}`, () => { + assert.strictEqual(String(val), String(actual[key])); }); }); }); - } - } + }); + }); }); -} +}); describe('Returns', function () { it('getResult() should returns JSON', function(done) { @@ -183,9 +183,9 @@ describe('Testing regexes', function () { describe('Begin testing', function () { it('all regexes in main file', function () { - regexes.forEach(function (regex) { - describe('Test against `safe-regex` : ' + regex, function () { - it('should be safe from potentially vulnerable regex', function () { + describe('Test against `safe-regex` module', function () { + regexes.forEach(function (regex) { + it(`Should pass \`safe-regex\`: ${regex}`, function () { assert.strictEqual(safe(regex), true); }); }); @@ -346,224 +346,11 @@ describe('Read user-agent data from req.headers', function () { let engine = UAParser(req.headers).engine; assert.strictEqual(engine.name, "EdgeHTML"); }); -}); -describe('Map UA-CH headers', function () { - - const headers = { - 'sec-ch-ua' : '"Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"', - 'sec-ch-ua-full-version-list' : '"Chromium";v="93.0.1.2", "Google Chrome";v="93.0.1.2", " Not;A Brand";v="99.0.1.2"', - 'sec-ch-ua-arch' : '"arm"', - 'sec-ch-ua-bitness' : '"64"', - 'sec-ch-ua-mobile' : '?1', - 'sec-ch-ua-model' : '"Pixel 99"', - 'sec-ch-ua-platform' : '"Windows"', - 'sec-ch-ua-platform-version' : '"13"', - 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' - }; - - let uap = UAParser(headers).withClientHints(); - let browser = new UAParser(headers).getBrowser().withClientHints(); - let cpu = new UAParser(headers).getCPU().withClientHints(); - let device = new UAParser(headers).getDevice().withClientHints(); - let engine = new UAParser(headers).getEngine().withClientHints(); - let os = new UAParser(headers).getOS().withClientHints(); - - it('Can read from client-hints headers using `withClientHints()`', function () { - - //assert.deepEqual(uap.ua_ch, ua_ch); - assert.strictEqual(uap.ua, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"); - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "93.0.1.2"); - assert.strictEqual(uap.browser.major, "93"); - assert.strictEqual(browser.name, "Chrome"); - assert.strictEqual(browser.version, "93.0.1.2"); - assert.strictEqual(browser.major, "93"); - assert.strictEqual(uap.cpu.architecture, "arm64"); - assert.strictEqual(cpu.architecture, "arm64"); - assert.strictEqual(uap.device.type, "mobile"); - assert.strictEqual(uap.device.model, "Pixel 99"); - assert.strictEqual(uap.device.vendor, undefined); - assert.strictEqual(device.type, "mobile"); - assert.strictEqual(device.model, "Pixel 99"); - assert.strictEqual(device.vendor, undefined); - assert.strictEqual(uap.engine.name, 'Blink'); - assert.strictEqual(uap.engine.version, '110.0.0.0'); - assert.strictEqual(engine.name, 'Blink'); - assert.strictEqual(engine.version, '110.0.0.0'); - assert.strictEqual(uap.os.name, "Windows"); - assert.strictEqual(uap.os.version, "11"); - assert.strictEqual(os.name, "Windows"); - assert.strictEqual(os.version, "11"); - }); - - it('Only read from user-agent header when called without `withClientHints()`', function () { - - uap = UAParser(headers); - browser = new UAParser(headers).getBrowser(); - cpu = new UAParser(headers).getCPU(); - device = new UAParser(headers).getDevice(); - engine = new UAParser(headers).getEngine(); - os = new UAParser(headers).getOS(); - - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "110.0.0.0"); - assert.strictEqual(uap.browser.major, "110"); - assert.strictEqual(uap.cpu.architecture, "amd64"); - assert.strictEqual(uap.device.type, undefined); - assert.strictEqual(uap.device.model, undefined); - assert.strictEqual(uap.device.vendor, undefined); - assert.strictEqual(uap.engine.name, 'Blink'); - assert.strictEqual(uap.engine.version, '110.0.0.0'); - assert.strictEqual(uap.os.name, "Linux"); - assert.strictEqual(uap.os.version, "x86_64"); - }); - - it('Fallback to user-agent header when using `withClientHints()` but found no client hints-related headers', function () { - - const headers2 = { - 'sec-ch-ua-mobile' : '?1', - 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' - }; - - uap = UAParser(headers2).withClientHints(); - - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "110.0.0.0"); - assert.strictEqual(uap.browser.major, "110"); - assert.strictEqual(uap.cpu.architecture, "amd64"); - assert.strictEqual(uap.device.type, "mobile"); - assert.strictEqual(uap.device.model, undefined); - assert.strictEqual(uap.device.vendor, undefined); - assert.strictEqual(uap.engine.name, 'Blink'); - assert.strictEqual(uap.engine.version, '110.0.0.0'); - assert.strictEqual(uap.os.name, "Linux"); - assert.strictEqual(uap.os.version, "x86_64"); - }); - - it('Can detect Apple silicon from client hints data', function () { - - // https://github.com/faisalman/ua-parser-js/issues/489#issuecomment-1479213579 - const httpHeadersFromAppleSilicon = { - 'sec-ch-ua-arch' : 'arm', - 'sec-ch-ua-platform' : 'macOS', - 'sec-ch-ua-mobile' : '?0', - 'sec-ch-ua' : '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', - 'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0' - }; - - UAParser(httpHeadersFromAppleSilicon).withClientHints().then(function (ua) { - - // Only works in Chrome - /* - if (ua.os.is("macOS") && - ua.cpu.is("arm") && - !ua.device.is("mobile") && - !ua.device.is("tablet")) { - // possibly an Apple silicon device - } - */ - - assert.strictEqual(ua.os.is("macOS"), true); - assert.strictEqual(ua.cpu.is("arm"), true); - assert.strictEqual(ua.device.is("mobile"), false); - assert.strictEqual(ua.device.is("tablet"), false); - }); - }); - - it('Can detect form-factors from client-hints', function () { - - const FFVR = { - 'sec-ch-ua-form-factors' : '"VR"' - }; - - const FFEInk = { - 'sec-ch-ua-form-factors' : '"Tablet", "EInk"' - }; - - const FFUnknown = { - 'sec-ch-ua-form-factors' : '"Unknown"' - }; - - UAParser(FFVR).withClientHints().then(function (ua) { - assert.strictEqual(ua.device.type, 'xr'); - }); - - UAParser(FFEInk).withClientHints().then(function (ua) { - assert.strictEqual(ua.device.type, 'tablet'); - }); - - - UAParser(FFUnknown).withClientHints().then(function (ua) { - assert.strictEqual(ua.device.type, undefined); - }); - }); - - it('Avoid error on headers variation', function () { - - const headers2 = { - 'sec-ch-ua' : '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', - 'sec-ch-ua-full-version-list' : '"Google Chrome", "Chromium", "Not?A_Brand";v="24.0.0.0"', - 'sec-ch-ua-full-version' : '""', - 'sec-ch-ua-mobile' : '?0', - 'sec-ch-ua-arch' : '""', - 'sec-ch-ua-bitness' : '""', - 'sec-ch-ua-model' : '""', - 'sec-ch-ua-platform' : '"Windows"', - 'sec-ch-ua-platform-version' : '""', - 'sec-ch-ua-wow64' : '?0', - }; - - uap = UAParser(headers2).withClientHints(); - - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, undefined); - assert.strictEqual(uap.browser.major, undefined); - }); - - it('Prioritize more specific brand name regardless the order', function () { - - const headers3a = { - 'sec-ch-ua-full-version-list' : '"Not_A Brand;v=8, Chromium;v=120.0.6099.131, Google Chrome;v=120.0.6099.132"' - }; - const headers3b = { - 'sec-ch-ua-full-version-list' : '"Chromium;v=120.0.6099.131, Not_A Brand;v=8, Google Chrome;v=120.0.6099.132"' - }; - const headers3c = { - 'sec-ch-ua-full-version-list' : '"Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131, Not_A Brand;v=8"' - }; - const headers3d = { - 'sec-ch-ua-full-version-list' : '"Microsoft Edge;v=120.0.6099.133, Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131, Not_A Brand;v=8"' - }; - const headers3e = { - 'sec-ch-ua-full-version-list' : '"Chromium;v=120.0.6099.131, Google Chrome;v=120.0.6099.132, Microsoft Edge;v=120.0.6099.133, Not_A Brand;v=8"' - }; - const headers3f = { - 'sec-ch-ua-full-version-list' : '"Not_A Brand;v=8, Microsoft Edge;v=120.0.6099.133, Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131"' - }; - - uap = UAParser(headers3a).withClientHints(); - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "120.0.6099.132"); - - uap = UAParser(headers3b).withClientHints(); - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "120.0.6099.132"); - - uap = UAParser(headers3c).withClientHints(); - assert.strictEqual(uap.browser.name, "Chrome"); - assert.strictEqual(uap.browser.version, "120.0.6099.132"); - - uap = UAParser(headers3d).withClientHints(); - assert.strictEqual(uap.browser.name, "Edge"); - assert.strictEqual(uap.browser.version, "120.0.6099.133"); - - uap = UAParser(headers3e).withClientHints(); - assert.strictEqual(uap.browser.name, "Edge"); - assert.strictEqual(uap.browser.version, "120.0.6099.133"); - - uap = UAParser(headers3f).withClientHints(); - assert.strictEqual(uap.browser.name, "Edge"); - assert.strictEqual(uap.browser.version, "120.0.6099.133"); + it('Fetch API\'s Header can be passed directly into headers', () => { + const reqHeaders = new Headers(); + reqHeaders.append('User-Agent', 'Midori/0.2.2 (X11; Linux i686; U; en-us) WebKit/531.2+'); + const { browser } = UAParser(reqHeaders); + assert.strictEqual(browser.is('Midori'), true); }); }); \ No newline at end of file diff --git a/test/unit/ua-ch.js b/test/unit/ua-ch.js new file mode 100644 index 0000000..54e2f9a --- /dev/null +++ b/test/unit/ua-ch.js @@ -0,0 +1,622 @@ +const assert = require('assert'); +const { UAParser } = require('../../src/main/ua-parser'); + +describe('Map UA-CH headers', () => { + + const headers = { + 'sec-ch-ua' : '"Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"', + 'sec-ch-ua-full-version-list' : '"Chromium";v="93.0.1.2", "Google Chrome";v="93.0.1.2", " Not;A Brand";v="99.0.1.2"', + 'sec-ch-ua-arch' : '"arm"', + 'sec-ch-ua-bitness' : '"64"', + 'sec-ch-ua-mobile' : '?1', + 'sec-ch-ua-model' : '"Pixel 99"', + 'sec-ch-ua-platform' : '"Windows"', + 'sec-ch-ua-platform-version' : '"13"', + 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' + }; + + let uap = UAParser(headers).withClientHints(); + let browser = new UAParser(headers).getBrowser().withClientHints(); + let cpu = new UAParser(headers).getCPU().withClientHints(); + let device = new UAParser(headers).getDevice().withClientHints(); + let engine = new UAParser(headers).getEngine().withClientHints(); + let os = new UAParser(headers).getOS().withClientHints(); + + it('Can read from client-hints headers using `withClientHints()`', () => { + + assert.strictEqual(uap.ua, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"); + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "93.0.1.2"); + assert.strictEqual(uap.browser.major, "93"); + assert.strictEqual(browser.name, "Chrome"); + assert.strictEqual(browser.version, "93.0.1.2"); + assert.strictEqual(browser.major, "93"); + assert.strictEqual(uap.cpu.architecture, "arm64"); + assert.strictEqual(cpu.architecture, "arm64"); + assert.strictEqual(uap.device.type, "mobile"); + assert.strictEqual(uap.device.model, "Pixel 99"); + assert.strictEqual(uap.device.vendor, "Google"); + assert.strictEqual(device.type, "mobile"); + assert.strictEqual(device.model, "Pixel 99"); + assert.strictEqual(device.vendor, "Google"); + assert.strictEqual(uap.engine.name, 'Blink'); + assert.strictEqual(uap.engine.version, '93.0.1.2'); + assert.strictEqual(engine.name, 'Blink'); + assert.strictEqual(engine.version, '93.0.1.2'); + assert.strictEqual(uap.os.name, "Windows"); + assert.strictEqual(uap.os.version, "11"); + assert.strictEqual(os.name, "Windows"); + assert.strictEqual(os.version, "11"); + }); + + it('Only read from user-agent header when called without `withClientHints()`', () => { + + uap = UAParser(headers); + browser = new UAParser(headers).getBrowser(); + cpu = new UAParser(headers).getCPU(); + device = new UAParser(headers).getDevice(); + engine = new UAParser(headers).getEngine(); + os = new UAParser(headers).getOS(); + + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "110.0.0.0"); + assert.strictEqual(uap.browser.major, "110"); + assert.strictEqual(uap.cpu.architecture, "amd64"); + assert.strictEqual(uap.device.type, undefined); + assert.strictEqual(uap.device.model, undefined); + assert.strictEqual(uap.device.vendor, undefined); + assert.strictEqual(uap.engine.name, 'Blink'); + assert.strictEqual(uap.engine.version, '110.0.0.0'); + assert.strictEqual(uap.os.name, "Linux"); + assert.strictEqual(uap.os.version, undefined); + }); + + it('Fallback to user-agent header when using `withClientHints()` but found no client hints-related headers', () => { + + const headers2 = { + 'sec-ch-ua-mobile' : '?1', + 'user-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' + }; + + uap = UAParser(headers2).withClientHints(); + + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "110.0.0.0"); + assert.strictEqual(uap.browser.major, "110"); + assert.strictEqual(uap.cpu.architecture, "amd64"); + assert.strictEqual(uap.device.type, "mobile"); + assert.strictEqual(uap.device.model, undefined); + assert.strictEqual(uap.device.vendor, undefined); + assert.strictEqual(uap.engine.name, 'Blink'); + assert.strictEqual(uap.engine.version, '110.0.0.0'); + assert.strictEqual(uap.os.name, "Linux"); + assert.strictEqual(uap.os.version, undefined); + }); + + it('Can detect Apple silicon from client hints data', () => { + + // https://github.com/faisalman/ua-parser-js/issues/489#issuecomment-1479213579 + const httpHeadersFromAppleSilicon = { + 'sec-ch-ua-arch' : 'arm', + 'sec-ch-ua-platform' : 'macOS', + 'sec-ch-ua-mobile' : '?0', + 'sec-ch-ua' : '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + 'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0' + }; + + UAParser(httpHeadersFromAppleSilicon).withClientHints().then(ua => { + + // Only works in Chrome + /* + if (ua.os.is("macOS") && + ua.cpu.is("arm") && + !ua.device.is("mobile") && + !ua.device.is("tablet")) { + // possibly an Apple silicon device + } + */ + + assert.strictEqual(ua.os.is("macOS"), true); + assert.strictEqual(ua.cpu.is("arm"), true); + assert.strictEqual(ua.device.is("mobile"), false); + assert.strictEqual(ua.device.is("tablet"), false); + }); + }); + + it('Can detect form-factors from client-hints', () => { + + const FFVR = { + 'sec-ch-ua-form-factors' : '"VR"' + }; + + const FFEInk = { + 'sec-ch-ua-form-factors' : '"Tablet", "EInk"' + }; + + const FFUnknown = { + 'sec-ch-ua-form-factors' : '"Unknown"' + }; + + UAParser(FFVR).withClientHints().then(ua => { + assert.strictEqual(ua.device.type, 'xr'); + }); + + UAParser(FFEInk).withClientHints().then(ua => { + assert.strictEqual(ua.device.type, 'tablet'); + }); + + + UAParser(FFUnknown).withClientHints().then(ua => { + assert.strictEqual(ua.device.type, undefined); + }); + }); + + it('Avoid error on headers variation', () => { + + const headers2 = { + 'sec-ch-ua' : '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', + 'sec-ch-ua-full-version-list' : '"Google Chrome", "Chromium", "Not?A_Brand";v="24.0.0.0"', + 'sec-ch-ua-full-version' : '""', + 'sec-ch-ua-mobile' : '?0', + 'sec-ch-ua-arch' : '""', + 'sec-ch-ua-bitness' : '""', + 'sec-ch-ua-model' : '""', + 'sec-ch-ua-platform' : '"Windows"', + 'sec-ch-ua-platform-version' : '""', + 'sec-ch-ua-wow64' : '?0', + }; + + uap = UAParser(headers2).withClientHints(); + + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, undefined); + assert.strictEqual(uap.browser.major, undefined); + }); + + it('Prioritize more specific brand name regardless the order', () => { + + const headers3a = { + 'sec-ch-ua-full-version-list' : '"Not_A Brand;v=8, Chromium;v=120.0.6099.131, Google Chrome;v=120.0.6099.132"' + }; + const headers3b = { + 'sec-ch-ua-full-version-list' : '"Chromium;v=120.0.6099.131, Not_A Brand;v=8, Google Chrome;v=120.0.6099.132"' + }; + const headers3c = { + 'sec-ch-ua-full-version-list' : '"Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131, Not_A Brand;v=8"' + }; + const headers3d = { + 'sec-ch-ua-full-version-list' : '"Microsoft Edge;v=120.0.6099.133, Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131, Not_A Brand;v=8"' + }; + const headers3e = { + 'sec-ch-ua-full-version-list' : '"Chromium;v=120.0.6099.131, Google Chrome;v=120.0.6099.132, Microsoft Edge;v=120.0.6099.133, Not_A Brand;v=8"' + }; + const headers3f = { + 'sec-ch-ua-full-version-list' : '"Not_A Brand;v=8, Microsoft Edge;v=120.0.6099.133, Google Chrome;v=120.0.6099.132, Chromium;v=120.0.6099.131"' + }; + + uap = UAParser(headers3a).withClientHints(); + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "120.0.6099.132"); + + uap = UAParser(headers3b).withClientHints(); + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "120.0.6099.132"); + + uap = UAParser(headers3c).withClientHints(); + assert.strictEqual(uap.browser.name, "Chrome"); + assert.strictEqual(uap.browser.version, "120.0.6099.132"); + + uap = UAParser(headers3d).withClientHints(); + assert.strictEqual(uap.browser.name, "Edge"); + assert.strictEqual(uap.browser.version, "120.0.6099.133"); + + uap = UAParser(headers3e).withClientHints(); + assert.strictEqual(uap.browser.name, "Edge"); + assert.strictEqual(uap.browser.version, "120.0.6099.133"); + + uap = UAParser(headers3f).withClientHints(); + assert.strictEqual(uap.browser.name, "Edge"); + assert.strictEqual(uap.browser.version, "120.0.6099.133"); + }); +}); + +describe('UA-CH Headers tests', () => { + [ + { + headers : { + 'sec-ch-ua': '"Avast Secure Browser";v="131", "Chromium";v="131", "Not_A Brand";v="24"' + }, + expect: { + browser : { + name : 'Avast Secure Browser', + version : '131', + major : '131', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"' + }, + expect: { + browser : { + name : 'Brave', + version : '132', + major : '132', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"' + }, + expect: { + browser : { + name : 'Chrome', + version : '111', + major : '111', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"' + }, + expect: { + browser : { + name : 'Chrome Headless', + version : '124', + major : '124', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"' + }, + expect: { + browser : { + name : 'Chrome WebView', + version : '123', + major : '123', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"DuckDuckGo";v="131", "Chromium";v="131", "Not_A Brand";v="24"' + }, + expect : { + browser : { + name : 'DuckDuckGo', + version : '131', + major : '131', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"' + }, + expect: { + browser : { + name : 'Edge', + version : '120', + major : '120', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "HuaweiBrowser";v="114"' + }, + expect: { + browser : { + name : 'Huawei Browser', + version : '114', + major : '114', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Miui Browser";v="123", "Not:A-Brand";v="8", "Chromium";v="123"' + }, + expect: { + browser : { + name : 'MIUI Browser', + version : '123', + major : '123', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="130", "Oculus Browser";v="36", "Not?A_Brand";v="99"' + }, + expect: { + browser : { + name : 'Oculus Browser', + version : '36', + major : '36', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Opera";v="116", "Chromium";v="131", "Not_A Brand";v="24"' + }, + expect: { + browser : { + name : 'Opera', + version : '116', + major : '116', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Opera GX";v="114"' + }, + expect: { + browser : { + name : 'Opera GX', + version : '114', + major : '114', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"OperaMobile";v="86", ";Not A Brand";v="99", "Opera";v="115", "Chromium";v="130"' + }, + expect: { + browser : { + name : 'Opera Mobi', + version : '86', + major : '86', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="132", "OperaMobile";v="87", "Opera";v="117", " Not A;Brand";v="99"' + }, + expect: { + browser : { + name : 'Opera Mobi', + version : '87', + major : '87', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="125", "Not.A/Brand";v="24", "Samsung Internet";v="27.0"' + }, + expect: { + browser : { + name : 'Samsung Internet', + version : '27.0', + major : '27', + type : undefined + } + } + }, + { + headers : { + 'sec-ch-ua': '"Chromium";v="130", "YaBrowser";v="24.12", "Not?A_Brand";v="99", "Yowser";v="2.5"' + }, + expect: { + browser : { + name : 'Yandex', + version : '24.12', + major : '24', + type : undefined + } + } + }, + ] + .forEach(test => { + const { browser } = UAParser(test.headers).withClientHints(); + assert.deepEqual(browser, test.expect.browser); + }); +}); + +describe('Identify vendor & type of device from given model name', () => { + [ + { + model: '220733SG', + expect: { + vendor : 'Xiaomi', + type : 'mobile' + } + }, + { + model: '5087Z', + expect: { + vendor : 'TCL', + type : 'mobile' + } + }, + { + model: '9137W', + expect: { + vendor : 'TCL', + type : 'tablet' + } + }, + { + model: 'BE2015', + expect: { + vendor : 'OnePlus', + type : 'mobile' + } + }, + { + model: 'CPH2389', + expect: { + vendor : 'OPPO', + type : 'mobile' + } + }, + { + model: 'Infinix X669C', + expect: { + vendor : 'Infinix', + type : 'mobile' + } + }, + { + model: 'itel L6502', + expect: { + vendor : 'itel', + type : 'mobile' + } + }, + { + model: 'Lenovo TB-X606F', + expect: { + vendor : 'Lenovo', + type : 'tablet' + } + }, + { + model: 'LM-Q720', + expect: { + vendor : 'LG', + type : 'mobile' + } + }, + { + model: 'M2003J15SC', + expect: { + vendor : 'Xiaomi', + type : 'mobile' + } + }, + { + model: 'MAR-LX1A', + expect: { + vendor : 'Huawei', + type : 'mobile' + } + }, + { + model: 'moto g(20)', + expect: { + vendor : 'Motorola', + type : 'mobile' + } + }, + { + model: 'Nokia C210', + expect: { + vendor : 'Nokia', + type : 'mobile' + } + }, + { + model: 'Pixel 8', + expect: { + vendor : 'Google', + type : 'mobile' + } + }, + { + model: 'Redmi Note 9S', + expect: { + vendor : 'Xiaomi', + type : 'mobile' + } + }, + { + model: 'RMX3830', + expect: { + vendor : 'Realme', + type : 'mobile' + } + }, + { + model: 'SM-S536DL', + expect: { + vendor : 'Samsung', + type : 'mobile' + } + }, + { + model: 'SM-S546VL', + expect: { + vendor : 'Samsung', + type : 'mobile' + } + }, + { + model: 'SM-T875', + expect: { + vendor : 'Samsung', + type : 'tablet' + } + }, + { + model: 'STK-L21', + expect: { + vendor : 'Huawei', + type : 'mobile' + } + }, + { + model: 'T430W', + expect: { + vendor : 'TCL', + type : 'mobile' + } + }, + { + model: 'TECNO KI5k', + expect: { + vendor : 'TECNO', + type : 'mobile' + } + }, + { + model: 'vivo 1820', + expect: { + vendor : 'Vivo', + type : 'mobile' + } + }, + { + model: 'Xbox', + expect: { + vendor : 'Microsoft', + type : 'console' + } + } + ] + .forEach(test => { + it(`Solve "${test.model}"`, () => { + const headers = { + 'sec-ch-ua-model' : test.model, + }; + const { device } = UAParser(headers).withClientHints(); + assert.strictEqual(device.model, test.model); + assert.strictEqual(device.vendor, test.expect.vendor); + assert.strictEqual(device.type, test.expect.type); + }); + }); +}); \ No newline at end of file