ua-parser-js 2.0.0-beta.2 → 2.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/README.md +26 -22
  2. package/dist/icons/color/LICENSE.md +3 -0
  3. package/dist/icons/color/browser/android-browser.svg +1 -0
  4. package/dist/icons/color/browser/avant.png +0 -0
  5. package/dist/icons/color/browser/basilisk.png +0 -0
  6. package/dist/icons/color/browser/basilisk.svg +1 -0
  7. package/dist/icons/color/browser/brave.png +0 -0
  8. package/dist/icons/color/browser/brave.svg +1 -0
  9. package/dist/icons/color/browser/chrome.png +0 -0
  10. package/dist/icons/color/browser/chrome.svg +1 -0
  11. package/dist/icons/color/browser/chromium.png +0 -0
  12. package/dist/icons/color/browser/chromium.svg +1 -0
  13. package/dist/icons/color/browser/coc-coc.png +0 -0
  14. package/dist/icons/color/browser/default.png +0 -0
  15. package/dist/icons/color/browser/default.svg +1 -0
  16. package/dist/icons/color/browser/dolphin.png +0 -0
  17. package/dist/icons/color/browser/edge.png +0 -0
  18. package/dist/icons/color/browser/edge.svg +1 -0
  19. package/dist/icons/color/browser/electron.png +0 -0
  20. package/dist/icons/color/browser/electron.svg +1 -0
  21. package/dist/icons/color/browser/falkon.png +0 -0
  22. package/dist/icons/color/browser/falkon.svg +1 -0
  23. package/dist/icons/color/browser/firefox-reality.png +0 -0
  24. package/dist/icons/color/browser/firefox-reality.svg +1 -0
  25. package/dist/icons/color/browser/firefox.png +0 -0
  26. package/dist/icons/color/browser/firefox.svg +1 -0
  27. package/dist/icons/color/browser/gsa.svg +9 -0
  28. package/dist/icons/color/browser/icecat.png +0 -0
  29. package/dist/icons/color/browser/ie.svg +6 -0
  30. package/dist/icons/color/browser/konqueror.png +0 -0
  31. package/dist/icons/color/browser/konqueror.svg +1 -0
  32. package/dist/icons/color/browser/maxthon.png +0 -0
  33. package/dist/icons/color/browser/midori.png +0 -0
  34. package/dist/icons/color/browser/midori.svg +1 -0
  35. package/dist/icons/color/browser/netsurf.png +0 -0
  36. package/dist/icons/color/browser/netsurf.svg +1 -0
  37. package/dist/icons/color/browser/opera-gx.png +0 -0
  38. package/dist/icons/color/browser/opera-gx.svg +1 -0
  39. package/dist/icons/color/browser/opera-mini.png +0 -0
  40. package/dist/icons/color/browser/opera-touch.png +0 -0
  41. package/dist/icons/color/browser/opera.png +0 -0
  42. package/dist/icons/color/browser/opera.svg +1 -0
  43. package/dist/icons/color/browser/palemoon.png +0 -0
  44. package/dist/icons/color/browser/puffin.png +0 -0
  45. package/dist/icons/color/browser/safari.png +0 -0
  46. package/dist/icons/color/browser/safari.svg +1 -0
  47. package/dist/icons/color/browser/samsung-internet.png +0 -0
  48. package/dist/icons/color/browser/samsung-internet.svg +1 -0
  49. package/dist/icons/color/browser/seamonkey.png +0 -0
  50. package/dist/icons/color/browser/silk.png +0 -0
  51. package/dist/icons/color/browser/sogou-mobile.png +0 -0
  52. package/dist/icons/color/browser/ucbrowser.png +0 -0
  53. package/dist/icons/color/browser/ucbrowser.svg +1 -0
  54. package/dist/icons/color/browser/vivaldi.png +0 -0
  55. package/dist/icons/color/browser/vivaldi.svg +1 -0
  56. package/dist/icons/color/browser/webkit.png +0 -0
  57. package/dist/icons/color/browser/webkit.svg +1 -0
  58. package/dist/icons/color/browser/yandex.png +0 -0
  59. package/dist/icons/color/os/centos.svg +1 -0
  60. package/dist/icons/mono/LICENSE.md +3 -0
  61. package/dist/icons/mono/browser/alipay.svg +1 -0
  62. package/dist/icons/mono/browser/android-browser.svg +1 -0
  63. package/dist/icons/mono/browser/avast-secure-browser.svg +1 -0
  64. package/dist/icons/mono/browser/baidu-browser.svg +1 -0
  65. package/dist/icons/mono/browser/brave.svg +1 -0
  66. package/dist/icons/mono/browser/chrome-headless.svg +1 -0
  67. package/dist/icons/mono/browser/chrome-webview.svg +1 -0
  68. package/dist/icons/mono/browser/chrome.svg +1 -0
  69. package/dist/icons/mono/browser/chromium.svg +1 -0
  70. package/dist/icons/mono/browser/duckduckgo.svg +1 -0
  71. package/dist/icons/mono/browser/edge.svg +1 -0
  72. package/dist/icons/mono/browser/electron.svg +1 -0
  73. package/dist/icons/mono/browser/facebook.svg +1 -0
  74. package/dist/icons/mono/browser/firefox-focus.svg +1 -0
  75. package/dist/icons/mono/browser/firefox-reality.svg +1 -0
  76. package/dist/icons/mono/browser/firefox.svg +1 -0
  77. package/dist/icons/mono/browser/gsa.svg +1 -0
  78. package/dist/icons/mono/browser/huawei-browser.svg +1 -0
  79. package/dist/icons/mono/browser/icecat.svg +1 -0
  80. package/dist/icons/mono/browser/ie.svg +1 -0
  81. package/dist/icons/mono/browser/instagram.svg +1 -0
  82. package/dist/icons/mono/browser/jasmine.svg +1 -0
  83. package/dist/icons/mono/browser/kakaotalk.svg +1 -0
  84. package/dist/icons/mono/browser/klarna.svg +1 -0
  85. package/dist/icons/mono/browser/line.svg +1 -0
  86. package/dist/icons/mono/browser/linkedin.svg +1 -0
  87. package/dist/icons/mono/browser/miui-browser.svg +1 -0
  88. package/dist/icons/mono/browser/mobile-chrome.svg +1 -0
  89. package/dist/icons/mono/browser/mobile-firefox.svg +1 -0
  90. package/dist/icons/mono/browser/mobile-safari.svg +1 -0
  91. package/dist/icons/mono/browser/mozilla.svg +1 -0
  92. package/dist/icons/mono/browser/naver.svg +1 -0
  93. package/dist/icons/mono/browser/nokia-browser.svg +1 -0
  94. package/dist/icons/mono/browser/oculus-browser.svg +1 -0
  95. package/dist/icons/mono/browser/opera-coast.svg +1 -0
  96. package/dist/icons/mono/browser/opera-gx.svg +1 -0
  97. package/dist/icons/mono/browser/opera-mini.svg +1 -0
  98. package/dist/icons/mono/browser/opera-mobi.svg +1 -0
  99. package/dist/icons/mono/browser/opera-tablet.svg +1 -0
  100. package/dist/icons/mono/browser/opera-touch.svg +1 -0
  101. package/dist/icons/mono/browser/opera.svg +1 -0
  102. package/dist/icons/mono/browser/qqbrowser.svg +1 -0
  103. package/dist/icons/mono/browser/qqbrowserlite.svg +1 -0
  104. package/dist/icons/mono/browser/safari.svg +1 -0
  105. package/dist/icons/mono/browser/sailfish-browser.svg +1 -0
  106. package/dist/icons/mono/browser/samsung-internet.svg +1 -0
  107. package/dist/icons/mono/browser/smart-lenovo-browser.svg +1 -0
  108. package/dist/icons/mono/browser/snapchat.svg +1 -0
  109. package/dist/icons/mono/browser/sogou-explorer.svg +1 -0
  110. package/dist/icons/mono/browser/sogou-mobile.svg +1 -0
  111. package/dist/icons/mono/browser/tesla.svg +1 -0
  112. package/dist/icons/mono/browser/tiktok.svg +1 -0
  113. package/dist/icons/mono/browser/twitter.svg +1 -0
  114. package/dist/icons/mono/browser/vivaldi.svg +1 -0
  115. package/dist/icons/mono/browser/vivo-browser.svg +1 -0
  116. package/dist/icons/mono/browser/wechat.svg +1 -0
  117. package/dist/icons/mono/browser/weibo.svg +1 -0
  118. package/dist/icons/mono/browser/yandex.svg +1 -0
  119. package/dist/icons/mono/device/acer.svg +1 -0
  120. package/dist/icons/mono/device/amazon.svg +1 -0
  121. package/dist/icons/mono/device/apple.svg +1 -0
  122. package/dist/icons/mono/device/asus.svg +1 -0
  123. package/dist/icons/mono/device/att.svg +1 -0
  124. package/dist/icons/mono/device/blackberry.svg +1 -0
  125. package/dist/icons/mono/device/dell.svg +1 -0
  126. package/dist/icons/mono/device/facebook.svg +1 -0
  127. package/dist/icons/mono/device/fairphone.svg +1 -0
  128. package/dist/icons/mono/device/google.svg +1 -0
  129. package/dist/icons/mono/device/hp.svg +1 -0
  130. package/dist/icons/mono/device/huawei.svg +1 -0
  131. package/dist/icons/mono/device/lenovo.svg +1 -0
  132. package/dist/icons/mono/device/lg.svg +1 -0
  133. package/dist/icons/mono/device/meizu.svg +1 -0
  134. package/dist/icons/mono/device/microsoft.svg +1 -0
  135. package/dist/icons/mono/device/motorola.svg +1 -0
  136. package/dist/icons/mono/device/nintendo.svg +1 -0
  137. package/dist/icons/mono/device/nokia.svg +1 -0
  138. package/dist/icons/mono/device/nvidia.svg +1 -0
  139. package/dist/icons/mono/device/oneplus.svg +1 -0
  140. package/dist/icons/mono/device/oppo.svg +1 -0
  141. package/dist/icons/mono/device/panasonic.svg +1 -0
  142. package/dist/icons/mono/device/roku.svg +1 -0
  143. package/dist/icons/mono/device/samsung.svg +1 -0
  144. package/dist/icons/mono/device/siemens.svg +1 -0
  145. package/dist/icons/mono/device/sony.svg +1 -0
  146. package/dist/icons/mono/device/tesla.svg +1 -0
  147. package/dist/icons/mono/device/vivo.svg +1 -0
  148. package/dist/icons/mono/device/vodafone.svg +1 -0
  149. package/dist/icons/mono/device/xiaomi.svg +1 -0
  150. package/dist/icons/mono/device/zebra.svg +1 -0
  151. package/dist/icons/mono/os/android.svg +1 -0
  152. package/dist/icons/mono/os/arch.svg +1 -0
  153. package/dist/icons/mono/os/blackberry.svg +1 -0
  154. package/dist/icons/mono/os/centos.svg +1 -0
  155. package/dist/icons/mono/os/chrome-os.svg +1 -0
  156. package/dist/icons/mono/os/chromecast.svg +1 -0
  157. package/dist/icons/mono/os/debian.svg +1 -0
  158. package/dist/icons/mono/os/deepin.svg +1 -0
  159. package/dist/icons/mono/os/elementary-os.svg +1 -0
  160. package/dist/icons/mono/os/fedora.svg +1 -0
  161. package/dist/icons/mono/os/firefox.svg +1 -0
  162. package/dist/icons/mono/os/freebsd.svg +1 -0
  163. package/dist/icons/mono/os/gentoo.svg +1 -0
  164. package/dist/icons/mono/os/gnu.svg +1 -0
  165. package/dist/icons/mono/os/harmonyos.svg +1 -0
  166. package/dist/icons/mono/os/ios.svg +1 -0
  167. package/dist/icons/mono/os/kaios.svg +1 -0
  168. package/dist/icons/mono/os/linux.svg +1 -0
  169. package/dist/icons/mono/os/macos.svg +1 -0
  170. package/dist/icons/mono/os/manjaro.svg +1 -0
  171. package/dist/icons/mono/os/mint.svg +1 -0
  172. package/dist/icons/mono/os/netbsd.svg +1 -0
  173. package/dist/icons/mono/os/nintendo.svg +1 -0
  174. package/dist/icons/mono/os/openbsd.svg +1 -0
  175. package/dist/icons/mono/os/playstation.svg +1 -0
  176. package/dist/icons/mono/os/raspbian.svg +1 -0
  177. package/dist/icons/mono/os/redhat.svg +1 -0
  178. package/dist/icons/mono/os/sailfish.svg +1 -0
  179. package/dist/icons/mono/os/slackware.svg +1 -0
  180. package/dist/icons/mono/os/suse.svg +1 -0
  181. package/dist/icons/mono/os/ubuntu.svg +1 -0
  182. package/dist/icons/mono/os/windows.svg +1 -0
  183. package/dist/icons/mono/os/xbox.svg +1 -0
  184. package/dist/ua-parser.min.js +3 -3
  185. package/dist/ua-parser.pack.js +3 -3
  186. package/package.json +11 -6
  187. package/script/cli.js +4 -0
  188. package/src/enums/ua-parser-enums.js +30 -9
  189. package/src/enums/ua-parser-enums.mjs +30 -9
  190. package/src/extensions/ua-parser-extensions.d.ts +4 -2
  191. package/src/extensions/ua-parser-extensions.js +169 -48
  192. package/src/extensions/ua-parser-extensions.mjs +169 -48
  193. package/src/helpers/ua-parser-helpers.d.ts +12 -4
  194. package/src/helpers/ua-parser-helpers.js +44 -5
  195. package/src/helpers/ua-parser-helpers.mjs +45 -6
  196. package/src/main/ua-parser.d.ts +7 -4
  197. package/src/main/ua-parser.js +121 -54
  198. package/src/main/ua-parser.mjs +121 -54
