1/** 2 * UAParser.js v0.7.9 3 * Lightweight JavaScript-based User-Agent string parser 4 * https://github.com/faisalman/ua-parser-js 5 * 6 * Copyright © 2012-2015 Faisal Salman <[email protected]> 7 * Dual licensed under GPLv2 & MIT 8 */ 9 10(function (window, undefined) { 11 12 'use strict'; 13 14 ////////////// 15 // Constants 16 ///////////// 17 18 19 var LIBVERSION = '0.7.9', 20 EMPTY = '', 21 UNKNOWN = '?', 22 FUNC_TYPE = 'function', 23 UNDEF_TYPE = 'undefined', 24 OBJ_TYPE = 'object', 25 STR_TYPE = 'string', 26 MAJOR = 'major', // deprecated 27 MODEL = 'model', 28 NAME = 'name', 29 TYPE = 'type', 30 VENDOR = 'vendor', 31 VERSION = 'version', 32 ARCHITECTURE= 'architecture', 33 CONSOLE = 'console', 34 MOBILE = 'mobile', 35 TABLET = 'tablet', 36 SMARTTV = 'smarttv', 37 WEARABLE = 'wearable', 38 EMBEDDED = 'embedded'; 39 40 41 /////////// 42 // Helper 43 ////////// 44 45 46 var util = { 47 extend : function (regexes, extensions) { 48 for (var i in extensions) { 49 if ("browser cpu device engine os".indexOf(i) !== -1 && extensions[i].length % 2 === 0) { 50 regexes[i] = extensions[i].concat(regexes[i]); 51 } 52 } 53 return regexes; 54 }, 55 has : function (str1, str2) { 56 if (typeof str1 === "string") { 57 return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1; 58 } else { 59 return false; 60 } 61 }, 62 lowerize : function (str) { 63 return str.toLowerCase(); 64 }, 65 major : function (version) { 66 return typeof(version) === STR_TYPE ? version.split(".")[0] : undefined; 67 } 68 }; 69 70 71 /////////////// 72 // Map helper 73 ////////////// 74 75 76 var mapper = { 77 78 rgx : function () { 79 80 var result, i = 0, j, k, p, q, matches, match, args = arguments; 81 82 // loop through all regexes maps 83 while (i < args.length && !matches) { 84 85 var regex = args[i], // even sequence (0,2,4,..) 86 props = args[i + 1]; // odd sequence (1,3,5,..) 87 88 // construct object barebones 89 if (typeof result === UNDEF_TYPE) { 90 result = {}; 91 for (p in props) { 92 q = props[p]; 93 if (typeof q === OBJ_TYPE) { 94 result[q[0]] = undefined; 95 } else { 96 result[q] = undefined; 97 } 98 } 99 } 100 101 // try matching uastring with regexes 102 j = k = 0; 103 while (j < regex.length && !matches) { 104 matches = regex[j++].exec(this.getUA()); 105 if (!!matches) { 106 for (p = 0; p < props.length; p++) { 107 match = matches[++k]; 108 q = props[p]; 109 // check if given property is actually array 110 if (typeof q === OBJ_TYPE && q.length > 0) { 111 if (q.length == 2) { 112 if (typeof q[1] == FUNC_TYPE) { 113 // assign modified match 114 result[q[0]] = q[1].call(this, match); 115 } else { 116 // assign given value, ignore regex match 117 result[q[0]] = q[1]; 118 } 119 } else if (q.length == 3) { 120 // check whether function or regex 121 if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { 122 // call function (usually string mapper) 123 result[q[0]] = match ? q[1].call(this, match, q[2]) : undefined; 124 } else { 125 // sanitize match using given regex 126 result[q[0]] = match ? match.replace(q[1], q[2]) : undefined; 127 } 128 } else if (q.length == 4) { 129 result[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined; 130 } 131 } else { 132 result[q] = match ? match : undefined; 133 } 134 } 135 } 136 } 137 i += 2; 138 } 139 return result; 140 }, 141 142 str : function (str, map) { 143 144 for (var i in map) { 145 // check if array 146 if (typeof map[i] === OBJ_TYPE && map[i].length > 0) { 147 for (var j = 0; j < map[i].length; j++) { 148 if (util.has(map[i][j], str)) { 149 return (i === UNKNOWN) ? undefined : i; 150 } 151 } 152 } else if (util.has(map[i], str)) { 153 return (i === UNKNOWN) ? undefined : i; 154 } 155 } 156 return str; 157 } 158 }; 159 160
vendor: 5,632 bytes, lines 161-302
161 /////////////// 162 // String map 163 ////////////// 164 165 166 var maps = { 167 168 browser : { 169 oldsafari : { 170 version : { 171 '1.0' : '/8', 172 '1.2' : '/1', 173 '1.3' : '/3', 174 '2.0' : '/412', 175 '2.0.2' : '/416', 176 '2.0.3' : '/417', 177 '2.0.4' : '/419', 178 '?' : '/' 179 } 180 } 181 }, 182 183 device : { 184 amazon : { 185 model : { 186 'Fire Phone' : ['SD', 'KF'] 187 } 188 }, 189 sprint : { 190 model : { 191 'Evo Shift 4G' : '7373KT' 192 }, 193 vendor : { 194 'HTC' : 'APA', 195 'Sprint' : 'Sprint' 196 } 197 } 198 }, 199 200 os : { 201 windows : { 202 version : { 203 'ME' : '4.90', 204 'NT 3.11' : 'NT3.51', 205 'NT 4.0' : 'NT4.0', 206 '2000' : 'NT 5.0', 207 'XP' : ['NT 5.1', 'NT 5.2'], 208 'Vista' : 'NT 6.0', 209 '7' : 'NT 6.1', 210 '8' : 'NT 6.2', 211 '8.1' : 'NT 6.3', 212 '10' : ['NT 6.4', 'NT 10.0'], 213 'RT' : 'ARM' 214 } 215 } 216 } 217 }; 218 219 220 ////////////// 221 // Regex map 222 ///////////// 223 224 225 var regexes = { 226 227 browser : [[ 228 229 // Presto based 230 /(opera\smini)\/([\w\.-]+)/i, // Opera Mini 231 /(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet 232 /(opera).+version\/([\w\.]+)/i, // Opera > 9.80 233 /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80 234 235 ], [NAME, VERSION], [ 236 237 /\s(opr)\/([\w\.]+)/i // Opera Webkit 238 ], [[NAME, 'Opera'], VERSION], [ 239 240 // Mixed 241 /(kindle)\/([\w\.]+)/i, // Kindle 242 /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i, 243 // Lunascape/Maxthon/Netfront/Jasmine/Blazer 244 245 // Trident based 246 /(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i, 247 // Avant/IEMobile/SlimBrowser/Baidu 248 /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer 249 250 // Webkit/KHTML based 251 /(rekonq)\/([\w\.]+)*/i, // Rekonq 252 /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium)\/([\w\.-]+)/i 253 // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium 254 ], [NAME, VERSION], [ 255 256 /(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11 257 ], [[NAME, 'IE'], VERSION], [ 258 259 /(edge)\/((\d+)?[\w\.]+)/i // Microsoft Edge 260 ], [NAME, VERSION], [ 261 262 /(yabrowser)\/([\w\.]+)/i // Yandex 263 ], [[NAME, 'Yandex'], VERSION], [ 264 265 /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon 266 ], [[NAME, /_/g, ' '], VERSION], [ 267 268 /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i, 269 // Chrome/OmniWeb/Arora/Tizen/Nokia 270 /(uc\s?browser|qqbrowser)[\/\s]?([\w\.]+)/i 271 // UCBrowser/QQBrowser 272 ], [NAME, VERSION], [ 273 274 /(dolfin)\/([\w\.]+)/i // Dolphin 275 ], [[NAME, 'Dolphin'], VERSION], [ 276 277 /((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS 278 ], [[NAME, 'Chrome'], VERSION], [ 279 280 /XiaoMi\/MiuiBrowser\/([\w\.]+)/i // MIUI Browser 281 ], [VERSION, [NAME, 'MIUI Browser']], [ 282 283 /android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i // Android Browser 284 ], [VERSION, [NAME, 'Android Browser']], [ 285 286 /FBAV\/([\w\.]+);/i // Facebook App for iOS 287 ], [VERSION, [NAME, 'Facebook']], [ 288 289 /version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari 290 ], [VERSION, [NAME, 'Mobile Safari']], [ 291 292 /version\/([\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile 293 ], [VERSION, NAME], [ 294 295 /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 296 ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [ 297 298 /(konqueror)\/([\w\.]+)/i, // Konqueror 299 /(webkit|khtml)\/([\w\.]+)/i 300 ], [NAME, VERSION], [ 301 302 // Gecko based
303 /(navigator|netscape)\/([\w\.-]+)/i // Netscape 304 ], [[NAME, 'Netscape'], VERSION], [ 305 /fxios\/([\w\.-]+)/i // Firefox for iOS 306 ], [VERSION, [NAME, 'Firefox']], [ 307 /(swiftfox)/i, // Swiftfox 308 /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, 309 // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror 310 /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i, 311 // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix 312 /(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla 313 314 // Other 315 /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?([\w\.]+)/i, 316 // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf 317 /(links)\s\(([\w\.]+)/i, // Links 318 /(gobrowser)\/?([\w\.]+)*/i, // GoBrowser 319 /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser 320 /(mosaic)[\/\s]([\w\.]+)/i // Mosaic 321 ], [NAME, VERSION] 322 323 /* ///////////////////// 324 // Media players BEGIN
vendor: 3,742 bytes, lines 325-390
325 //////////////////////// 326 327 , [ 328 329 /(apple(?:coremedia|))\/((\d+)[\w\._]+)/i, // Generic Apple CoreMedia 330 /(coremedia) v((\d+)[\w\._]+)/i 331 ], [NAME, VERSION], [ 332 333 /(aqualung|lyssna|bsplayer)\/((\d+)?[\w\.-]+)/i // Aqualung/Lyssna/BSPlayer 334 ], [NAME, VERSION], [ 335 336 /(ares|ossproxy)\s((\d+)[\w\.-]+)/i // Ares/OSSProxy 337 ], [NAME, VERSION], [ 338 339 /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/((\d+)[\w\.-]+)/i, 340 // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC 341 // NSPlayer/PSP-InternetRadioPlayer/Videos 342 /(clementine|music player daemon)\s((\d+)[\w\.-]+)/i, // Clementine/MPD 343 /(lg player|nexplayer)\s((\d+)[\d\.]+)/i, 344 /player\/(nexplayer|lg player)\s((\d+)[\w\.-]+)/i // NexPlayer/LG Player 345 ], [NAME, VERSION], [ 346 /(nexplayer)\s((\d+)[\w\.-]+)/i // Nexplayer 347 ], [NAME, VERSION], [ 348 349 /(flrp)\/((\d+)[\w\.-]+)/i // Flip Player 350 ], [[NAME, 'Flip Player'], VERSION], [ 351 352 /(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i 353 // FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit 354 ], [NAME], [ 355 356 /(gstreamer) souphttpsrc (?:\([^\)]+\)){0,1} libsoup\/((\d+)[\w\.-]+)/i 357 // Gstreamer 358 ], [NAME, VERSION], [ 359 360 /(htc streaming player)\s[\w_]+\s\/\s((\d+)[\d\.]+)/i, // HTC Streaming Player 361 /(java|python-urllib|python-requests|wget|libcurl)\/((\d+)[\w\.-_]+)/i, 362 // Java/urllib/requests/wget/cURL 363 /(lavf)((\d+)[\d\.]+)/i // Lavf (FFMPEG) 364 ], [NAME, VERSION], [ 365 366 /(htc_one_s)\/((\d+)[\d\.]+)/i // HTC One S 367 ], [[NAME, /_/g, ' '], VERSION], [ 368 369 /(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+){0,1})/i 370 // MPlayer SVN 371 ], [NAME, VERSION], [ 372 373 /(mplayer)(?:\s|\/|[unkow-]+)((\d+)[\w\.-]+)/i // MPlayer 374 ], [NAME, VERSION], [ 375 376 /(mplayer)/i, // MPlayer (no other info) 377 /(yourmuze)/i, // YourMuze 378 /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime 379 ], [NAME], [ 380 381 /(nero (?:home|scout))\/((\d+)[\w\.-]+)/i // Nero Home/Nero Scout 382 ], [NAME, VERSION], [ 383 384 /(nokia\d+)\/((\d+)[\w\.-]+)/i // Nokia 385 ], [NAME, VERSION], [ 386 387 /\s(songbird)\/((\d+)[\w\.-]+)/i // Songbird/Philips-Songbird 388 ], [NAME, VERSION], [ 389 390 /(winamp)3 version ((\d+)[\w\.-]+)/i, // W
390inamp 391 /(winamp)\s((\d+)[\w\.-]+)/i, 392 /(winamp)mpeg\/((\d+)[\w\.-]+)/i 393 ], [NAME, VERSION], [ 394 395 /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) 396 // inlight radio 397 ], [NAME], [ 398 399 /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/((\d+)[\w\.-]+)/i 400 // QuickTime/RealMedia/RadioApp/RadioClientApplication/ 401 // SoundTap/Totem/Stagefright/Streamium 402 ], [NAME, VERSION], [ 403 404 /(smp)((\d+)[\d\.]+)/i // SMP 405 ], [NAME, VERSION], [ 406 407 /(vlc) media player - version ((\d+)[\w\.]+)/i, // VLC Videolan 408 /(vlc)\/((\d+)[\w\.-]+)/i, 409 /(xbmc|gvfs|xine|xmms|irapp)\/((\d+)[\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp 410 /(foobar2000)\/((\d+)[\d\.]+)/i, // Foobar2000 411 /(itunes)\/((\d+)[\d\.]+)/i // iTunes 412 ], [NAME, VERSION], [ 413 414 /(wmplayer)\/((\d+)[\w\.-]+)/i, // W
414indows Media Player 415 /(windows-media-player)\/((\d+)[\w\.-]+)/i 416 ], [[NAME, /-/g, ' '], VERSION], [ 417 418 /windows\/((\d+)[\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i 419 // Windows Media Server 420 ], [VERSION, [NAME, 'Windows']], [ 421 422 /(com\.riseupradioalarm)\/((\d+)[\d\.]*)/i // RiseUP Radio Alarm 423 ], [NAME, VERSION], [ 424 425 /(rad.io)\s((\d+)[\d\.]+)/i, // Rad.io 426 /(radio.(?:de|at|fr))\s((\d+)[\d\.]+)/i 427 ], [[NAME, 'rad.io'], VERSION] 428 429 ////////////////////// 430 // Media players END 431 ////////////////////*/ 432 433 ], 434 435 cpu : [[ 436 437 /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i // AMD64 438 ], [[ARCHITECTURE, 'amd64']], [ 439 440 /(ia32(?=;))/i // IA32 (quicktime) 441 ], [[ARCHITECTURE, util.lowerize]], [ 442 443 /((?:i[346]|x)86)[;\)]/i // IA32 444 ], [[ARCHITECTURE, 'ia32']], [ 445 446 // PocketPC mistakenly identified as PowerPC 447 /windows\s(ce|mobile);\sppc;/i 448 ], [[ARCHITECTURE, 'arm']], [ 449 450 /((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i // PowerPC 451 ], [[ARCHITECTURE, /ower/, '', util.lowerize]], [ 452 453 /(sun4\w)[;\)]/i // SPARC 454 ], [[ARCHITECTURE, 'sparc']], [ 455 456 /((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i 457 // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC 458 ], [[ARCHITECTURE, util.lowerize]] 459 ], 460 461 device : [[ 462 463 /\((ipad|playbook);[\w\s\);-]+(rim|apple)/i // iPad/PlayBook 464 ], [MODEL, VENDOR, [TYPE, TABLET]], [ 465 466 /applecoremedia\/[\w\.]+ \((ipad)/ // iPad 467 ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [ 468 469 /(apple\s{0,1}tv)/i // Apple TV 470 ], [[MODEL, 'Apple TV'], [VENDOR, 'Apple']], [ 471 472 /(archos)\s(gamepad2?)/i, // Archos 473 /(hp).+(touchpad)/i, // HP TouchPad 474 /(kindle)\/([\w\.]+)/i, // Kindle 475 /\s(nook)[\w\s]+build\/(\w+)/i, // Nook 476 /(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak 477 ], [VENDOR, MODEL, [TYPE, TABLET]], [ 478 479 /(kf[A-z]+)\sbuild\/[\w\.]+.*silk\//i // Kindle Fire HD 480 ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ 481 /(sd|kf)[0349hijorstuw]+\sbuild\/[\w\.]+.*silk\//i // Fire Phone 482 ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ 483 484 /\((ip[honed|\s\w*]+);.+(apple)/i // iPod/iPhone 485 ], [MODEL, VENDOR, [TYPE, MOBILE]], [ 486 /\((ip[honed|\s\w*]+);/i // iPod/iPhone 487 ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ 488 489 /(blackberry)[\s-]?(\w+)/i, // BlackBerry 490 /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola|polytron)[\s_-]?([\w-]+)*/i, 491 // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Huawei/Meizu/Motorola/Polytron 492 /(hp)\s([\w\s]+\w)/i, // HP iPAQ 493 /(asus)-?(\w+)/i // Asus 494 ], [VENDOR, MODEL, [TYPE, MOBILE]], [ 495 /\(bb10;\s(\w+)/i // BlackBerry 10 496 ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ 497 // Asus Tablets 498 /android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7)/i 499 ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [ 500 501 /(sony)\s(tablet\s[ps])\sbuild\//i, // Sony 502 /(sony)?(?:sgp.+)\sbuild\//i 503 ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [
vendor: 4,825 bytes, lines 504-587
504 /(?:sony)?(?:(?:(?:c|d)\d{4})|(?:so[-l].+))\sbuild\//i 505 ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Phone'], [TYPE, MOBILE]], [ 506 507 /\s(ouya)\s/i, // Ouya 508 /(nintendo)\s([wids3u]+)/i // Nintendo 509 ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ 510 511 /android.+;\s(shield)\sbuild/i // Nvidia 512 ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ 513 514 /(playstation\s[3portablevi]+)/i // Playstation 515 ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [ 516 517 /(sprint\s(\w+))/i // Sprint Phones 518 ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [ 519 520 /(lenovo)\s?(S(?:5000|6000)+(?:[-][\w+]))/i // Lenovo tablets 521 ], [VENDOR, MODEL, [TYPE, TABLET]], [ 522 523 /(htc)[;_\s-]+([\w\s]+(?=\))|\w+)*/i, // HTC 524 /(zte)-(\w+)*/i, // ZTE 525 /(alcatel|geeksphone|huawei|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]+)*/i 526 // Alcatel/GeeksPhone/Huawei/Lenovo/Nexian/Panasonic/Sony 527 ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ 528 529 /(nexus\s9)/i // HTC Nexus 9 530 ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ 531 532 /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox 533 ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ 534 /(kin\.[onetw]{3})/i // Microsoft Kin 535 ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ 536 537 // Motorola 538 /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?)[\w\s]+build\//i, 539 /mot[\s-]?(\w+)*/i, 540 /(XT\d{3,4}) build\//i 541 ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ 542 /android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i 543 ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ 544 545 /android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n8000|sgh-t8[56]9|nexus 10))/i, 546 /((SM-T\w+))/i 547 ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung 548 /((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-n900))/i, 549 /(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i, 550 /sec-((sgh\w+))/i 551 ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [ 552 /(samsung);smarttv/i 553 ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ 554 555 /\(dtv[\);].+(aquos)/i // Sharp 556 ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ 557 /sie-(\w+)*/i // Siemens 558 ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ 559 560 /(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia 561 /(nokia)[\s_-]?([\w-]+)*/i 562 ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [ 563 564 /android\s3\.[\s\w;-]{10}(a\d{3})/i // Acer 565 ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [ 566 567 /android\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet 568 ], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [ 569 /(lg) netcast\.tv/i // LG SmartTV 570 ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ 571 /(nexus\s[45])/i, // LG 572 /lg[e;\s\/-]+(\w+)*/i 573 ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ 574 575 /android.+(ideatab[a-z0-9\-\s]+)/i // Lenovo 576 ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ 577 578 /linux;.+((jolla));/i // Jolla 579 ], [VENDOR, MODEL, [TYPE, MOBILE]], [ 580 581 /((pebble))app\/[\d\.]+\s/i // Pebble 582 ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ 583 584 /android.+;\s(glass)\s\d/i // Google Glass 585 ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ 586 587 /android.+(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
588 /android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi 589 /android.+(mi[\s\-_]*(?:one|one[\s_]plus)?[\s_]*(?:\d\w)?)\s+build/i // Xiaomi Mi 590 ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ 591 592 /(mobile|tablet);.+rv\:.+gecko\//i // Unidentifiable 593 ], [[TYPE, util.lowerize], VENDOR, MODEL] 594 595 /*////////////////////////// 596 // TODO: move to string map 597 //////////////////////////// 598 599 /(C6603)/i // Sony Xperia Z C6603 600 ], [[MODEL, 'Xperia Z C6603'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [ 601 /(C6903)/i // Sony Xperia Z 1 602 ], [[MODEL, 'Xperia Z 1'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [ 603 604 /(SM-G900[F|H])/i // Samsung Galaxy S5 605 ], [[MODEL, 'Galaxy S5'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ 606 /(SM-G7102)/i // Samsung Galaxy Grand 2 607 ], [[MODEL, 'Galaxy Grand 2'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ 608 /(SM-G530H)/i // Samsung Galaxy Grand Prime 609 ], [[MODEL, 'Galaxy Grand Prime'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ 610 /(SM-G313HZ)/i // Samsung Galaxy V 611 ], [[MODEL, 'Galaxy V'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ 612 /(SM-T805)/i // Samsung Galaxy Tab S 10.5 613 ], [[MODEL, 'Galaxy Tab S 10.5'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [ 614 /(SM-G800F)/i // Samsung Galaxy S5 Mini 615 ], [[MODEL, 'Galaxy S5 Mini'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ 616 /(SM-T311)/i // Samsung Galaxy Tab 3 8.0 617 ], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [ 618 619 /(R1001)/i // Oppo R1001 620 ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ 621 /(X9006)/i // Oppo Find 7a 622 ], [[MODEL, 'Find 7a'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [ 623 /(R2001)/i // Oppo YOYO R2001 624 ], [[MODEL, 'Yoyo R2001'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [ 625 /(R815)/i // Oppo Clover R815 626 ], [[MODEL, 'Clover R815'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [ 627 /(U707)/i // Oppo Find Way S 628 ], [[MODEL, 'Find Way S'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [ 629 630 /(T3C)/i // Advan Vandroid T3C 631 ], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [ 632 /(ADVAN T1J\+)/i // Advan Vandroid T1J+ 633 ], [[MODEL, 'Vandroid T1J+'], [VENDOR, 'Advan'], [TYPE, TABLET]], [ 634 /(ADVAN S4A)/i // Advan Vandroid S4A 635 ], [[MODEL, 'Vandroid S4A'], [VENDOR, 'Advan'], [TYPE, MOBILE]], [ 636 637 /(V972M)/i // ZTE V972M 638 ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ 639 640 /(i-mobile)\s(IQ\s[\d\.]+)/i // i-mobile IQ 641 ], [VENDOR, MODEL, [TYPE, MOBILE]], [ 642 /(IQ6.3)/i // i-mobile IQ IQ 6.3 643 ], [[MODEL, 'IQ 6.3'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [ 644 /(i-mobile)\s(i-style\s[\d\.]+)/i // i-mobile i-STYLE 645 ], [VENDOR, MODEL, [TYPE, MOBILE]], [ 646 /(i-STYLE2.1)/i // i-mobile i-STYLE 2.1 647 ], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [ 648 649 /(mobiistar touch LAI 512)/i // mobiistar touch LAI 512 650 ], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [ 651
652 ///////////// 653 // END TODO 654 ///////////*/ 655 656 ], 657 658 engine : [[ 659 660 /windows.+\sedge\/([\w\.]+)/i // EdgeHTML 661 ], [VERSION, [NAME, 'EdgeHTML']], [ 662 663 /(presto)\/([\w\.]+)/i, // Presto 664 /(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m 665 /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links 666 /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab 667 ], [NAME, VERSION], [ 668 669 /rv\:([\w\.]+).*(gecko)/i // Gecko 670 ], [VERSION, NAME] 671 ], 672 673 os : [[ 674 675 // Windows based 676 /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes) 677 ], [NAME, VERSION], [ 678 /(windows)\snt\s6\.2;
vendor: 1,596 bytes, lines 678-701
678\s(arm)/i, // Windows RT 679 /(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i 680 ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [ 681 /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i 682 ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [ 683 684 // Mobile/Embedded OS 685 /\((bb)(10);/i // BlackBerry 10 686 ], [[NAME, 'BlackBerry'], VERSION], [ 687 /(blackberry)\w*\/?([\w\.]+)*/i, // Blackberry 688 /(tizen)[\/\s]([\w\.]+)/i, // Tizen 689 /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i, 690 // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki 691 /linux;.+(sailfish);/i // Sailfish OS 692 ], [NAME, VERSION], [ 693 /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian 694 ], [[NAME, 'Symbian'], VERSION], [ 695 /\((series40);/i // Series 40 696 ], [NAME], [ 697 /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS 698 ], [[NAME, 'Firefox OS'], VERSION], [ 699 700 // Console 701 /(nintendo|playstation)\s([wids3portablevu]+)/i, // Nintendo
701/Playstation 702 703 // GNU/Linux based 704 /(mint)[\/\s\(]?(\w+)*/i, // Mint 705 /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux 706 /(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i, 707 // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware 708 // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus 709 /(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux 710 /(gnu)\s?([\w\.]+)*/i // GNU 711 ], [NAME, VERSION], [ 712 713 /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS 714 ], [[NAME, 'Chromium OS'], VERSION],[ 715 716 // Solaris 717 /(sunos)\s?([\w\.]+\d)*/i // Solaris 718 ], [[NAME, 'Solaris'], VERSION], [ 719 720 // BSD based 721 /\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly 722 ], [NAME, VERSION],[ 723 724 /(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i // iOS 725 ], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [ 726 727 /(mac\sos\sx)\s?([\w\s\.]+\w)*/i, 728 /(macintosh|mac(?=_powerpc)\s)/i // Mac OS 729 ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ 730 731 // Other 732 /((?:open)?solaris)[\/\s-]?([\w\.]+)*/i, // Solaris 733 /(haiku)\s(\w+)/i, // Haiku 734 /(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i, // AIX 735 /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i, 736 // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS 737 /(unix)\s?([\w\.]+)*/i // UNIX 738 ], [NAME, VERSION] 739 ] 740 }; 741 742 743 ///////////////// 744 // Constructor 745 //////////////// 746 747 748 var UAParser = function (uastring, extensions) { 749 750 if (!(this instanceof UAParser)) { 751 return new UAParser(uastring, extensions).getResult(); 752 } 753 754 var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); 755 var rgxmap = extensions ? util.extend(regexes, extensions) : regexes; 756 757 this.getBrowser = function () { 758 var browser = mapper.rgx.apply(this, rgxmap.browser); 759 browser.major = util.major(browser.version); 760 return browser; 761 }; 762 this.getCPU = function () { 763 return mapper.rgx.apply(this, rgxmap.cpu); 764 }; 765 this.getDevice = function () { 766 return mapper.rgx.apply(this, rgxmap.device); 767 }; 768 this.getEngine = function () { 769 return mapper.rgx.apply(this, rgxmap.engine); 770 }; 771 this.getOS = function () { 772 return mapper.rgx.apply(this, rgxmap.os); 773 }; 774 this.getResult = function() { 775 return { 776 ua : this.getUA(), 777 browser : this.getBrowser(), 778 engine : this.getEngine(), 779 os : this.getOS(), 780 device : this.getDevice(), 781 cpu : this.getCPU() 782 }; 783 }; 784 this.getUA = function () { 785 return ua; 786 }; 787 this.setUA = function (uastring) { 788 ua = uastring; 789 return this; 790 }; 791 this.setUA(ua); 792 return this; 793 }; 794 795 UAParser.VERSION = LIBVERSION; 796 UAParser.BROWSER = { 797 NAME : NAME, 798 MAJOR : MAJOR, // deprecated 799 VERSION : VERSION 800 }; 801 UAParser.CPU = { 802 ARCHITECTURE : ARCHITECTURE 803 }; 804 UAParser.DEVICE = { 805 MODEL : MODEL, 806 VENDOR : VENDOR, 807 TYPE : TYPE, 808 CONSOLE : CONSOLE, 809 MOBILE : MOBILE, 810 SMARTTV : SMARTTV, 811 TABLET : TABLET, 812 WEARABLE: WEARABLE, 813 EMBEDDED: EMBEDDED 814 };
815 UAParser.ENGINE = { 816 NAME : NAME, 817 VERSION : VERSION 818 }; 819 UAParser.OS = { 820 NAME : NAME, 821 VERSION : VERSION 822 }; 823 824 825 /////////// 826 // Export 827 ////////// 828 829 830 // check js environment 831 if (typeof(exports) !== UNDEF_TYPE) { 832 // nodejs env 833 if (typeof module !== UNDEF_TYPE && module.exports) { 834 exports = module.exports = UAParser; 835 } 836 exports.UAParser = UAParser; 837 } else { 838 // requirejs env (optional) 839 if (typeof(define) === FUNC_TYPE && define.amd) { 840 define(function () { 841 return UAParser; 842 }); 843 } else { 844 // browser env 845 window.UAParser = UAParser; 846 } 847 } 848 849 // jQuery/Zepto specific (optional) 850 // Note: 851 // In AMD env the global scope should be kept clean, but jQuery is an exception. 852 // jQuery always exports to global scope, unless jQuery.noConflict(true) is used, 853 // and we should catch that. 854 var $ = window.jQuery || window.Zepto; 855 if (typeof $ !== UNDEF_TYPE) { 856 var parser = new UAParser(); 857 $.ua = parser.getResult(); 858 $.ua.get = function() { 859 return parser.getUA(); 860 }; 861 $.ua.set = function (uastring) { 862 parser.setUA(uastring); 863 var result = parser.getResult(); 864 for (var prop in result) { 865 $.ua[prop] = result[prop]; 866 } 867 }; 868 } 869 870})(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.