1export function browserDetect(dotNetObjectRef) { 2 var parser = new UAParser(); 3 var result = parser.getResult(); 4 5 var gl = getGlRenderer(); 6 7 var isMobile = navigator.userAgent.toLowerCase().indexOf('mobile') > -1 ?? (isiOS()), 8 isTablet = navigator.userAgent.toLowerCase().indexOf('tablet') > -1 ?? (isiPadOS() || isiPadPro()), 9 isAndroid = navigator.userAgent.toLowerCase().indexOf('android') > -1, 10 isiPhone = isiOS(), 11 isiPad = isiPadOS() || isiPadPro(); 12 13 var agent = window.navigator.userAgent; 14 var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; 15 16 var deviceVendor = result.device.vendor ?? ''; 17 if (deviceVendor === '' && (isiPad || isiPhone || isiPadPro())) 18 deviceVendor = 'Apple Inc.'; 19 20 var deviceModel = result.device.model ?? ''; 21 var deviceType = result.device.type ?? ''; 22 23 if (deviceModel === 'iPad' || isiPad) { 24 deviceType = 'iPad'; 25 deviceModel = getModels().toString(); 26 } 27 else if (deviceModel === 'iPhone' || isiPhone) { 28 deviceType = 'iPhone'; 29 deviceModel = getModels().toString(); 30 } 31 32 var osName = parser.getOS().name; 33 var osVersion = parser.getOS().version; 34 35 var winVer = ''; 36 37 if (typeof navigator.userAgentData !== 'undefined') { 38 navigator.userAgentData.getHighEntropyValues(["platformVersion"]) 39 .then(ua => { 40 if (navigator.userAgentData.platform === "Windows") { 41 var majorPlatformVersion = parseInt(ua.platformVersion.split('.')[0]); 42 if (majorPlatformVersion >= 13) { 43 winVer = "11 or later"; 44 } 45 else { 46 switch (majorPlatformVersion) { 47 case 0: 48 winVer = "7/8/8.1"; 49 break; 50 case 1: 51 winVer = "10 (1507)"; 52 break; 53 case 2: 54 winVer = "10 (1511)"; 55 break; 56 case 3: 57 winVer = "10 (1607)"; 58 break; 59 case 4: 60 winVer = "10 (1703)"; 61 break; 62 case 5: 63 winVer = "10 (1709)"; 64 break; 65 case 6: 66 winVer = "10 (1803)"; 67 break; 68 case 7: 69 winVer = "10 (1809)"; 70 break; 71 case 8: 72 winVer = "10 (1903 or 10 1909)"; 73 break; 74 case 10: 75 winVer = "10 (2004 or 20H2 or 21H1 or 21H2)"; 76 break; 77 default: 78 break; 79 } 80 } 81 82 osVersion = winVer; 83 84 dotNetObjectRef.invokeMethodAsync('OSUpdateString', winVer).then(null, function (err) { 85 throw new Error(err); 86 }); 87 } 88 else if (navigator.userAgentData.platform === "macOS") { 89 var macVer = ua.platformVersion; 90 dotNetObjectRef.invokeMethodAsync('OSUpdateString', macVer).then(null, function (err) { 91 throw new Error(err); 92 }); 93 } 94 }); 95 96 navigator.userAgentData.getHighEntropyValues(["architecture", "bitness"]) 97 .then(ua => { 98 if (navigator.userAgentData.platform === "Windows") { 99 var winCPU = ''; 100 if (ua.architecture === 'x86') { 101 if (ua.bitness === '64') { 102 winCPU = "x86_64"; 103 } 104 else if (ua.bitness === '32') { 105 winCPU = "x86"; 106 } 107 } 108 else if (ua.architecture === 'arm') { 109 if (ua.bitness === '64') { 110 winCPU = "ARM64"; 111 } 112 else if (ua.bitness === '32') { 113 winCPU = "ARM32"; 114 } 115 } 116 117 dotNetObjectRef.invokeMethodAsync('OSArchitectureUpdateString', winCPU).then(null, function (err) { 118 throw new Error(err); 119 }); 120 } 121 else if (navigator.userAgentData.platform === "macOS") { 122 var macCPU = ua.architecture + ' ' + ua.bitness; 123 dotNetObjectRef.invokeMethodAsync('OSArchitectureUpdateString', macCPU).then(null, function (err) { 124 throw new Error(err); 125 }); 126 } 127 }); 128 } 129 130 var rtn = { 131 BrowserMajor: result.browser.major ?? '', 132 BrowserName: result.browser.name ?? '', 133 BrowserVersion: result.browser.version ?? '', 134 CPUArchitect: result.cpu.architecture ?? '', 135 DeviceModel: deviceModel, 136 DeviceType: deviceType, 137 DeviceVendor: deviceVendor, 138 EngineName: result.engine.name ?? '', 139 EngineVersion: result.engine.version ?? '',
140 GPURenderer: gl.glRenderer, 141 GPUVendor: gl.glVendor, 142 IsDesktop: isDesktop(), 143 IsMobile: isMobile ?? false, 144 IsTablet: isTablet ?? false, 145 IsAndroid: isAndroid ?? false, 146 IsIPhone: isiPhone ?? false, 147 IsIPad: isiPad ?? false, 148 isIpadPro: isiPadPro(), 149 OSName: osName, 150 OSVersion: osVersion, 151 ScreenResolution: (window.screen.width * window.devicePixelRatio) + 'x' + (window.screen.height * window.devicePixelRatio), 152 TimeZone: timeZone, 153 UserAgent: agent 154 }; 155 156 return rtn; 157} 158 159function isiOS() { 160 if (/iPhone|iPod/.test(navigator.platform)) { 161 return true; 162 } else { 163 return false; 164 } 165} 166 167function isiPadOS() { 168 if (/iPad/.test(navigator.platform)) { 169 return true; 170 } else { 171 return false; 172 } 173} 174 175function isiPadPro() { 176 var ratio = window.devicePixelRatio || 1; 177 var screen = { 178 width: window.screen.width * ratio, 179 height: window.screen.height * ratio 180 }; 181 182 return (screen.width === 2048 && screen.height === 2732) || 183 (screen.width === 2732 && screen.height === 2048) || 184 (screen.width === 1536 && screen.height === 2048) || 185 (screen.width === 2048 && screen.height === 1536); 186} 187 188function isDesktop() { 189 if ((navigator.userAgent.match(/iPhone/i)) || 190 (navigator.userAgent.match(/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|vodafone|o2|pocket|kindle|mobile|pda|psp|treo)/i)) || 191 (navigator.userAgent.match(/iPod/i)) || 192 (navigator.userAgent.match(/operamini/i)) || 193 (navigator.userAgent.match(/blackberry/i)) || 194 (navigator.userAgent.match(/(palmos|palm|hiptop|avantgo|plucker|xiino|blazer|elaine)/i)) || 195 (navigator.userAgent.match(/(windowsce; ppc;|windows ce;smartphone;|windows ce; iemobile) /i)) || 196 (navigator.userAgent.match(/android/i)) || isiOS() || isiPadOS() || isiPadPro()) { 197 return false; 198 } 199 else { 200 return true; 201 } 202} 203 204function OSVersion() { 205 var rtn = ""; 206 207 var userAgent = window.navigator.userAgent; 208 209 if (userAgent.indexOf("Windows NT 10.0") > 0) { 210 rtn = "Windows 10/11"; 211 } 212 else if (userAgent.indexOf("Windows NT 6.3") > 0) { 213 rtn = "Windows 8.1"; 214 } 215 else if (userAgent.indexOf("Windows NT 6.2") > 0) { 216 rtn = "Windows 8"; 217 } 218 else if (userAgent.indexOf("Windows NT 6.1") > 0) { 219 rtn = "Windows 7"; 220 } 221 else if (userAgent.indexOf("Windows NT 6.0") > 0) { 222 rtn = "Windows Vista"; 223 } 224 else if (userAgent.indexOf("Windows NT 5.2") > 0) { 225 rtn = "Windows Server 2003; Windows XP x64 Edition"; 226 } 227 else if (userAgent.indexOf("Windows NT 5.1") > 0) { 228 rtn = "Windows XP"; 229 } 230 else if (userAgent.indexOf("Windows NT 5.01") > 0) { 231 rtn = "Windows 2000, Service Pack 1 (SP1)"; 232 } 233 else if (userAgent.indexOf("Windows NT 5.0") > 0) { 234 rtn = "Windows 2000"; 235 } 236 else if (userAgent.indexOf("Windows NT 4.0") > 0) { 237 rtn = "Microsoft Windows NT 4.0"; 238 } 239 else if (userAgent.indexOf("Win 9x 4.90") > 0) { 240 rtn = "Windows Millennium Edition (Windows Me)"; 241 } 242 else if (userAgent.indexOf("Windows 98") > 0) { 243 rtn = "Windows 98"; 244 } 245 else if (userAgent.indexOf("Windows 95") > 0) { 246 rtn = "Windows 95"; 247 } 248 else if (userAgent.indexOf("Windows CE") > 0) { 249 rtn = "Windows CE"; 250 } 251 else if (userAgent.indexOf("iPhone OS") > 0) { 252 rtn = "iPhone OS"; 253 } 254 else if (userAgent.indexOf("Mac OS") > 0) { 255 rtn = "Max OS"; 256 } 257 else if (userAgent.indexOf("Android") > 0) { 258 rtn = "Android"; 259 } 260 else if (userAgent.indexOf("Silk") > 0) { 261 rtn = "Amazon Fire"; 262 } 263 else if (userAgent.indexOf("facebook") > 0) { 264 rtn = "Facebook External Hit"; 265 } 266 else if (userAgent.indexOf("Twitterbot") > 0) { 267 rtn = "Twitterbot"; 268 } 269 else if (userAgent.indexOf("WhatsApp") > 0) { 270 rtn = "WhatsApp"; 271 } 272 else { 273 //Others 274 } 275 276 return rtn; 277} 278 279var canvas, gl, glRenderer, models, 280 devices = [ 281 ['a7', '640x1136', ['iPhone 5', 'iPhone 5s']], 282 ['a7', '1536x2048', ['iPad Air', 'iPad Mini 2', 'iPad Mini 3', 'iPad Pro 9.7']], 283 ['a8', '640x1136', ['iPod touch (6th gen)']], 284 ['a8', '750x1334', ['iPhone 6']], 285 ['a8', '1242x2208', ['iPhone 6 Plus']], 286 ['a8', '1536x2048', ['iPad Air 2', 'iPad Mini 4']], 287 ['a9', '640x1136', ['iPhone SE']], 288 ['a9', '750x1334', ['iPhone 6s']],
289 ['a9', '1242x2208', ['iPhone 6s Plus']], 290 ['a9x', '1536x2048', ['iPad Pro (1st gen 9.7-inch)']], 291 ['a9x', '2048x2732', ['iPad Pro (1st gen 12.9-inch)']], 292 ['a10', '750x1334', ['iPhone 7']], 293 ['a10', '1242x2208', ['iPhone 7 Plus']], 294 ['a10x', '1668x2224', ['iPad Pro (2th gen 10.5-inch)']], 295 ['a10x', '2048x2732', ['iPad Pro (2th gen 12.9-inch)']], 296 ['a11', '750x1334', ['iPhone 8']], 297 ['a11', '1242x2208', ['iPhone 8 Plus']], 298 ['a11', '1125x2436', ['iPhone X']], 299 ['a12', '828x1792', ['iPhone Xr']], 300 ['a12', '1125x2436', ['iPhone Xs']], 301 ['a12', '1242x2688', ['iPhone Xs Max']], 302 ['a12x', '1668x2388', ['iPad Pro (3rd gen 11-inch)']], 303 ['a12x', '2048x2732', ['iPad Pro (3rd gen 12.9-inch)']], 304 ['a15', '2556x1179', ['iPhone 14']], 305 ['a15', '2796x1290', ['iPhone 14 Max']] 306 ]; 307 308function getCanvas() { 309 if (canvas == null) { 310 canvas = document.createElement('canvas'); 311 } 312 313 return canvas; 314} 315 316function getGl() { 317 if (gl == null) { 318 gl = getCanvas().getContext('webgl'); 319 } 320 321 return gl; 322} 323 324function getResolution() { 325 var ratio = window.devicePixelRatio || 1; 326 return (Math.min(screen.width, screen.height) * ratio) 327 + 'x' + (Math.max(screen.width, screen.height) * ratio); 328} 329 330function getGlRenderer() { 331 var glVendor = 'Unknown'; 332 333 if (glRenderer == null) { 334 const gl = document.createElement("canvas").getContext("webgl"); 335 // try to get the extensions 336 const ext = gl.getExtension("WEBGL_debug_renderer_info"); 337 338 // if the extension exists, find out the info. 339 if (ext) { 340 glRenderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL); 341 glVendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL); 342 } 343 else { 344 glRenderer = "Unknown"; 345 } 346 } 347 348 return { glRenderer, glVendor }; 349} 350 351function getModels() { 352 if (models === undefined) { 353 var gpu = getGlRenderer(); 354 var matches = gpu.glRenderer.toLowerCase().includes('apple'); 355 var res = getResolution(); 356 357 models = ['unknown']; 358 359 if (matches) { 360 for (var i = 0; i < devices.length; i++) { 361 var device = devices[i]; 362 363 var res2 = res.split('x').reverse().join('x'); 364 if (res == device[1] || res2 == device[1]) { 365 models = device[2]; 366 break; 367 } 368 } 369 } 370 } 371 372 return models; 373} 374 375function getDeviceInfo() { 376 if (window.MobileDevice == undefined) { 377 window.MobileDevice = {}; 378 } 379 380 window.MobileDevice.getGlRenderer = getGlRenderer; 381 window.MobileDevice.getModels = getModels; 382 window.MobileDevice.getResolution = getResolution; 383 384 var currentModels = getModels(); 385 //var match = match.toLowerCase().replace(/\s+$/, '') + ' '; 386 387 for (var i = 0; i < currentModels.length; i++) { 388 var model = currentModels[i].toLowerCase() + ' '; 389 390 if (0 === model.indexOf(math)) { 391 return true; 392 } 393 } 394} 395 396(function (window, undefined) { 397 'use strict'; 398 399 ////////////// 400 // Constants 401 ///////////// 402 403 var LIBVERSION = '0.7.31', 404 EMPTY = '', 405 UNKNOWN = '?', 406 FUNC_TYPE = 'function', 407 UNDEF_TYPE = 'undefined', 408 OBJ_TYPE = 'object', 409 STR_TYPE = 'string', 410 MAJOR = 'major', 411 MODEL = 'model', 412 NAME = 'name', 413 TYPE = 'type', 414 VENDOR = 'vendor', 415 VERSION = 'version', 416 ARCHITECTURE = 'architecture', 417 CONSOLE = 'console', 418 MOBILE = 'mobile', 419 TABLET = 'tablet', 420 SMARTTV = 'smarttv', 421 WEARABLE = 'wearable', 422 EMBEDDED = 'embedded', 423 UA_MAX_LENGTH = 275; 424 425 var AMAZON = 'Amazon', 426 APPLE = 'Apple', 427 ASUS = 'ASUS', 428 BLACKBERRY = 'BlackBerry', 429 BROWSER = 'Browser', 430 CHROME = 'Chrome', 431 EDGE = 'Edge', 432 FIREFOX = 'Firefox', 433 GOOGLE = 'Google', 434 HUAWEI = 'Huawei', 435 LG = 'LG', 436 MICROSOFT = 'Microsoft', 437 MOTOROLA = 'Motorola', 438 OPERA = 'Opera', 439 SAMSUNG = 'Samsung', 440 SONY = 'Sony', 441 XIAOMI = 'Xiaomi', 442 ZEBRA = 'Zebra', 443 FACEBOOK = 'Facebook'; 444
445 /////////// 446 // Helper 447 ////////// 448 449 var extend = function (regexes, extensions) { 450 var mergedRegexes = {}; 451 for (var i in regexes) { 452 if (extensions[i] && extensions[i].length % 2 === 0) { 453 mergedRegexes[i] = extensions[i].concat(regexes[i]); 454 } else { 455 mergedRegexes[i] = regexes[i]; 456 } 457 } 458 return mergedRegexes; 459 }, 460 enumerize = function (arr) { 461 var enums = {}; 462 for (var i = 0; i < arr.length; i++) { 463 enums[arr[i].toUpperCase()] = arr[i]; 464 } 465 return enums; 466 }, 467 has = function (str1, str2) { 468 return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; 469 }, 470 lowerize = function (str) { 471 return str.toLowerCase(); 472 }, 473 majorize = function (version) { 474 return typeof (version) === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split('.')[0] : undefined; 475 }, 476 trim = function (str, len) { 477 if (typeof (str) === STR_TYPE) { 478 str = str.replace(/^\s\s*/, EMPTY).replace(/\s\s*$/, EMPTY); 479 return typeof (len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); 480 } 481 }; 482 483 /////////////// 484 // Map helper 485 ////////////// 486 487 var rgxMapper = function (ua, arrays) { 488 489 var i = 0, j, k, p, q, matches, match; 490 491 // loop through all regexes maps 492 while (i < arrays.length && !matches) { 493 494 var regex = arrays[i], // even sequence (0,2,4,..) 495 props = arrays[i + 1]; // odd sequence (1,3,5,..) 496 j = k = 0; 497 498 // try matching uastring with regexes 499 while (j < regex.length && !matches) { 500 501 matches = regex[j++].exec(ua); 502 503 if (!!matches) { 504 for (p = 0; p < props.length; p++) { 505 match = matches[++k]; 506 q = props[p]; 507 // check if given property is actually array 508 if (typeof q === OBJ_TYPE && q.length > 0) { 509 if (q.length === 2) { 510 if (typeof q[1] == FUNC_TYPE) { 511 // assign modified match 512 this[q[0]] = q[1].call(this, match); 513 } else { 514 // assign given value, ignore regex match 515 this[q[0]] = q[1]; 516 } 517 } else if (q.length === 3) { 518 // check whether function or regex 519 if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { 520 // call function (usually string mapper) 521 this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined; 522 } else { 523 // sanitize match using given regex 524 this[q[0]] = match ? match.replace(q[1], q[2]) : undefined; 525 } 526 } else if (q.length === 4) { 527 this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined; 528 } 529 } else { 530 this[q] = match ? match : undefined; 531 } 532 } 533 } 534 } 535 i += 2; 536 } 537 }, 538 539 strMapper = function (str, map) { 540 541 for (var i in map) { 542 // check if current value is array 543 if (typeof map[i] === OBJ_TYPE && map[i].length > 0) { 544 for (var j = 0; j < map[i].length; j++) { 545 if (has(map[i][j], str)) { 546 return (i === UNKNOWN) ? undefined : i; 547 } 548 } 549 } else if (has(map[i], str)) { 550 return (i === UNKNOWN) ? undefined : i; 551 } 552 } 553 return str; 554 }; 555
vendor: 4,091 bytes, lines 556-637
556 /////////////// 557 // String map 558 ////////////// 559 560 // Safari < 3.0 561 var oldSafariMap = { 562 '1.0': '/8', 563 '1.2': '/1', 564 '1.3': '/3', 565 '2.0': '/412', 566 '2.0.2': '/416', 567 '2.0.3': '/417', 568 '2.0.4': '/419', 569 '?': '/' 570 }, 571 windowsVersionMap = { 572 'ME': '4.90', 573 'NT 3.11': 'NT3.51', 574 'NT 4.0': 'NT4.0', 575 '2000': 'NT 5.0', 576 'XP': ['NT 5.1', 'NT 5.2'], 577 'Vista': 'NT 6.0', 578 '7': 'NT 6.1', 579 '8': 'NT 6.2', 580 '8.1': 'NT 6.3', 581 '10': ['NT 6.4', 'NT 10.0'], 582 'RT': 'ARM' 583 }; 584 585 ////////////// 586 // Regex map 587 ///////////// 588 589 var regexes = { 590 591 browser: [[ 592 593 /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS 594 ], [VERSION, [NAME, 'Chrome']], [ 595 /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge 596 ], [VERSION, [NAME, 'Edge']], [ 597 598 // Presto based 599 /(opera mini)\/([-\w\.]+)/i, // Opera Mini 600 /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet 601 /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera 602 ], [NAME, VERSION], [ 603 /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 604 ], [VERSION, [NAME, OPERA + ' Mini']], [ 605 /\bopr\/([\w\.]+)/i // Opera Webkit 606 ], [VERSION, [NAME, OPERA]], [ 607 608 // Mixed 609 /(kindle)\/([\w\.]+)/i, // Kindle 610 /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer 611 // Trident based 612 /(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser 613 /(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser 614 /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer 615 616 // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon 617 /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([-\w\.]+)/i, 618 // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ 619 /(weibo)__([\d\.]+)/i // Weibo 620 ], [NAME, VERSION], [ 621 /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser 622 ], [VERSION, [NAME, 'UC' + BROWSER]], [ 623 /\bqbcore\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser 624 ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [ 625 /micromessenger\/([\w\.]+)/i // WeChat 626 ], [VERSION, [NAME, 'WeChat']], [ 627 /konqueror\/([\w\.]+)/i // Konqueror 628 ], [VERSION, [NAME, 'Konqueror']], [ 629 /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11 630 ], [VERSION, [NAME, 'IE']], [ 631 /yabrowser\/([\w\.]+)/i // Yandex 632 ], [VERSION, [NAME, 'Yandex']], [ 633 /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser 634 ], [[NAME, /(.+)/, '$1 Secure ' + BROWSER], VERSION], [ 635 /\bfocus\/([\w\.]+)/i // Firefox Focus 636 ], [VERSION, [NAME, FIREFOX + ' Focus']], [ 637 /\bopt\/([\w\.]+)/i // Opera Touch
vendor: 4,336 bytes, lines 638-704
638 ], [VERSION, [NAME, OPERA + ' Touch']], [ 639 /coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser 640 ], [VERSION, [NAME, 'Coc Coc']], [ 641 /dolfin\/([\w\.]+)/i // Dolphin 642 ], [VERSION, [NAME, 'Dolphin']], [ 643 /coast\/([\w\.]+)/i // Opera Coast 644 ], [VERSION, [NAME, OPERA + ' Coast']], [ 645 /miuibrowser\/([\w\.]+)/i // MIUI Browser 646 ], [VERSION, [NAME, 'MIUI ' + BROWSER]], [ 647 /fxios\/([-\w\.]+)/i // Firefox for iOS 648 ], [VERSION, [NAME, FIREFOX]], [ 649 /\bqihu|(qi?ho?o?|360)browser/i // 360 650 ], [[NAME, '360 ' + BROWSER]], [ 651 /(oculus|samsung|sailfish)browser\/([\w\.]+)/i 652 ], [[NAME, /(.+)/, '$1 ' + BROWSER], VERSION], [ // Oculus/Samsung/Sailfish Browser 653 /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon 654 ], [[NAME, /_/g, ' '], VERSION], [ 655 /(electron)\/([\w\.]+) safari/i, // Electron-based App 656 /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla 657 /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser 658 ], [NAME, VERSION], [ 659 /(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser 660 /(lbbrowser)/i // LieBao Browser 661 ], [NAME], [ 662 663 // WebView 664 /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android 665 ], [[NAME, FACEBOOK], VERSION], [ 666 /safari (line)\/([\w\.]+)/i, // Line App for iOS 667 /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android 668 /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram 669 ], [NAME, VERSION], [ 670 /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS 671 ], [VERSION, [NAME, 'GSA']], [ 672 673 /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless 674 ], [VERSION, [NAME, CHROME + ' Headless']], [ 675 676 / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView 677 ], [[NAME, CHROME + ' WebView'], VERSION], [ 678 679 /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser 680 ], [VERSION, [NAME, 'Android ' + BROWSER]], [ 681 682 /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia 683 ], [NAME, VERSION], [ 684 685 /version\/([\w\.]+) .*mobile\/\w+ (safari)/i // Mobile Safari 686 ], [VERSION, [NAME, 'Mobile Safari']], [ 687 /version\/([\w\.]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile 688 ], [VERSION, NAME], [ 689 /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 690 ], [NAME, [VERSION, strMapper, oldSafariMap]], [ 691 692 /(webkit|khtml)\/([\w\.]+)/i 693 ], [NAME, VERSION], [ 694 695 // Gecko based 696 /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape 697 ], [[NAME, 'Netscape'], VERSION], [ 698 /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality 699 ], [VERSION, [NAME, FIREFOX + ' Reality']], [ 700 /ekiohf.+(flow)\/([\w\.]+)/i, // Flow 701 /(swiftfox)/i, // Swiftfox 702 /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i, 703 // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar 704 /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
705 // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix 706 /(firefox)\/([\w\.]+)/i, // Other Firefox-based 707 /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla 708 709 // Other 710 /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, 711 // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser 712 /(links) \(([\w\.]+)/i // Links 713 ], [NAME, VERSION] 714 ], 715 716 cpu: [[ 717 718 /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i // AMD64 (x64) 719 ], [[ARCHITECTURE, 'amd64']], [ 720 721 /(ia32(?=;))/i // IA32 (quicktime) 722 ], [[ARCHITECTURE, lowerize]], [ 723 724 /((?:i[346]|x)86)[;\)]/i // IA32 (x86) 725 ], [[ARCHITECTURE, 'ia32']], [ 726 727 /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 728 ], [[ARCHITECTURE, 'arm64']], [ 729 730 /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF 731 ], [[ARCHITECTURE, 'armhf']], [ 732 733 // PocketPC mistakenly identified as PowerPC 734 /windows (ce|mobile); ppc;/i 735 ], [[ARCHITECTURE, 'arm']], [ 736 737 /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC 738 ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ 739 740 /(sun4\w)[;\)]/i // SPARC 741 ], [[ARCHITECTURE, 'sparc']], [ 742 743 /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i 744 // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC 745 ], [[ARCHITECTURE, lowerize]] 746 ], 747 748 device: [[ 749
vendor: 20,329 bytes, lines 750-1110
750 ////////////////////////// 751 // MOBILES & TABLETS 752 // Ordered by popularity 753 ///////////////////////// 754 755 // Samsung 756 /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i 757 ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ 758 /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i, 759 /samsung[- ]([-\w]+)/i, 760 /sec-(sgh\w+)/i 761 ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ 762 763 // Apple 764 /\((ip(?:hone|od)[\w ]*);/i // iPod/iPhone 765 ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ 766 /\((ipad);[-\w\),; ]+apple/i, // iPad 767 /applecoremedia\/[\w\.]+ \((ipad)/i, 768 /\b(ipad)\d\d?,\d\d?[;\]].+ios/i 769 ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ 770 771 // Huawei 772 /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i 773 ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ 774 /(?:huawei|honor)([-\w ]+)[;\)]/i, 775 /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i 776 ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ 777 778 // Xiaomi 779 /\b(poco[\w ]+)(?: bui|\))/i, // Xiaomi POCO 780 /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models 781 /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi 782 /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi 783 /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi 784 ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ 785 /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets 786 ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [ 787 788 // OPPO 789 /; (\w+) bui.+ oppo/i, 790 /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i 791 ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ 792 793 // Vivo 794 /vivo (\w+)(?: bui|\))/i, 795 /\b(v[12]\d{3}\w?[at])(?: bui|;)/i 796 ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [ 797 798 // Realme 799 /\b(rmx[12]\d{3})(?: bui|;|\))/i 800 ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [ 801 802 // Motorola 803 /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, 804 /\bmot(?:orola)?[- ](\w*)/i, 805 /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i 806 ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ 807 /\b(mz60\d|xoom[2 ]{0,2}) build\//i 808 ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ 809 810 // LG 811 /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i 812 ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ 813 /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, 814 /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, 815 /\blg-?([\d\w]+) bui/i 816 ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ 817 818 // Lenovo 819 /(ideatab[-\w ]+)/i, 820 /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i 821 ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ 822 823 // Nokia 824 /(?:maemo|nokia).*(n900|lumia \d+)/i, 825 /nokia[-_ ]?([-\w\.]*)/i 826 ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [ 827 828 // Google 829 /(pixel c)\b/i // Google Pixel C 830 ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ 831 /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel 832 ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ 833 834 // Sony 835 /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i 836 ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ 837 /sony tablet [ps]/i, 838 /\b(?:sony)?sgp\w+(?: bui|\))/i 839 ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [ 840 841 // OnePlus 842 / (kb2005|in20[12]5|be20[12][59])\b/i, 843 /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i 844 ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [ 845 846 // Amazon 847 /(alexa)webm/i, 848 /(kf[a-z]{2}wi)( bui|\))/i, // Kindle Fire without Silk 849 /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD 850 ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [ 851 /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone 852 ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [ 853 854 // BlackBerry 855 /(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook 856 ], [MODEL, VENDOR, [TYPE, TABLET]], [ 857 /\b((?:bb[a-f]|st[hv])100-\d)/i, 858 /\(bb10; (\w+)/i // BlackBerry 10 859 ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [ 860 861 // Asus 862 /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i 863 ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [ 864 / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i 865 ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ 866 867 // HTC 868 /(nexus 9)/i // HTC Nexus 9 869 ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ 870 /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC 871 872 // ZTE 873 /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, 874 /(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony 875 ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ 876 877 // Acer 878 /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i 879 ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [ 880 881 // Meizu 882 /droid.+; (m[1-5] note) bui/i, 883 /\bmz-([-\w]{2,})/i 884 ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [ 885 886 // Sharp 887 /\b(sh-?[altvz]?\d\d[a-ekm]?)/i 888 ], [MODEL, [VENDOR, 'Sharp'], [TYPE, MOBILE]], [ 889 890 // MIXED 891 /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i, 892 // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron 893 /(hp) ([\w ]+\w)/i, // HP iPAQ 894 /(asus)-?(\w+)/i, // Asus 895 /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia 896 /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo 897 /(jolla)/i, // Jolla 898 /(oppo) ?([\w ]+) bui/i // OPPO 899 ], [VENDOR, MODEL, [TYPE, MOBILE]], [ 900 901 /(archos) (gamepad2?)/i, // Archos 902 /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad 903 /(kindle)\/([\w\.]+)/i, // Kindle 904 /(nook)[\w ]+build\/(\w+)/i, // Nook 905 /(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak 906 /(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets 907 /(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets 908 /(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets 909 /(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone 910 ], [VENDOR, MODEL, [TYPE, TABLET]], [ 911 912 /(surface duo)/i // Surface Duo 913 ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ 914 /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone 915 ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [ 916 /(u304aa)/i // AT&T 917 ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [ 918 /\bsie-(\w*)/i // Siemens 919 ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ 920 /\b(rct\w+) b/i // RCA Tablets 921 ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [ 922 /\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets 923 ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [ 924 /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet 925 ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [ 926 /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet 927 ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [ 928 /\b(tm\d{3}\w+) b/i 929 ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [ 930 /\b(k88) b/i // ZTE K Series Tablet 931 ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [ 932 /\b(nx\d{3}j) b/i // ZTE Nubia 933 ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ 934 /\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile 935 ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [ 936 /\b(zur\d{3}) b/i // Swiss ZUR Tablet 937 ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [ 938 /\b((zeki)?tb.*\b) b/i // Zeki Tablets 939 ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [ 940 /\b([yr]\d{2}) b/i, 941 /\b(dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet 942 ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [ 943 /\b(ns-?\w{0,9}) b/i // Insignia Tablets 944 ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [ 945 /\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets 946 ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [ 947 /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones 948 ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ 949 /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones 950 ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [ 951 /\b(ph-1) /i // Essential PH-1 952 ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ 953 /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets 954 ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [ 955 /\b(trio[-\w\. ]+) b/i // MachSpeed Tablets 956 ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [ 957 /\btu_(1491) b/i // Rotor Tablets 958 ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [ 959 /(shield[\w ]+) b/i // Nvidia Shield Tablets 960 ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [ 961 /(sprint) (\w+)/i // Sprint Phones 962 ], [VENDOR, MODEL, [TYPE, MOBILE]], [ 963 /(kin\.[onetw]{3})/i // Microsoft Kin 964 ], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [ 965 /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra 966 ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [ 967 /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i 968 ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [ 969 970 /////////////////// 971 // CONSOLES 972 /////////////////// 973 974 /(ouya)/i, // Ouya 975 /(nintendo) ([wids3utch]+)/i // Nintendo 976 ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ 977 /droid.+; (shield) bui/i // Nvidia 978 ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ 979 /(playstation [345portablevi]+)/i // Playstation 980 ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ 981 /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox 982 ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [ 983 984 /////////////////// 985 // SMARTTVS 986 /////////////////// 987 988 /smart-tv.+(samsung)/i // Samsung 989 ], [VENDOR, [TYPE, SMARTTV]], [ 990 /hbbtv.+maple;(\d+)/i 991 ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ 992 /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV 993 ], [[VENDOR, LG], [TYPE, SMARTTV]], [ 994 /(apple) ?tv/i // Apple TV 995 ], [VENDOR, [MODEL, APPLE + ' TV'], [TYPE, SMARTTV]], [ 996 /crkey/i // Google Chromecast 997 ], [[MODEL, CHROME + 'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ 998 /droid.+aft(\w)( bui|\))/i // Fire TV 999 ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ 1000 /\(dtv[\);].+(aquos)/i // Sharp 1001 ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ 1002 /(bravia[\w- ]+) bui/i // Sony 1003 ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ 1004 /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku 1005 /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices 1006 ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ 1007 /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors 1008 ], [[TYPE, SMARTTV]], [ 1009 1010 /////////////////// 1011 // WEARABLES 1012 /////////////////// 1013 1014 /((pebble))app/i // Pebble 1015 ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ 1016 /droid.+; (glass) \d/i // Google Glass 1017 ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ 1018 /droid.+; (wt63?0{2,3})\)/i 1019 ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ 1020 /(quest( 2)?)/i // Oculus Quest 1021 ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ 1022 1023 /////////////////// 1024 // EMBEDDED 1025 /////////////////// 1026 1027 /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla 1028 ], [VENDOR, [TYPE, EMBEDDED]], [ 1029 1030 //////////////////// 1031 // MIXED (GENERIC) 1032 /////////////////// 1033 1034 /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors 1035 ], [MODEL, [TYPE, MOBILE]], [ 1036 /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors 1037 ], [MODEL, [TYPE, TABLET]], [ 1038 /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet 1039 ], [[TYPE, TABLET]], [ 1040 /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile 1041 ], [[TYPE, MOBILE]], [ 1042 /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device 1043 ], [MODEL, [VENDOR, 'Generic']] 1044 ], 1045 1046 engine: [[ 1047 1048 /windows.+ edge\/([\w\.]+)/i // EdgeHTML 1049 ], [VERSION, [NAME, EDGE + 'HTML']], [ 1050 1051 /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink 1052 ], [VERSION, [NAME, 'Blink']], [ 1053 1054 /(presto)\/([\w\.]+)/i, // Presto 1055 /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna 1056 /ekioh(flow)\/([\w\.]+)/i, // Flow 1057 /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links 1058 /(icab)[\/ ]([23]\.[\d\.]+)/i // iCab 1059 ], [NAME, VERSION], [ 1060 1061 /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko 1062 ], [VERSION, NAME] 1063 ], 1064 1065 os: [[ 1066 1067 // Windows 1068 /microsoft (windows) (vista|xp)/i // Windows (iTunes) 1069 ], [NAME, VERSION], [ 1070 /(windows) nt 6\.2; (arm)/i, // Windows RT 1071 /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone 1072 /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i 1073 ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ 1074 /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i 1075 ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [ 1076 1077 // iOS/macOS 1078 /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS 1079 /cfnetwork\/.+darwin/i 1080 ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [ 1081 /(mac os x) ?([\w\. ]*)/i, 1082 /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS 1083 ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ 1084 1085 // Mobile OSes 1086 /droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86 1087 ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS 1088 /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, 1089 /(blackberry)\w*\/([\w\.]*)/i, // Blackberry 1090 /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS 1091 /\((series40);/i // Series 40 1092 ], [NAME, VERSION], [ 1093 /\(bb(10);/i // BlackBerry 10 1094 ], [VERSION, [NAME, BLACKBERRY]], [ 1095 /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian 1096 ], [VERSION, [NAME, 'Symbian']], [ 1097 /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS 1098 ], [VERSION, [NAME, FIREFOX + ' OS']], [ 1099 /web0s;.+rt(tv)/i, 1100 /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS 1101 ], [VERSION, [NAME, 'webOS']], [ 1102 1103 // Google Chromecast 1104 /crkey\/([\d\.]+)/i // Google Chromecast 1105 ], [VERSION, [NAME, CHROME + 'cast']], [ 1106 /(cros) [\w]+ ([\w\.]+\w)/i // Chromium OS 1107 ], [[NAME, 'Chromium OS'], VERSION], [ 1108 1109 // Console 1110 /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo
1110/Playstation 1111 /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) 1112 1113 // Other 1114 /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm 1115 /(mint)[\/\(\) ]?(\w*)/i, // Mint 1116 /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux 1117 /([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, 1118 // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire 1119 /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux 1120 /(gnu) ?([\w\.]*)/i, // GNU 1121 /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly 1122 /(haiku) (\w+)/i // Haiku 1123 ], [NAME, VERSION], [ 1124 /(sunos) ?([\w\.\d]*)/i // Solaris 1125 ], [[NAME, 'Solaris'], VERSION], [ 1126 /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris 1127 /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX 1128 /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX 1129 /(unix) ?([\w\.]*)/i // UNIX 1130 ], [NAME, VERSION] 1131 ] 1132 }; 1133 1134 ///////////////// 1135 // Constructor 1136 //////////////// 1137 1138 var UAParser = function (ua, extensions) { 1139 1140 if (typeof ua === OBJ_TYPE) { 1141 extensions = ua; 1142 ua = undefined; 1143 } 1144 1145 if (!(this instanceof UAParser)) { 1146 return new UAParser(ua, extensions).getResult(); 1147 } 1148 1149 var _ua = ua || ((typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); 1150 var _rgxmap = extensions ? extend(regexes, extensions) : regexes; 1151 1152 this.getBrowser = function () { 1153 var _browser = {}; 1154 _browser[NAME] = undefined; 1155 _browser[VERSION] = undefined; 1156 rgxMapper.call(_browser, _ua, _rgxmap.browser); 1157 _browser.major = majorize(_browser.version); 1158 return _browser; 1159 }; 1160 this.getCPU = function () { 1161 var _cpu = {}; 1162 _cpu[ARCHITECTURE] = undefined; 1163 rgxMapper.call(_cpu, _ua, _rgxmap.cpu); 1164 return _cpu; 1165 }; 1166 this.getDevice = function () { 1167 var _device = {}; 1168 _device[VENDOR] = undefined; 1169 _device[MODEL] = undefined; 1170 _device[TYPE] = undefined; 1171 rgxMapper.call(_device, _ua, _rgxmap.device); 1172 return _device; 1173 }; 1174 this.getEngine = function () { 1175 var _engine = {}; 1176 _engine[NAME] = undefined; 1177 _engine[VERSION] = undefined; 1178 rgxMapper.call(_engine, _ua, _rgxmap.engine); 1179 return _engine; 1180 }; 1181 this.getOS = function () { 1182 var _os = {}; 1183 _os[NAME] = undefined; 1184 _os[VERSION] = undefined; 1185 rgxMapper.call(_os, _ua, _rgxmap.os); 1186 return _os; 1187 }; 1188 this.getResult = function () { 1189 return { 1190 ua: this.getUA(), 1191 browser: this.getBrowser(), 1192 engine: this.getEngine(), 1193 os: this.getOS(), 1194 device: this.getDevice(), 1195 cpu: this.getCPU() 1196 }; 1197 }; 1198 this.getUA = function () { 1199 return _ua; 1200 }; 1201 this.setUA = function (ua) { 1202 _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua; 1203 return this; 1204 }; 1205 this.setUA(_ua); 1206 return this; 1207 }; 1208 1209 UAParser.VERSION = LIBVERSION; 1210 UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]); 1211 UAParser.CPU = enumerize([ARCHITECTURE]); 1212 UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
1213 UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]); 1214 1215 /////////// 1216 // Export 1217 ////////// 1218 1219 // check js environment 1220 if (typeof (exports) !== UNDEF_TYPE) { 1221 // nodejs env 1222 if (typeof module !== UNDEF_TYPE && module.exports) { 1223 exports = module.exports = UAParser; 1224 } 1225 exports.UAParser = UAParser; 1226 } else { 1227 // requirejs env (optional) 1228 if (typeof (define) === FUNC_TYPE && define.amd) { 1229 define(function () { 1230 return UAParser; 1231 }); 1232 } else if (typeof window !== UNDEF_TYPE) { 1233 // browser env 1234 window.UAParser = UAParser; 1235 } 1236 } 1237 1238 // jQuery/Zepto specific (optional) 1239 // Note: 1240 // In AMD env the global scope should be kept clean, but jQuery is an exception. 1241 // jQuery always exports to global scope, unless jQuery.noConflict(true) is used, 1242 // and we should catch that. 1243 var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto); 1244 if ($ && !$.ua) { 1245 var parser = new UAParser(); 1246 $.ua = parser.getResult(); 1247 $.ua.get = function () { 1248 return parser.getUA(); 1249 }; 1250 $.ua.set = function (ua) { 1251 parser.setUA(ua); 1252 var result = parser.getResult(); 1253 for (var prop in result) { 1254 $.ua[prop] = result[prop]; 1255 } 1256 }; 1257 } 1258 1259})(typeof window === 'object' ? window : this);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.