@@ -1,10 +1,10 @@
1
1
  /////////////////////////////////////////////////////////////////////////////////
2
- /* UAParser.js v2.0.0-beta.2
3
- Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
2
+ /* UAParser.js v2.0.0-rc.1
3
+ Copyright © 2012-2024 Faisal Salman <f@faisalman.com>
4
4
  AGPLv3 License *//*
5
5
  Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
6
6
  Supports browser & node.js environment.
7
- Demo : https://faisalman.github.io/ua-parser-js
7
+ Demo : https://uaparser.dev
8
8
  Source : https://github.com/faisalman/ua-parser-js */
9
9
  /////////////////////////////////////////////////////////////////////////////////
10
10
 
@@ -19,7 +19,7 @@
19
19
  // Constants
20
20
  /////////////
21
21
 
22
- var LIBVERSION = '2.0.0-beta.2',
22
+ var LIBVERSION = '2.0.0-rc.1',
23
23
  EMPTY = '',
24
24
  UNKNOWN = '?',
25
25
  FUNC_TYPE = 'function',
@@ -38,11 +38,12 @@
38
38
  TABLET = 'tablet',
39
39
  SMARTTV = 'smarttv',
40
40
  WEARABLE = 'wearable',
41
+ XR = 'xr',
41
42
  EMBEDDED = 'embedded',
42
43
  USER_AGENT = 'user-agent',
43
44
  UA_MAX_LENGTH = 500,
44
45
  BRANDS = 'brands',
45
- FORMFACTOR = 'formFactor',
46
+ FORMFACTORS = 'formFactors',
46
47
  FULLVERLIST = 'fullVersionList',
47
48
  PLATFORM = 'platform',
48
49
  PLATFORMVER = 'platformVersion',
@@ -51,12 +52,12 @@
51
52
  CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
52
53
  CH_HEADER_ARCH = CH_HEADER + '-arch',
53
54
  CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
54
- CH_HEADER_FORM_FACTOR = CH_HEADER + '-form-factor',
55
+ CH_HEADER_FORM_FACTORS = CH_HEADER + '-form-factors',
55
56
  CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
56
57
  CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
57
58
  CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
58
59
  CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
59
- CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTOR, BITNESS],
60
+ CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
60
61
  UA_BROWSER = 'browser',
61
62
  UA_CPU = 'cpu',
62
63
  UA_DEVICE = 'device',
@@ -81,6 +82,7 @@
81
82
  PREFIX_MOBILE = 'Mobile ',
82
83
  SUFFIX_BROWSER = ' Browser',
83
84
  CHROME = 'Chrome',
85
+ CHROMECAST = 'Chromecast',
84
86
  EDGE = 'Edge',
85
87
  FIREFOX = 'Firefox',
86
88
  OPERA = 'Opera',
@@ -100,12 +102,21 @@
100
102
  // Helper
101
103
  //////////
102
104
 
103
- var extend = function (regexes, extensions) {
104
- var mergedRegexes = {};
105
- for (var i in regexes) {
106
- mergedRegexes[i] = extensions[i] && extensions[i].length % 2 === 0 ? extensions[i].concat(regexes[i]) : regexes[i];
105
+ var extend = function (defaultRgx, extensions) {
106
+ var mergedRgx = {};
107
+ var extraRgx = extensions;
108
+ if (!isExtensions(extensions)) {
109
+ extraRgx = {};
110
+ for (var i in extensions) {
111
+ for (var j in extensions[i]) {
112
+ extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
113
+ }
114
+ }
115
+ }
116
+ for (var k in defaultRgx) {
117
+ mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
107
118
  }
108
- return mergedRegexes;
119
+ return mergedRgx;
109
120
  },
110
121
  enumerize = function (arr) {
111
122
  var enums = {};
@@ -123,9 +134,9 @@
123
134
  }
124
135
  return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
125
136
  },
126
- isExtensions = function (obj) {
137
+ isExtensions = function (obj, deep) {
127
138
  for (var prop in obj) {
128
- return /^(browser|cpu|device|engine|os)$/.test(prop);
139
+ return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
129
140
  }
130
141
  },
131
142
  isString = function (val) {
@@ -269,12 +280,13 @@
269
280
  'RT' : 'ARM'
270
281
  },
271
282
 
272
- formFactorMap = {
283
+ formFactorsMap = {
273
284
  'embedded' : 'Automotive',
274
285
  'mobile' : 'Mobile',
275
286
  'tablet' : ['Tablet', 'EInk'],
276
287
  'smarttv' : 'TV',
277
- 'wearable' : ['VR', 'XR', 'Watch'],
288
+ 'wearable' : 'Watch',
289
+ 'xr' : ['VR', 'XR'],
278
290
  '?' : ['Desktop', 'Unknown'],
279
291
  '*' : undefined
280
292
  };
@@ -309,17 +321,22 @@
309
321
  /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
310
322
  ], [VERSION, [NAME, 'Baidu']], [
311
323
  /(kindle)\/([\w\.]+)/i, // Kindle
312
- /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
324
+ /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
325
+ // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
313
326
  // Trident based
314
327
  /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
315
328
  /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
316
329
 
317
330
  // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
318
- /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
319
- // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo
331
+ /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio)\/([-\w\.]+)/i,
332
+ // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio
320
333
  /(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
321
334
  /(weibo)__([\d\.]+)/i // Weibo
322
335
  ], [NAME, VERSION], [
336
+ /quark(?:pc)?\/([-\w\.]+)/i // Quark
337
+ ], [VERSION, [NAME, 'Quark']], [
338
+ /\bddg\/([\w\.]+)/i // DuckDuckGo
339
+ ], [VERSION, [NAME, 'DuckDuckGo']], [
323
340
  /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
324
341
  ], [VERSION, [NAME, 'UCBrowser']], [
325
342
  /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
@@ -352,8 +369,10 @@
352
369
  ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
353
370
  /\bqihu|(qi?ho?o?|360)browser/i // 360
354
371
  ], [[NAME, '360' + SUFFIX_BROWSER]], [
355
- /(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i
356
- ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser
372
+ /\b(qq)\/([\w\.]+)/i // QQ
373
+ ], [[NAME, /(.+)/, '$1Browser'], VERSION], [
374
+ /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
375
+ ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
357
376
  /samsungbrowser\/([\w\.]+)/i // Samsung Internet
358
377
  ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
359
378
  /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
@@ -366,7 +385,7 @@
366
385
  /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
367
386
  /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
368
387
  ], [NAME, VERSION], [
369
- /(lbbrowser)/i, // LieBao Browser
388
+ /(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
370
389
  /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
371
390
  ], [NAME], [
372
391
 
@@ -379,6 +398,7 @@
379
398
  /safari (line)\/([\w\.]+)/i, // Line App for iOS
380
399
  /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
381
400
  /(alipay)client\/([\w\.]+)/i, // Alipay
401
+ /(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
382
402
  /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
383
403
  ], [NAME, VERSION], [
384
404
  /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
@@ -418,23 +438,24 @@
418
438
  ], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
419
439
  /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
420
440
  ], [[NAME, 'Netscape'], VERSION], [
441
+ /(wolvic)\/([\w\.]+)/i // Wolvic
442
+ ], [NAME, VERSION], [
421
443
  /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
422
444
  ], [VERSION, [NAME, FIREFOX+' Reality']], [
423
445
  /ekiohf.+(flow)\/([\w\.]+)/i, // Flow
424
446
  /(swiftfox)/i, // Swiftfox
425
- /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
426
- // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
447
+ /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
448
+ // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
427
449
  /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
428
450
  // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
429
451
  /(firefox)\/([\w\.]+)/i, // Other Firefox-based
430
452
  /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
431
453
 
432
454
  // Other
433
- /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
434
- // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
435
- /(links) \(([\w\.]+)/i, // Links
436
- /panasonic;(viera)/i // Panasonic Viera
437
- ], [NAME, VERSION], [
455
+ /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
456
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser
457
+ /(links) \(([\w\.]+)/i // Links
458
+ ], [NAME, [VERSION, /_/g, '.']], [
438
459
 
439
460
  /(cobalt)\/([\w\.]+)/i // Cobalt
440
461
  ], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
@@ -479,8 +500,8 @@
479
500
  // Samsung
480
501
  /\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
481
502
  ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
482
- /\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
483
- /samsung[- ]([-\w]+)/i,
503
+ /\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
504
+ /samsung[- ]((?!sm-[lr])[-\w]+)/i,
484
505
  /sec-(sgh\w+)/i
485
506
  ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
486
507
 
@@ -511,7 +532,7 @@
511
532
  /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
512
533
  /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
513
534
  /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
514
- /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
535
+ /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi
515
536
  ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
516
537
  /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
517
538
  /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
@@ -521,6 +542,8 @@
521
542
  /; (\w+) bui.+ oppo/i,
522
543
  /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
523
544
  ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
545
+ /\b(opd2\d{3}a?) bui/i
546
+ ], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [
524
547
 
525
548
  // Vivo
526
549
  /vivo (\w+)(?: bui|\))/i,
@@ -577,7 +600,7 @@
577
600
 
578
601
  // Amazon
579
602
  /(alexa)webm/i,
580
- /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show
603
+ /(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i, // Kindle Fire without Silk / Echo Show
581
604
  /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
582
605
  ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
583
606
  /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
@@ -606,6 +629,17 @@
606
629
  /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
607
630
  ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
608
631
 
632
+ // TCL
633
+ /tcl (xess p17aa)/i,
634
+ /droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i
635
+ ], [MODEL, [VENDOR, 'TCL'], [TYPE, TABLET]], [
636
+ /droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i
637
+ ], [MODEL, [VENDOR, 'TCL'], [TYPE, MOBILE]], [
638
+
639
+ // itel
640
+ /(itel) ((\w+))/i
641
+ ], [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { 'tablet' : ['p10001l', 'w7001'], '*' : 'mobile' }]], [
642
+
609
643
  // Acer
610
644
  /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
611
645
  ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
@@ -619,6 +653,10 @@
619
653
  /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
620
654
  ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
621
655
 
656
+ // Nothing
657
+ /droid.+; (a(?:015|06[35]|142p?))/i
658
+ ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
659
+
622
660
  // MIXED
623
661
  /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
624
662
  // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
@@ -663,8 +701,14 @@
663
701
  ], [[VENDOR, LG], [TYPE, SMARTTV]], [
664
702
  /(apple) ?tv/i // Apple TV
665
703
  ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
666
- /crkey/i // Google Chromecast
667
- ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
704
+ /crkey.*devicetype\/chromecast/i // Google Chromecast Third Generation
705
+ ], [[MODEL, CHROMECAST+' Third Generation'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
706
+ /crkey.*devicetype\/([^/]*)/i // Google Chromecast with specific device type
707
+ ], [[MODEL, /^/, 'Chromecast '], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
708
+ /fuchsia.*crkey/i // Google Chromecast Nest Hub
709
+ ], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
710
+ /crkey/i // Google Chromecast, Linux-based or unknown
711
+ ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
668
712
  /droid.+aft(\w+)( bui|\))/i // Fire TV
669
713
  ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
670
714
  /\(dtv[\);].+(aquos)/i,
@@ -700,16 +744,25 @@
700
744
  // WEARABLES
701
745
  ///////////////////
702
746
 
747
+ /\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch
748
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [
703
749
  /((pebble))app/i // Pebble
704
750
  ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
705
751
  /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
706
752
  ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
707
- /droid.+; (glass) \d/i // Google Glass
708
- ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
709
753
  /droid.+; (wt63?0{2,3})\)/i
710
754
  ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
711
- /(quest( 2| pro)?)/i // Oculus Quest
712
- ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [
755
+
756
+ ///////////////////
757
+ // XR
758
+ ///////////////////
759
+
760
+ /droid.+; (glass) \d/i // Google Glass
761
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
762
+ /(pico) (4|neo3(?: link|pro)?)/i // Pico
763
+ ], [VENDOR, MODEL, [TYPE, XR]], [
764
+ /; (quest( \d| pro)?)/i // Oculus Quest
765
+ ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
713
766
 
714
767
  ///////////////////
715
768
  // EMBEDDED
@@ -741,6 +794,9 @@
741
794
  /windows.+ edge\/([\w\.]+)/i // EdgeHTML
742
795
  ], [VERSION, [NAME, EDGE+'HTML']], [
743
796
 
797
+ /(arkweb)\/([\w\.]+)/i // ArkWeb
798
+ ], [NAME, VERSION], [
799
+
744
800
  /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
745
801
  ], [VERSION, [NAME, 'Blink']], [
746
802
 
@@ -777,10 +833,22 @@
777
833
  /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS
778
834
  ], [[NAME, 'macOS'], [VERSION, /_/g, '.']], [
779
835
 
836
+ // Google Chromecast
837
+ /android ([\d\.]+).*crkey/i // Google Chromecast, Android-based
838
+ ], [VERSION, [NAME, CHROMECAST + ' Android']], [
839
+ /fuchsia.*crkey\/([\d\.]+)/i // Google Chromecast, Fuchsia-based
840
+ ], [VERSION, [NAME, CHROMECAST + ' Fuchsia']], [
841
+ /crkey\/([\d\.]+).*devicetype\/smartspeaker/i // Google Chromecast, Linux-based Smart Speaker
842
+ ], [VERSION, [NAME, CHROMECAST + ' SmartSpeaker']], [
843
+ /linux.*crkey\/([\d\.]+)/i // Google Chromecast, Legacy Linux-based
844
+ ], [VERSION, [NAME, CHROMECAST + ' Linux']], [
845
+ /crkey\/([\d\.]+)/i // Google Chromecast, unknown
846
+ ], [VERSION, [NAME, CHROMECAST]], [
847
+
780
848
  // Mobile OSes
781
849
  /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS
782
- ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
783
- /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
850
+ ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony
851
+ /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i,
784
852
  /(blackberry)\w*\/([\w\.]*)/i, // Blackberry
785
853
  /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS
786
854
  /\((series40);/i // Series 40
@@ -797,9 +865,7 @@
797
865
  /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
798
866
  ], [VERSION, [NAME, 'watchOS']], [
799
867
 
800
- // Google Chromecast
801
- /crkey\/([\d\.]+)/i // Google Chromecast
802
- ], [VERSION, [NAME, CHROME+'cast']], [
868
+ // Google ChromeOS
803
869
  /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
804
870
  ], [[NAME, "Chrome OS"], VERSION],[
805
871
 
@@ -811,6 +877,7 @@
811
877
  // Console
812
878
  /(nintendo|playstation) (\w+)/i, // Nintendo/Playstation
813
879
  /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
880
+ /(pico) .+os([\w\.]+)/i, // Pico
814
881
 
815
882
  // Other
816
883
  /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
@@ -840,7 +907,7 @@
840
907
  var defaultProps = (function () {
841
908
  var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
842
909
  setProps.call(props.init, [
843
- [UA_BROWSER, [NAME, VERSION, MAJOR]],
910
+ [UA_BROWSER, [NAME, VERSION, MAJOR, TYPE]],
844
911
  [UA_CPU, [ARCHITECTURE]],
845
912
  [UA_DEVICE, [TYPE, MODEL, VENDOR]],
846
913
  [UA_ENGINE, [NAME, VERSION]],
@@ -968,7 +1035,7 @@
968
1035
  [PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
969
1036
  [PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
970
1037
  [ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
971
- [FORMFACTOR, itemListToArray(uach[CH_HEADER_FORM_FACTOR])],
1038
+ [FORMFACTORS, itemListToArray(uach[CH_HEADER_FORM_FACTORS])],
972
1039
  [BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
973
1040
  ]);
974
1041
  } else {
@@ -1088,15 +1155,15 @@
1088
1155
  this.set(TYPE, CONSOLE)
1089
1156
  .set(VENDOR, MICROSOFT);
1090
1157
  }
1091
- if (uaCH[FORMFACTOR]) {
1158
+ if (uaCH[FORMFACTORS]) {
1092
1159
  var ff;
1093
- if (typeof uaCH[FORMFACTOR] !== 'string') {
1160
+ if (typeof uaCH[FORMFACTORS] !== 'string') {
1094
1161
  var idx = 0;
1095
- while (!ff && idx < uaCH[FORMFACTOR].length) {
1096
- ff = strMapper(uaCH[FORMFACTOR][idx++], formFactorMap);
1162
+ while (!ff && idx < uaCH[FORMFACTORS].length) {
1163
+ ff = strMapper(uaCH[FORMFACTORS][idx++], formFactorsMap);
1097
1164
  }
1098
1165
  } else {
1099
- ff = strMapper(uaCH[FORMFACTOR], formFactorMap);
1166
+ ff = strMapper(uaCH[FORMFACTORS], formFactorsMap);
1100
1167
  }
1101
1168
  this.set(TYPE, ff);
1102
1169
  }
@@ -1147,7 +1214,7 @@
1147
1214
  function UAParser (ua, extensions, headers) {
1148
1215
 
1149
1216
  if (typeof ua === OBJ_TYPE) {
1150
- if (isExtensions(ua)) {
1217
+ if (isExtensions(ua, true)) {
1151
1218
  if (typeof extensions === OBJ_TYPE) {
1152
1219
  headers = extensions; // case UAParser(extensions, headers)
1153
1220
  }
@@ -1157,7 +1224,7 @@
1157
1224
  extensions = undefined;
1158
1225
  }
1159
1226
  ua = undefined;
1160
- } else if (typeof ua === STR_TYPE && !isExtensions(extensions)) {
1227
+ } else if (typeof ua === STR_TYPE && !isExtensions(extensions, true)) {
1161
1228
  headers = extensions; // case UAParser(ua, headers)
1162
1229
  extensions = undefined;
1163
1230
  }
@@ -1218,7 +1285,7 @@
1218
1285
  }
1219
1286
 
1220
1287
  UAParser.VERSION = LIBVERSION;
1221
- UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
1288
+ UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR, TYPE]);
1222
1289
  UAParser.CPU = enumerize([ARCHITECTURE]);
1223
1290
  UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
1224
1291
  UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);