ua-parser-js 0.7.24 → 0.7.25

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.

Potentially problematic release.


This version of ua-parser-js might be problematic. Click here for more details.

package/src/ua-parser.js CHANGED
@@ -1,937 +1,924 @@
1
- /*!
2
- * UAParser.js v0.7.24
3
- * Lightweight JavaScript-based User-Agent string parser
4
- * https://github.com/faisalman/ua-parser-js
5
- *
6
- * Copyright © 2012-2021 Faisal Salman <f@faisalman.com>
7
- * Licensed under MIT License
8
- */
9
-
10
- (function (window, undefined) {
11
-
12
- 'use strict';
13
-
14
- //////////////
15
- // Constants
16
- /////////////
17
-
18
-
19
- var LIBVERSION = '0.7.24',
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
- var mergedRegexes = {};
49
- for (var i in regexes) {
50
- if (extensions[i] && extensions[i].length % 2 === 0) {
51
- mergedRegexes[i] = extensions[i].concat(regexes[i]);
52
- } else {
53
- mergedRegexes[i] = regexes[i];
54
- }
55
- }
56
- return mergedRegexes;
57
- },
58
- has : function (str1, str2) {
59
- if (typeof str1 === "string") {
60
- return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;
61
- } else {
62
- return false;
63
- }
64
- },
65
- lowerize : function (str) {
66
- return str.toLowerCase();
67
- },
68
- major : function (version) {
69
- return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g,'').split(".")[0] : undefined;
70
- },
71
- trim : function (str) {
72
- return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
73
- }
74
- };
75
-
76
-
77
- ///////////////
78
- // Map helper
79
- //////////////
80
-
81
-
82
- var mapper = {
83
-
84
- rgx : function (ua, arrays) {
85
-
86
- var i = 0, j, k, p, q, matches, match;
87
-
88
- // loop through all regexes maps
89
- while (i < arrays.length && !matches) {
90
-
91
- var regex = arrays[i], // even sequence (0,2,4,..)
92
- props = arrays[i + 1]; // odd sequence (1,3,5,..)
93
- j = k = 0;
94
-
95
- // try matching uastring with regexes
96
- while (j < regex.length && !matches) {
97
-
98
- matches = regex[j++].exec(ua);
99
-
100
- if (!!matches) {
101
- for (p = 0; p < props.length; p++) {
102
- match = matches[++k];
103
- q = props[p];
104
- // check if given property is actually array
105
- if (typeof q === OBJ_TYPE && q.length > 0) {
106
- if (q.length == 2) {
107
- if (typeof q[1] == FUNC_TYPE) {
108
- // assign modified match
109
- this[q[0]] = q[1].call(this, match);
110
- } else {
111
- // assign given value, ignore regex match
112
- this[q[0]] = q[1];
113
- }
114
- } else if (q.length == 3) {
115
- // check whether function or regex
116
- if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
117
- // call function (usually string mapper)
118
- this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
119
- } else {
120
- // sanitize match using given regex
121
- this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
122
- }
123
- } else if (q.length == 4) {
124
- this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
125
- }
126
- } else {
127
- this[q] = match ? match : undefined;
128
- }
129
- }
130
- }
131
- }
132
- i += 2;
133
- }
134
- },
135
-
136
- str : function (str, map) {
137
-
138
- for (var i in map) {
139
- // check if array
140
- if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
141
- for (var j = 0; j < map[i].length; j++) {
142
- if (util.has(map[i][j], str)) {
143
- return (i === UNKNOWN) ? undefined : i;
144
- }
145
- }
146
- } else if (util.has(map[i], str)) {
147
- return (i === UNKNOWN) ? undefined : i;
148
- }
149
- }
150
- return str;
151
- }
152
- };
153
-
154
-
155
- ///////////////
156
- // String map
157
- //////////////
158
-
159
-
160
- var maps = {
161
-
162
- browser : {
163
- oldsafari : {
164
- version : {
165
- '1.0' : '/8',
166
- '1.2' : '/1',
167
- '1.3' : '/3',
168
- '2.0' : '/412',
169
- '2.0.2' : '/416',
170
- '2.0.3' : '/417',
171
- '2.0.4' : '/419',
172
- '?' : '/'
173
- }
174
- }
175
- },
176
-
177
- device : {
178
- amazon : {
179
- model : {
180
- 'Fire Phone' : ['SD', 'KF']
181
- }
182
- },
183
- sprint : {
184
- model : {
185
- 'Evo Shift 4G' : '7373KT'
186
- },
187
- vendor : {
188
- 'HTC' : 'APA',
189
- 'Sprint' : 'Sprint'
190
- }
191
- }
192
- },
193
-
194
- os : {
195
- windows : {
196
- version : {
197
- 'ME' : '4.90',
198
- 'NT 3.11' : 'NT3.51',
199
- 'NT 4.0' : 'NT4.0',
200
- '2000' : 'NT 5.0',
201
- 'XP' : ['NT 5.1', 'NT 5.2'],
202
- 'Vista' : 'NT 6.0',
203
- '7' : 'NT 6.1',
204
- '8' : 'NT 6.2',
205
- '8.1' : 'NT 6.3',
206
- '10' : ['NT 6.4', 'NT 10.0'],
207
- 'RT' : 'ARM'
208
- }
209
- }
210
- }
211
- };
212
-
213
-
214
- //////////////
215
- // Regex map
216
- /////////////
217
-
218
-
219
- var regexes = {
220
-
221
- browser : [[
222
-
223
- // Presto based
224
- /(opera\smini)\/([\w\.-]+)/i, // Opera Mini
225
- /(opera\s[mobiletab]{3,6}).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet
226
- /(opera).+version\/([\w\.]+)/i, // Opera > 9.80
227
- /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80
228
- ], [NAME, VERSION], [
229
-
230
- /(opios)[\/\s]+([\w\.]+)/i // Opera mini on iphone >= 8.0
231
- ], [[NAME, 'Opera Mini'], VERSION], [
232
-
233
- /\s(opr)\/([\w\.]+)/i // Opera Webkit
234
- ], [[NAME, 'Opera'], VERSION], [
235
-
236
- // Mixed
237
- /(kindle)\/([\w\.]+)/i, // Kindle
238
- /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]*)/i,
239
- // Lunascape/Maxthon/Netfront/Jasmine/Blazer
240
- // Trident based
241
- /(avant\s|iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i,
242
- // Avant/IEMobile/SlimBrowser
243
- /(bidubrowser|baidubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser
244
- /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer
245
-
246
- // Webkit/KHTML based
247
- /(rekonq)\/([\w\.]*)/i, // Rekonq
248
- /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon)\/([\w\.-]+)/i
249
- // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
250
- ], [NAME, VERSION], [
251
-
252
- /(konqueror)\/([\w\.]+)/i // Konqueror
253
- ], [[NAME, 'Konqueror'], VERSION], [
254
-
255
- /(trident).+rv[:\s]([\w\.]{1,9}).+like\sgecko/i // IE11
256
- ], [[NAME, 'IE'], VERSION], [
257
-
258
- /(edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge
259
- ], [[NAME, 'Edge'], VERSION], [
260
-
261
- /(yabrowser)\/([\w\.]+)/i // Yandex
262
- ], [[NAME, 'Yandex'], VERSION], [
263
-
264
- /(Avast)\/([\w\.]+)/i // Avast Secure Browser
265
- ], [[NAME, 'Avast Secure Browser'], VERSION], [
266
-
267
- /(AVG)\/([\w\.]+)/i // AVG Secure Browser
268
- ], [[NAME, 'AVG Secure Browser'], VERSION], [
269
-
270
- /(puffin)\/([\w\.]+)/i // Puffin
271
- ], [[NAME, 'Puffin'], VERSION], [
272
-
273
- /(focus)\/([\w\.]+)/i // Firefox Focus
274
- ], [[NAME, 'Firefox Focus'], VERSION], [
275
-
276
- /(opt)\/([\w\.]+)/i // Opera Touch
277
- ], [[NAME, 'Opera Touch'], VERSION], [
278
-
279
- /((?:[\s\/])uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser
280
- ], [[NAME, 'UCBrowser'], VERSION], [
281
-
282
- /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
283
- ], [[NAME, /_/g, ' '], VERSION], [
284
-
285
- /(windowswechat qbcore)\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser
286
- ], [[NAME, 'WeChat(Win) Desktop'], VERSION], [
287
-
288
- /(micromessenger)\/([\w\.]+)/i // WeChat
289
- ], [[NAME, 'WeChat'], VERSION], [
290
-
291
- /(brave)\/([\w\.]+)/i // Brave browser
292
- ], [[NAME, 'Brave'], VERSION], [
293
-
294
- /(whale)\/([\w\.]+)/i // Whale browser
295
- ], [[NAME, 'Whale'], VERSION], [
296
-
297
- /(qqbrowserlite)\/([\w\.]+)/i // QQBrowserLite
298
- ], [NAME, VERSION], [
299
-
300
- /(QQ)\/([\d\.]+)/i // QQ, aka ShouQ
301
- ], [NAME, VERSION], [
302
-
303
- /m?(qqbrowser)[\/\s]?([\w\.]+)/i // QQBrowser
304
- ], [NAME, VERSION], [
305
-
306
- /(baiduboxapp)[\/\s]?([\w\.]+)/i // Baidu App
307
- ], [NAME, VERSION], [
308
-
309
- /(2345Explorer)[\/\s]?([\w\.]+)/i // 2345 Browser
310
- ], [NAME, VERSION], [
311
-
312
- /(MetaSr)[\/\s]?([\w\.]+)/i // SouGouBrowser
313
- ], [NAME], [
314
-
315
- /(LBBROWSER)/i // LieBao Browser
316
- ], [NAME], [
317
-
318
- /xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser
319
- ], [VERSION, [NAME, 'MIUI Browser']], [
320
-
321
- /;fbav\/([\w\.]+);/i // Facebook App for iOS & Android with version
322
- ], [VERSION, [NAME, 'Facebook']], [
323
-
324
- /FBAN\/FBIOS|FB_IAB\/FB4A/i // Facebook App for iOS & Android without version
325
- ], [[NAME, 'Facebook']], [
326
-
327
- /safari\s(line)\/([\w\.]+)/i, // Line App for iOS
328
- /android.+(line)\/([\w\.]+)\/iab/i // Line App for Android
329
- ], [NAME, VERSION], [
330
-
331
- /headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless
332
- ], [VERSION, [NAME, 'Chrome Headless']], [
333
-
334
- /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
335
- ], [[NAME, /(.+)/, '$1 WebView'], VERSION], [
336
-
337
- /((?:oculus|samsung)browser)\/([\w\.]+)/i
338
- ], [[NAME, /(.+(?:g|us))(.+)/, '$1 $2'], VERSION], [ // Oculus / Samsung Browser
339
-
340
- /android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)*/i // Android Browser
341
- ], [VERSION, [NAME, 'Android Browser']], [
342
-
343
- /(coc_coc_browser)\/([\w\.]+)/i // Coc Coc Browser
344
- ], [[NAME, 'Coc Coc'], VERSION], [
345
-
346
- /(sailfishbrowser)\/([\w\.]+)/i // Sailfish Browser
347
- ], [[NAME, 'Sailfish Browser'], VERSION], [
348
-
349
- /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i
350
- // Chrome/OmniWeb/Arora/Tizen/Nokia
351
- ], [NAME, VERSION], [
352
-
353
- /(dolfin)\/([\w\.]+)/i // Dolphin
354
- ], [[NAME, 'Dolphin'], VERSION], [
355
-
356
- /(qihu|qhbrowser|qihoobrowser|360browser)/i // 360
357
- ], [[NAME, '360 Browser']], [
358
-
359
- /((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
360
- ], [[NAME, 'Chrome'], VERSION], [
361
-
362
- /(coast)\/([\w\.]+)/i // Opera Coast
363
- ], [[NAME, 'Opera Coast'], VERSION], [
364
-
365
- /fxios\/([\w\.-]+)/i // Firefox for iOS
366
- ], [VERSION, [NAME, 'Firefox']], [
367
-
368
- /version\/([\w\.]+)\s.*mobile\/\w+\s(safari)/i // Mobile Safari
369
- ], [VERSION, [NAME, 'Mobile Safari']], [
370
-
371
- /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile
372
- ], [VERSION, NAME], [
373
-
374
- /webkit.+?(gsa)\/([\w\.]+)\s.*(mobile\s?safari|safari)(\/[\w\.]+)/i // Google Search Appliance on iOS
375
- ], [[NAME, 'GSA'], VERSION], [
376
-
377
- /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
378
- ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [
379
-
380
- /(webkit|khtml)\/([\w\.]+)/i
381
- ], [NAME, VERSION], [
382
-
383
- // Gecko based
384
- /(navigator|netscape)\/([\w\.-]+)/i // Netscape
385
- ], [[NAME, 'Netscape'], VERSION], [
386
- /(swiftfox)/i, // Swiftfox
387
- /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,
388
- // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
389
- /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i,
390
-
391
- // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
392
- /(firefox)\/([\w\.]+)\s[\w\s\-]+\/[\w\.]+$/i, // Other Firefox-based
393
- /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla
394
-
395
- // Other
396
- /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i,
397
- // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir
398
- /(links)\s\(([\w\.]+)/i, // Links
399
- /(gobrowser)\/?([\w\.]*)/i, // GoBrowser
400
- /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser
401
- /(mosaic)[\/\s]([\w\.]+)/i // Mosaic
402
- ], [NAME, VERSION]
403
- ],
404
-
405
- cpu : [[
406
-
407
- /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i // AMD64
408
- ], [[ARCHITECTURE, 'amd64']], [
409
-
410
- /(ia32(?=;))/i // IA32 (quicktime)
411
- ], [[ARCHITECTURE, util.lowerize]], [
412
-
413
- /((?:i[346]|x)86)[;\)]/i // IA32
414
- ], [[ARCHITECTURE, 'ia32']], [
415
-
416
- // PocketPC mistakenly identified as PowerPC
417
- /windows\s(ce|mobile);\sppc;/i
418
- ], [[ARCHITECTURE, 'arm']], [
419
-
420
- /((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i // PowerPC
421
- ], [[ARCHITECTURE, /ower/, '', util.lowerize]], [
422
-
423
- /(sun4\w)[;\)]/i // SPARC
424
- ], [[ARCHITECTURE, 'sparc']], [
425
-
426
- /((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+[;l]))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i
427
- // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
428
- ], [[ARCHITECTURE, util.lowerize]]
429
- ],
430
-
431
- device : [[
432
-
433
- /\((ipad|playbook);[\w\s\),;-]+(rim|apple)/i // iPad/PlayBook
434
- ], [MODEL, VENDOR, [TYPE, TABLET]], [
435
-
436
- /applecoremedia\/[\w\.]+ \((ipad)/ // iPad
437
- ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [
438
-
439
- /(apple\s{0,1}tv)/i // Apple TV
440
- ], [[MODEL, 'Apple TV'], [VENDOR, 'Apple'], [TYPE, SMARTTV]], [
441
-
442
- /(archos)\s(gamepad2?)/i, // Archos
443
- /(hp).+(touchpad)/i, // HP TouchPad
444
- /(hp).+(tablet)/i, // HP Tablet
445
- /(kindle)\/([\w\.]+)/i, // Kindle
446
- /\s(nook)[\w\s]+build\/(\w+)/i, // Nook
447
- /(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak
448
- ], [VENDOR, MODEL, [TYPE, TABLET]], [
449
-
450
- /(kf[A-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD
451
- ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [
452
- /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone
453
- ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [
454
- /android.+aft([\w])(\sbuild\/|\))/i // Fire TV
455
- ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [
456
-
457
- /\((ip[honed|\s\w*]+);.+(apple)/i // iPod/iPhone
458
- ], [MODEL, VENDOR, [TYPE, MOBILE]], [
459
- /\((ip[honed|\s\w*]+);/i // iPod/iPhone
460
- ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [
461
-
462
- /(blackberry)[\s-]?(\w+)/i, // BlackBerry
463
- /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\s_-]?([\w-]*)/i,
464
- // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
465
- /(hp)\s([\w\s]+\w)/i, // HP iPAQ
466
- /(asus)-?(\w+)/i // Asus
467
- ], [VENDOR, MODEL, [TYPE, MOBILE]], [
468
- /\(bb10;\s(\w+)/i // BlackBerry 10
469
- ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [
470
- // Asus Tablets
471
- /android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone|p00c)/i
472
- ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [
473
-
474
- /(sony)\s(tablet\s[ps])\sbuild\//i, // Sony
475
- /(sony)?(?:sgp.+)\sbuild\//i
476
- ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [
477
- /android.+\s([c-g]\d{4}|so[-l]\w+)(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i
478
- ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [
479
-
480
- /\s(ouya)\s/i, // Ouya
481
- /(nintendo)\s([wids3u]+)/i // Nintendo
482
- ], [VENDOR, MODEL, [TYPE, CONSOLE]], [
483
-
484
- /android.+;\s(shield)\sbuild/i // Nvidia
485
- ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
486
-
487
- /(playstation\s[34portablevi]+)/i // Playstation
488
- ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [
489
-
490
- /(sprint\s(\w+))/i // Sprint Phones
491
- ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [
492
-
493
- /(htc)[;_\s-]{1,2}([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC
494
- /(zte)-(\w*)/i, // ZTE
495
- /(alcatel|geeksphone|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i
496
- // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
497
- ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
498
-
499
- /(nexus\s9)/i // HTC Nexus 9
500
- ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
501
-
502
- /d\/huawei([\w\s-]+)[;\)]/i, // Huawei
503
- /android.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?)/i
504
-
505
- ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [
506
-
507
- /android.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad
508
- ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [
509
-
510
- /(microsoft);\s(lumia[\s\w]+)/i // Microsoft Lumia
511
- ], [VENDOR, MODEL, [TYPE, MOBILE]], [
512
-
513
- /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox
514
- ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [
515
- /(kin\.[onetw]{3})/i // Microsoft Kin
516
- ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [
517
-
518
- // Motorola
519
- /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)[\w\s]+build\//i,
520
- /mot[\s-]?(\w*)/i,
521
- /(XT\d{3,4}) build\//i,
522
- /(nexus\s6)/i
523
- ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [
524
- /android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i
525
- ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [
526
-
527
- /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices
528
- ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [
529
-
530
- /hbbtv.+maple;(\d+)/i
531
- ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [
532
-
533
- /\(dtv[\);].+(aquos)/i // Sharp
534
- ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
535
-
536
- /android.+((sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|SM-P587|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i,
537
- /((SM-T\w+))/i
538
- ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung
539
- /smart-tv.+(samsung)/i
540
- ], [VENDOR, [TYPE, SMARTTV], MODEL], [
541
- /((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+))/i,
542
- /(sam[sung]*)[\s-]*(\w+-?[\w-]*)/i,
543
- /sec-((sgh\w+))/i
544
- ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [
545
-
546
- /sie-(\w*)/i // Siemens
547
- ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
548
-
549
- /(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia
550
- /(nokia)[\s_-]?([\w-]*)/i
551
- ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [
552
-
553
- /android[x\d\.\s;]+\s([ab][1-7]\-?[0178a]\d\d?)/i // Acer
554
- ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
555
-
556
- /android.+([vl]k\-?\d{3})\s+build/i // LG Tablet
557
- ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [
558
- /android\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet
559
- ], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [
560
- /linux;\snetcast.+smarttv/i, // LG SmartTV
561
- /lg\snetcast\.tv-201\d/i
562
- ], [[VENDOR, 'LG'], MODEL, [TYPE, SMARTTV]], [
563
- /(nexus\s[45])/i, // LG
564
- /lg[e;\s\/-]+(\w*)/i,
565
- /android.+lg(\-?[\d\w]+)\s+build/i
566
- ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [
567
-
568
- /(lenovo)\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+))/i // Lenovo tablets
569
- ], [VENDOR, MODEL, [TYPE, TABLET]], [
570
- /android.+(ideatab[a-z0-9\-\s]+)/i // Lenovo
571
- ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
572
- /(lenovo)[_\s-]?([\w-]+)/i
573
- ], [VENDOR, MODEL, [TYPE, MOBILE]], [
574
-
575
- /linux;.+((jolla));/i // Jolla
576
- ], [VENDOR, MODEL, [TYPE, MOBILE]], [
577
-
578
- /((pebble))app\/[\d\.]+\s/i // Pebble
579
- ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
580
-
581
- /android.+;\s(oppo)\s?([\w\s]+)\sbuild/i // OPPO
582
- ], [VENDOR, MODEL, [TYPE, MOBILE]], [
583
-
584
- /crkey/i // Google Chromecast
585
- ], [[MODEL, 'Chromecast'], [VENDOR, 'Google'], [TYPE, SMARTTV]], [
586
-
587
- /android.+;\s(glass)\s\d/i // Google Glass
588
- ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [
589
-
590
- /android.+;\s(pixel c)[\s)]/i // Google Pixel C
591
- ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [
592
-
593
- /android.+;\s(pixel( [2-9]a?)?( xl)?)[\s)]/i // Google Pixel
594
- ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [
595
-
596
- /android.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
597
- /android.+(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi
598
- /android.+(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i,
599
- // Xiaomi Redmi
600
- /android.+(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i
601
- // Xiaomi Mi
602
- ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [
603
- /android.+(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets
604
- ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [
605
- /android.+;\s(m[1-5]\snote)\sbuild/i // Meizu
606
- ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
607
- /(mz)-([\w-]{2,})/i
608
- ], [[VENDOR, 'Meizu'], MODEL, [TYPE, MOBILE]], [
609
-
610
- /android.+a000(1)\s+build/i, // OnePlus
611
- /android.+oneplus\s(a\d{4})[\s)]/i
612
- ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
613
-
614
- /android.+[;\/]\s*(RCT[\d\w]+)\s+build/i // RCA Tablets
615
- ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
616
-
617
- /android.+[;\/\s](Venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets
618
- ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
619
-
620
- /android.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet
621
- ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
622
-
623
- /android.+[;\/]\s+(Barnes[&\s]+Noble\s+|BN[RT])(\S(?:.*\S)?)\s+build/i // Barnes & Noble Tablet
624
- ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [
625
-
626
- /android.+[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet
627
- ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
628
-
629
- /android.+;\s(k88)\sbuild/i // ZTE K Series Tablet
630
- ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
631
-
632
- /android.+[;\/]\s*(gen\d{3})\s+build.*49h/i // Swiss GEN Mobile
633
- ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
634
-
635
- /android.+[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet
636
- ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
637
-
638
- /android.+[;\/]\s*((Zeki)?TB.*\b)\s+build/i // Zeki Tablets
639
- ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
640
-
641
- /(android).+[;\/]\s+([YR]\d{2})\s+build/i,
642
- /android.+[;\/]\s+(Dragon[\-\s]+Touch\s+|DT)(\w{5})\sbuild/i // Dragon Touch Tablet
643
- ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [
644
-
645
- /android.+[;\/]\s*(NS-?\w{0,9})\sbuild/i // Insignia Tablets
646
- ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
647
-
648
- /android.+[;\/]\s*((NX|Next)-?\w{0,9})\s+build/i // NextBook Tablets
649
- ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
650
-
651
- /android.+[;\/]\s*(Xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i
652
- ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones
653
-
654
- /android.+[;\/]\s*(LVTEL\-)?(V1[12])\s+build/i // LvTel Phones
655
- ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
656
-
657
- /android.+;\s(PH-1)\s/i
658
- ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1
659
-
660
- /android.+[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i // Envizen Tablets
661
- ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
662
-
663
- /android.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(\w{1,9})\s+build/i // Le Pan Tablets
664
- ], [VENDOR, MODEL, [TYPE, TABLET]], [
665
-
666
- /android.+[;\/]\s*(Trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets
667
- ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
668
-
669
- /android.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i // Trinity Tablets
670
- ], [VENDOR, MODEL, [TYPE, TABLET]], [
671
-
672
- /android.+[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets
673
- ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [
674
-
675
- //android.+(KS(.+))\s+build/i // Amazon Kindle Tablets
676
- //], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [
677
-
678
- /android.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i // Gigaset Tablets
679
- ], [VENDOR, MODEL, [TYPE, TABLET]], [
680
- // Android Phones from Unidentified Vendors
681
- /android .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i
682
- ], [MODEL, [TYPE, MOBILE]], [
683
- // Android Tablets from Unidentified Vendors
684
- /android .+?;\s([^;]+?)(?: build|\) applewebkit).+?(?! mobile) safari/i
685
- ], [MODEL, [TYPE, TABLET]], [
686
-
687
- /\s(tablet|tab)[;\/]/i, // Unidentifiable Tablet
688
- /\s(mobile)(?:[;\/]|\ssafari)/i // Unidentifiable Mobile
689
- ], [[TYPE, util.lowerize], VENDOR, MODEL], [
690
-
691
- /[\s\/\(](smart-?tv)[;\)]/i // SmartTV
692
- ], [[TYPE, SMARTTV]], [
693
-
694
- /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device
695
- ], [MODEL, [VENDOR, 'Generic']], [
696
-
697
- /(phone)/i
698
- ], [[TYPE, MOBILE]]
699
- ],
700
-
701
- engine : [[
702
-
703
- /windows.+\sedge\/([\w\.]+)/i // EdgeHTML
704
- ], [VERSION, [NAME, 'EdgeHTML']], [
705
-
706
- /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
707
- ], [VERSION, [NAME, 'Blink']], [
708
-
709
- /(presto)\/([\w\.]+)/i, // Presto
710
- /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i,
711
- // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
712
- /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links
713
- /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab
714
- ], [NAME, VERSION], [
715
-
716
- /rv\:([\w\.]{1,9}).+(gecko)/i // Gecko
717
- ], [VERSION, NAME]
718
- ],
719
-
720
- os : [[
721
-
722
- // Xbox, consider this before other Windows-based devices
723
- /(xbox);\s+xbox\s([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
724
-
725
- // Windows based
726
- /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes)
727
- ], [NAME, VERSION], [
728
- /(windows)\snt\s6\.2;\s(arm)/i, // Windows RT
729
- /(windows\sphone(?:\sos)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone
730
- /(windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i
731
- ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [
732
- /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i
733
- ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [
734
-
735
- // Mobile/Embedded OS
736
- /\((bb)(10);/i // BlackBerry 10
737
- ], [[NAME, 'BlackBerry'], VERSION], [
738
- /(blackberry)\w*\/?([\w\.]*)/i, // Blackberry
739
- /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS
740
- /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i
741
- // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS
742
- ], [NAME, VERSION], [
743
- /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]*)/i // Symbian
744
- ], [[NAME, 'Symbian'], VERSION], [
745
- /\((series40);/i // Series 40
746
- ], [NAME], [
747
- /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS
748
- ], [[NAME, 'Firefox OS'], VERSION], [
749
-
750
- // Google Chromecast
751
- /crkey\/([\d\.]+)/i // Google Chromecast
752
- ], [VERSION, [NAME, 'Chromecast']], [
753
-
754
- // Console
755
- /(nintendo|playstation)\s([wids34portablevu]+)/i, // Nintendo/Playstation
756
-
757
- // GNU/Linux based
758
- /(mint)[\/\s\(]?(\w*)/i, // Mint
759
- /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux
760
- /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|(?=\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?(?!chrom)([\w\.-]*)/i,
761
- // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
762
- // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus
763
- /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux
764
- /(gnu)\s?([\w\.]*)/i // GNU
765
- ], [NAME, VERSION], [
766
-
767
- /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS
768
- ], [[NAME, 'Chromium OS'], VERSION],[
769
-
770
- // Solaris
771
- /(sunos)\s?([\w\.\d]*)/i // Solaris
772
- ], [[NAME, 'Solaris'], VERSION], [
773
-
774
- // BSD based
775
- /\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]*)/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly
776
- ], [NAME, VERSION],[
777
-
778
- /(haiku)\s(\w+)/i // Haiku
779
- ], [NAME, VERSION],[
780
-
781
- /cfnetwork\/.+darwin/i,
782
- /ip[honead]{2,4}(?:.*os\s([\w]+)\slike\smac|;\sopera)/i // iOS
783
- ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
784
-
785
- /(mac\sos\sx)\s?([\w\s\.]*)/i,
786
- /(macintosh|mac(?=_powerpc)\s)/i // Mac OS
787
- ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [
788
-
789
- // Other
790
- /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris
791
- /(aix)\s((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX
792
- /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms|fuchsia)/i,
793
- // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia
794
- /(unix)\s?([\w\.]*)/i // UNIX
795
- ], [NAME, VERSION]
796
- ]
797
- };
798
-
799
-
800
- /////////////////
801
- // Constructor
802
- ////////////////
803
- var UAParser = function (uastring, extensions) {
804
-
805
- if (typeof uastring === 'object') {
806
- extensions = uastring;
807
- uastring = undefined;
808
- }
809
-
810
- if (!(this instanceof UAParser)) {
811
- return new UAParser(uastring, extensions).getResult();
812
- }
813
-
814
- var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
815
- var rgxmap = extensions ? util.extend(regexes, extensions) : regexes;
816
-
817
- this.getBrowser = function () {
818
- var browser = { name: undefined, version: undefined };
819
- mapper.rgx.call(browser, ua, rgxmap.browser);
820
- browser.major = util.major(browser.version); // deprecated
821
- return browser;
822
- };
823
- this.getCPU = function () {
824
- var cpu = { architecture: undefined };
825
- mapper.rgx.call(cpu, ua, rgxmap.cpu);
826
- return cpu;
827
- };
828
- this.getDevice = function () {
829
- var device = { vendor: undefined, model: undefined, type: undefined };
830
- mapper.rgx.call(device, ua, rgxmap.device);
831
- return device;
832
- };
833
- this.getEngine = function () {
834
- var engine = { name: undefined, version: undefined };
835
- mapper.rgx.call(engine, ua, rgxmap.engine);
836
- return engine;
837
- };
838
- this.getOS = function () {
839
- var os = { name: undefined, version: undefined };
840
- mapper.rgx.call(os, ua, rgxmap.os);
841
- return os;
842
- };
843
- this.getResult = function () {
844
- return {
845
- ua : this.getUA(),
846
- browser : this.getBrowser(),
847
- engine : this.getEngine(),
848
- os : this.getOS(),
849
- device : this.getDevice(),
850
- cpu : this.getCPU()
851
- };
852
- };
853
- this.getUA = function () {
854
- return ua;
855
- };
856
- this.setUA = function (uastring) {
857
- ua = uastring;
858
- return this;
859
- };
860
- return this;
861
- };
862
-
863
- UAParser.VERSION = LIBVERSION;
864
- UAParser.BROWSER = {
865
- NAME : NAME,
866
- MAJOR : MAJOR, // deprecated
867
- VERSION : VERSION
868
- };
869
- UAParser.CPU = {
870
- ARCHITECTURE : ARCHITECTURE
871
- };
872
- UAParser.DEVICE = {
873
- MODEL : MODEL,
874
- VENDOR : VENDOR,
875
- TYPE : TYPE,
876
- CONSOLE : CONSOLE,
877
- MOBILE : MOBILE,
878
- SMARTTV : SMARTTV,
879
- TABLET : TABLET,
880
- WEARABLE: WEARABLE,
881
- EMBEDDED: EMBEDDED
882
- };
883
- UAParser.ENGINE = {
884
- NAME : NAME,
885
- VERSION : VERSION
886
- };
887
- UAParser.OS = {
888
- NAME : NAME,
889
- VERSION : VERSION
890
- };
891
-
892
- ///////////
893
- // Export
894
- //////////
895
-
896
-
897
- // check js environment
898
- if (typeof(exports) !== UNDEF_TYPE) {
899
- // nodejs env
900
- if (typeof module !== UNDEF_TYPE && module.exports) {
901
- exports = module.exports = UAParser;
902
- }
903
- exports.UAParser = UAParser;
904
- } else {
905
- // requirejs env (optional)
906
- if (typeof(define) === 'function' && define.amd) {
907
- define(function () {
908
- return UAParser;
909
- });
910
- } else if (window) {
911
- // browser env
912
- window.UAParser = UAParser;
913
- }
914
- }
915
-
916
- // jQuery/Zepto specific (optional)
917
- // Note:
918
- // In AMD env the global scope should be kept clean, but jQuery is an exception.
919
- // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
920
- // and we should catch that.
921
- var $ = window && (window.jQuery || window.Zepto);
922
- if ($ && !$.ua) {
923
- var parser = new UAParser();
924
- $.ua = parser.getResult();
925
- $.ua.get = function () {
926
- return parser.getUA();
927
- };
928
- $.ua.set = function (uastring) {
929
- parser.setUA(uastring);
930
- var result = parser.getResult();
931
- for (var prop in result) {
932
- $.ua[prop] = result[prop];
933
- }
934
- };
935
- }
936
-
937
- })(typeof window === 'object' ? window : this);
1
+ /*!@license
2
+ * UAParser.js v0.7.25
3
+ * Lightweight JavaScript-based User-Agent string parser
4
+ * https://github.com/faisalman/ua-parser-js
5
+ *
6
+ * Copyright © 2012-2021 Faisal Salman <f@faisalman.com>
7
+ * Licensed under MIT License
8
+ */
9
+
10
+ (function (window, undefined) {
11
+
12
+ 'use strict';
13
+
14
+ //////////////
15
+ // Constants
16
+ /////////////
17
+
18
+
19
+ var LIBVERSION = '0.7.25',
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
+ var mergedRegexes = {};
49
+ for (var i in regexes) {
50
+ if (extensions[i] && extensions[i].length % 2 === 0) {
51
+ mergedRegexes[i] = extensions[i].concat(regexes[i]);
52
+ } else {
53
+ mergedRegexes[i] = regexes[i];
54
+ }
55
+ }
56
+ return mergedRegexes;
57
+ },
58
+ has : function (str1, str2) {
59
+ if (typeof str1 === "string") {
60
+ return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;
61
+ } else {
62
+ return false;
63
+ }
64
+ },
65
+ lowerize : function (str) {
66
+ return str.toLowerCase();
67
+ },
68
+ major : function (version) {
69
+ return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g,'').split(".")[0] : undefined;
70
+ },
71
+ trim : function (str) {
72
+ return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
73
+ }
74
+ };
75
+
76
+
77
+ ///////////////
78
+ // Map helper
79
+ //////////////
80
+
81
+
82
+ var mapper = {
83
+
84
+ rgx : function (ua, arrays) {
85
+
86
+ var i = 0, j, k, p, q, matches, match;
87
+
88
+ // loop through all regexes maps
89
+ while (i < arrays.length && !matches) {
90
+
91
+ var regex = arrays[i], // even sequence (0,2,4,..)
92
+ props = arrays[i + 1]; // odd sequence (1,3,5,..)
93
+ j = k = 0;
94
+
95
+ // try matching uastring with regexes
96
+ while (j < regex.length && !matches) {
97
+
98
+ matches = regex[j++].exec(ua);
99
+
100
+ if (!!matches) {
101
+ for (p = 0; p < props.length; p++) {
102
+ match = matches[++k];
103
+ q = props[p];
104
+ // check if given property is actually array
105
+ if (typeof q === OBJ_TYPE && q.length > 0) {
106
+ if (q.length == 2) {
107
+ if (typeof q[1] == FUNC_TYPE) {
108
+ // assign modified match
109
+ this[q[0]] = q[1].call(this, match);
110
+ } else {
111
+ // assign given value, ignore regex match
112
+ this[q[0]] = q[1];
113
+ }
114
+ } else if (q.length == 3) {
115
+ // check whether function or regex
116
+ if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
117
+ // call function (usually string mapper)
118
+ this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
119
+ } else {
120
+ // sanitize match using given regex
121
+ this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
122
+ }
123
+ } else if (q.length == 4) {
124
+ this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
125
+ }
126
+ } else {
127
+ this[q] = match ? match : undefined;
128
+ }
129
+ }
130
+ }
131
+ }
132
+ i += 2;
133
+ }
134
+ },
135
+
136
+ str : function (str, map) {
137
+
138
+ for (var i in map) {
139
+ // check if array
140
+ if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
141
+ for (var j = 0; j < map[i].length; j++) {
142
+ if (util.has(map[i][j], str)) {
143
+ return (i === UNKNOWN) ? undefined : i;
144
+ }
145
+ }
146
+ } else if (util.has(map[i], str)) {
147
+ return (i === UNKNOWN) ? undefined : i;
148
+ }
149
+ }
150
+ return str;
151
+ }
152
+ };
153
+
154
+
155
+ ///////////////
156
+ // String map
157
+ //////////////
158
+
159
+
160
+ var maps = {
161
+
162
+ browser : {
163
+ oldsafari : {
164
+ version : {
165
+ '1.0' : '/8',
166
+ '1.2' : '/1',
167
+ '1.3' : '/3',
168
+ '2.0' : '/412',
169
+ '2.0.2' : '/416',
170
+ '2.0.3' : '/417',
171
+ '2.0.4' : '/419',
172
+ '?' : '/'
173
+ }
174
+ }
175
+ },
176
+
177
+ device : {
178
+ amazon : {
179
+ model : {
180
+ 'Fire Phone' : ['SD', 'KF']
181
+ }
182
+ },
183
+ sprint : {
184
+ model : {
185
+ 'Evo Shift 4G' : '7373KT'
186
+ },
187
+ vendor : {
188
+ 'HTC' : 'APA',
189
+ 'Sprint' : 'Sprint'
190
+ }
191
+ }
192
+ },
193
+
194
+ os : {
195
+ windows : {
196
+ version : {
197
+ 'ME' : '4.90',
198
+ 'NT 3.11' : 'NT3.51',
199
+ 'NT 4.0' : 'NT4.0',
200
+ '2000' : 'NT 5.0',
201
+ 'XP' : ['NT 5.1', 'NT 5.2'],
202
+ 'Vista' : 'NT 6.0',
203
+ '7' : 'NT 6.1',
204
+ '8' : 'NT 6.2',
205
+ '8.1' : 'NT 6.3',
206
+ '10' : ['NT 6.4', 'NT 10.0'],
207
+ 'RT' : 'ARM'
208
+ }
209
+ }
210
+ }
211
+ };
212
+
213
+
214
+ //////////////
215
+ // Regex map
216
+ /////////////
217
+
218
+
219
+ var regexes = {
220
+
221
+ browser : [[
222
+
223
+ // Presto based
224
+ /(opera\smini)\/([\w\.-]+)/i, // Opera Mini
225
+ /(opera\s[mobiletab]{3,6}).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet
226
+ /(opera).+version\/([\w\.]+)/i, // Opera > 9.80
227
+ /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80
228
+ ], [NAME, VERSION], [
229
+
230
+ /(opios)[\/\s]+([\w\.]+)/i // Opera mini on iphone >= 8.0
231
+ ], [[NAME, 'Opera Mini'], VERSION], [
232
+
233
+ /\s(opr)\/([\w\.]+)/i // Opera Webkit
234
+ ], [[NAME, 'Opera'], VERSION], [
235
+
236
+ // Mixed
237
+ /(kindle)\/([\w\.]+)/i, // Kindle
238
+ /(lunascape|maxthon|netfront|jasmine|blazer|instagram)[\/\s]?([\w\.]*)/i,
239
+ // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Instagram
240
+ // Trident based
241
+ /(avant\s|iemobile|slim)(?:browser)?[\/\s]?([\w\.]*)/i,
242
+ // Avant/IEMobile/SlimBrowser
243
+ /(bidubrowser|baidubrowser)[\/\s]?([\w\.]+)/i, // Baidu Browser
244
+ /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer
245
+
246
+ // Webkit/KHTML based
247
+ /(rekonq)\/([\w\.]*)/i, // Rekonq
248
+ /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon)\/([\w\.-]+)/i,
249
+ // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
250
+ /(puffin|brave|whale|qqbrowserlite|qq)\/([\w\.]+)/i // Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ
251
+ ], [NAME, VERSION], [
252
+
253
+ /(konqueror)\/([\w\.]+)/i // Konqueror
254
+ ], [[NAME, 'Konqueror'], VERSION], [
255
+
256
+ /(trident).+rv[:\s]([\w\.]{1,9}).+like\sgecko/i // IE11
257
+ ], [[NAME, 'IE'], VERSION], [
258
+
259
+ /(edge|edgios|edga|edg)\/((\d+)?[\w\.]+)/i // Microsoft Edge
260
+ ], [[NAME, 'Edge'], VERSION], [
261
+
262
+ /(yabrowser)\/([\w\.]+)/i // Yandex
263
+ ], [[NAME, 'Yandex'], VERSION], [
264
+
265
+ /(Avast)\/([\w\.]+)/i // Avast Secure Browser
266
+ ], [[NAME, 'Avast Secure Browser'], VERSION], [
267
+
268
+ /(AVG)\/([\w\.]+)/i // AVG Secure Browser
269
+ ], [[NAME, 'AVG Secure Browser'], VERSION], [
270
+
271
+ /(focus)\/([\w\.]+)/i // Firefox Focus
272
+ ], [[NAME, 'Firefox Focus'], VERSION], [
273
+
274
+ /(opt)\/([\w\.]+)/i // Opera Touch
275
+ ], [[NAME, 'Opera Touch'], VERSION], [
276
+
277
+ /((?:[\s\/])uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i // UCBrowser
278
+ ], [[NAME, 'UCBrowser'], VERSION], [
279
+
280
+ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
281
+ ], [[NAME, /_/g, ' '], VERSION], [
282
+
283
+ /((?:windowswechat)? qbcore)\/([\w\.]+).*(?:windowswechat)?/i // WeChat Desktop for Windows Built-in Browser
284
+ ], [[NAME, 'WeChat(Win) Desktop'], VERSION], [
285
+
286
+ /(micromessenger)\/([\w\.]+)/i // WeChat
287
+ ], [[NAME, 'WeChat'], VERSION], [
288
+
289
+ /m?(qqbrowser|baiduboxapp|2345Explorer)[\/\s]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser
290
+ ], [NAME, VERSION], [
291
+
292
+ /(MetaSr)[\/\s]?([\w\.]+)/i // SouGouBrowser
293
+ ], [NAME], [
294
+
295
+ /(LBBROWSER)/i // LieBao Browser
296
+ ], [NAME], [
297
+
298
+ /(weibo)__([\d\.]+)/i // Weibo
299
+ ], [NAME, VERSION], [
300
+
301
+ /xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser
302
+ ], [VERSION, [NAME, 'MIUI Browser']], [
303
+
304
+ /;fbav\/([\w\.]+);/i // Facebook App for iOS & Android with version
305
+ ], [VERSION, [NAME, 'Facebook']], [
306
+
307
+ /FBAN\/FBIOS|FB_IAB\/FB4A/i // Facebook App for iOS & Android without version
308
+ ], [[NAME, 'Facebook']], [
309
+
310
+ /safari\s(line)\/([\w\.]+)/i, // Line App for iOS
311
+ /droid.+(line)\/([\w\.]+)\/iab/i // Line App for Android
312
+ ], [NAME, VERSION], [
313
+
314
+ /headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless
315
+ ], [VERSION, [NAME, 'Chrome Headless']], [
316
+
317
+ /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
318
+ ], [[NAME, /(.+)/, '$1 WebView'], VERSION], [
319
+
320
+ /((?:oculus|samsung)browser)\/([\w\.]+)/i
321
+ ], [[NAME, /(.+(?:g|us))(.+)/, '$1 $2'], VERSION], [ // Oculus / Samsung Browser
322
+
323
+ /droid.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)*/i // Android Browser
324
+ ], [VERSION, [NAME, 'Android Browser']], [
325
+
326
+ /(coc_coc_browser)\/([\w\.]+)/i // Coc Coc Browser
327
+ ], [[NAME, 'Coc Coc'], VERSION], [
328
+
329
+ /(sailfishbrowser)\/([\w\.]+)/i // Sailfish Browser
330
+ ], [[NAME, 'Sailfish Browser'], VERSION], [
331
+
332
+ /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i
333
+ // Chrome/OmniWeb/Arora/Tizen/Nokia
334
+ ], [NAME, VERSION], [
335
+
336
+ /(dolfin)\/([\w\.]+)/i // Dolphin
337
+ ], [[NAME, 'Dolphin'], VERSION], [
338
+
339
+ /(qihu|qhbrowser|qihoobrowser|360browser)/i // 360
340
+ ], [[NAME, '360 Browser']], [
341
+
342
+ /((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
343
+ ], [[NAME, 'Chrome'], VERSION], [
344
+
345
+ /(coast)\/([\w\.]+)/i // Opera Coast
346
+ ], [[NAME, 'Opera Coast'], VERSION], [
347
+
348
+ /fxios\/([\w\.-]+)/i // Firefox for iOS
349
+ ], [VERSION, [NAME, 'Firefox']], [
350
+
351
+ /version\/([\w\.]+)\s.*mobile\/\w+\s(safari)/i // Mobile Safari
352
+ ], [VERSION, [NAME, 'Mobile Safari']], [
353
+
354
+ /version\/([\w\.]+)\s.*(mobile\s?safari|safari)/i // Safari & Safari Mobile
355
+ ], [VERSION, NAME], [
356
+
357
+ /webkit.+?(gsa)\/([\w\.]+)\s.*(mobile\s?safari|safari)(\/[\w\.]+)/i // Google Search Appliance on iOS
358
+ ], [[NAME, 'GSA'], VERSION], [
359
+
360
+ /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
361
+ ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [
362
+
363
+ /(webkit|khtml)\/([\w\.]+)/i
364
+ ], [NAME, VERSION], [
365
+
366
+ // Gecko based
367
+ /(navigator|netscape)\/([\w\.-]+)/i // Netscape
368
+ ], [[NAME, 'Netscape'], VERSION], [
369
+ /(swiftfox)/i, // Swiftfox
370
+ /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,
371
+ // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
372
+ /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i,
373
+
374
+ // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
375
+ /(firefox)\/([\w\.]+)\s[\w\s\-]+\/[\w\.]+$/i, // Other Firefox-based
376
+ /(mozilla)\/([\w\.]+)\s.+rv\:.+gecko\/\d+/i, // Mozilla
377
+
378
+ // Other
379
+ /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i,
380
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir
381
+ /(links)\s\(([\w\.]+)/i, // Links
382
+ /(gobrowser)\/?([\w\.]*)/i, // GoBrowser
383
+ /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser
384
+ /(mosaic)[\/\s]([\w\.]+)/i // Mosaic
385
+ ], [NAME, VERSION]
386
+ ],
387
+
388
+ cpu : [[
389
+
390
+ /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i // AMD64
391
+ ], [[ARCHITECTURE, 'amd64']], [
392
+
393
+ /(ia32(?=;))/i // IA32 (quicktime)
394
+ ], [[ARCHITECTURE, util.lowerize]], [
395
+
396
+ /((?:i[346]|x)86)[;\)]/i // IA32
397
+ ], [[ARCHITECTURE, 'ia32']], [
398
+
399
+ // PocketPC mistakenly identified as PowerPC
400
+ /windows\s(ce|mobile);\sppc;/i
401
+ ], [[ARCHITECTURE, 'arm']], [
402
+
403
+ /((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i // PowerPC
404
+ ], [[ARCHITECTURE, /ower/, '', util.lowerize]], [
405
+
406
+ /(sun4\w)[;\)]/i // SPARC
407
+ ], [[ARCHITECTURE, 'sparc']], [
408
+
409
+ /((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+[;l]))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i
410
+ // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
411
+ ], [[ARCHITECTURE, util.lowerize]]
412
+ ],
413
+
414
+ device : [[
415
+
416
+ /\((ipad|playbook);[\w\s\),;-]+(rim|apple)/i // iPad/PlayBook
417
+ ], [MODEL, VENDOR, [TYPE, TABLET]], [
418
+
419
+ /applecoremedia\/[\w\.]+ \((ipad)/ // iPad
420
+ ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [
421
+
422
+ /(apple\s{0,1}tv)/i // Apple TV
423
+ ], [[MODEL, 'Apple TV'], [VENDOR, 'Apple'], [TYPE, SMARTTV]], [
424
+
425
+ /(archos)\s(gamepad2?)/i, // Archos
426
+ /(hp).+(touchpad)/i, // HP TouchPad
427
+ /(hp).+(tablet)/i, // HP Tablet
428
+ /(kindle)\/([\w\.]+)/i, // Kindle
429
+ /\s(nook)[\w\s]+build\/(\w+)/i, // Nook
430
+ /(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak
431
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
432
+
433
+ /(alexa)webm/i,
434
+ /(kf[A-z]+)(\sbuild\/|\)).+silk\//i // Kindle Fire HD
435
+ ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [
436
+ /(sd|kf)[0349hijorstuw]+(\sbuild\/|\)).+silk\//i // Fire Phone
437
+ ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [
438
+ /droid.+aft([\w])(\sbuild\/|\))/i // Fire TV
439
+ ], [MODEL, [VENDOR, 'Amazon'], [TYPE, SMARTTV]], [
440
+
441
+ /\((ip(?:hone|od)[\s\w]*);/i // iPod/iPhone
442
+ ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [
443
+
444
+ /(blackberry)[\s-]?(\w+)/i, // BlackBerry
445
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\s_-]?([\w-]*)/i,
446
+ // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
447
+ /(hp)\s([\w\s]+\w)/i, // HP iPAQ
448
+ /(asus)-?(\w+)/i // Asus
449
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
450
+ /\(bb10;\s(\w+)/i // BlackBerry 10
451
+ ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [
452
+ // Asus Tablets
453
+ /droid.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone|p00c)/i
454
+ ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [
455
+
456
+ /sony\stablet\s[ps]\sbuild\//i, // Sony
457
+ /(?:sony)?sgp\w+(?:\sbuild\/|\))/i
458
+ ], [[MODEL, 'Xperia Tablet'], [VENDOR, 'Sony'], [TYPE, TABLET]], [
459
+ /droid.+\s([c-g]\d{4}|so[-l]\w+|xq-a\w[4-7][12])(?=\sbuild\/|\).+chrome\/(?![1-6]{0,1}\d\.))/i
460
+ ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [
461
+
462
+ /\s(ouya)\s/i, // Ouya
463
+ /(nintendo)\s([wids3utch]+)/i // Nintendo
464
+ ], [VENDOR, MODEL, [TYPE, CONSOLE]], [
465
+
466
+ /droid.+;\s(shield)\sbuild/i // Nvidia
467
+ ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
468
+
469
+ /(playstation\s[345portablevi]+)/i // Playstation
470
+ ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [
471
+
472
+ /(sprint\s(\w+))/i // Sprint Phones
473
+ ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [
474
+
475
+ /(htc)[;_\s-]{1,2}([\w\s]+(?=\)|\sbuild)|\w+)/i, // HTC
476
+ /(zte)-(\w*)/i, // ZTE
477
+ /(alcatel|geeksphone|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i
478
+ // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
479
+ ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
480
+
481
+ /(nexus\s9)/i // HTC Nexus 9
482
+ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
483
+
484
+ /d\/huawei([\w\s-]+)[;\)]/i, // Huawei
485
+ /droid.+\s(nexus\s6p|vog-[at]?l\d\d|ane-[at]?l[x\d]\d|eml-a?l\d\da?|lya-[at]?l\d[\dc]|clt-a?l\d\di?)/i,
486
+ /droid.+\s((?:A(?:GS2?|KA|LP|N[AE]|QM|RE|SK|TH)|B(?:A(?:C|H2)|G2|KL|LA|MH|Z[AKT])|C(?:AZ|DY|LT|OL|[MOR]R)|DUK|E(?:BG|DI|L[ES]|ML|V[AR])|FRD|G(?:LK|RA)|H(?:D[LN]|MA|LK|RY|WI)|INE|J(?:DN2|MM|NY|SN)|K(?:NT|OB|SA)|L(?:IO|LD|ON|[RY]A)|M(?:AR|ED|[HL]A|ON|RX|T7)|N(?:EO|TS|XT)|OXF|P(?:AR|CT|IC|LK|RA)|R(?:IO|VL)|S(?:C[ML]|EA|HT|PN|TF)|T(?:A[HS]|NY)|V(?:[CI]E|KY|OG|RD)|W(?:AS|LZ)|Y(?:635|AL))-[ATU][LN][01259][019])[;\)\s]/i
487
+
488
+ ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [
489
+
490
+ /droid.+(bah2?-a?[lw]\d{2})/i // Huawei MediaPad
491
+ ], [MODEL, [VENDOR, 'Huawei'], [TYPE, TABLET]], [
492
+
493
+ /(microsoft);\s(lumia[\s\w]+)/i // Microsoft Lumia
494
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
495
+
496
+ /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox
497
+ ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [
498
+ /(kin\.[onetw]{3})/i // Microsoft Kin
499
+ ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [
500
+
501
+ // Motorola
502
+ /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)[\w\s]+build\//i,
503
+ /\smot[\s-](\w*)/i,
504
+ /(moto[\s\w\(\)]+(?=\sbuild|\)))/i,
505
+ /(XT\d{3,4}) build\//i,
506
+ /(nexus\s6)/i
507
+ ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [
508
+ /droid.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i
509
+ ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [
510
+
511
+ /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices
512
+ ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [
513
+
514
+ /hbbtv.+maple;(\d+)/i
515
+ ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [
516
+
517
+ /\(dtv[\);].+(aquos)/i // Sharp
518
+ ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
519
+
520
+ /droid.+((sch-i[89]0\d|shw-m380s|SM-P605|SM-P610|SM-P587|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i,
521
+ /((SM-T\w+))/i
522
+ ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung
523
+ /smart-tv.+(samsung)/i
524
+ ], [VENDOR, [TYPE, SMARTTV], MODEL], [
525
+ /((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+))/i,
526
+ /\s(sam)(?:sung)[\s-]([\w-]+)/i,
527
+ /sec-((sgh\w+))/i
528
+ ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [
529
+
530
+ /sie-(\w*)/i // Siemens
531
+ ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
532
+
533
+ /(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia
534
+ /(nokia)[\s_-]?([\w\.-]*)/i
535
+ ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [
536
+
537
+ /droid[x\d\.\s;]+\s([ab][1-7]\-?[0178a]\d\d?)/i // Acer
538
+ ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
539
+
540
+ /droid.+([vl]k\-?\d{3})\s+build/i // LG Tablet
541
+ ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [
542
+ /droid\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet
543
+ ], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [
544
+ /linux;\snetcast.+smarttv/i, // LG SmartTV
545
+ /lg\snetcast\.tv-201\d/i
546
+ ], [[VENDOR, 'LG'], MODEL, [TYPE, SMARTTV]], [
547
+ /(nexus\s[45])/i, // LG
548
+ /lg[e;\s\/-]+(\w*)/i,
549
+ /droid.+lg(\-?[\d\w]+)\s+build/i
550
+ ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [
551
+
552
+ /(lenovo)\s?(s(?:5000|6000)(?:[\w-]+)|tab(?:[\s\w]+)|[\w-]+)/i // Lenovo tablets
553
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
554
+ /droid.+(ideatab[a-z0-9\-\s]+)/i // Lenovo
555
+ ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
556
+ /(lenovo)[_\s-]?([\w-]+)/i
557
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
558
+
559
+ /linux;.+((jolla));/i // Jolla
560
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
561
+
562
+ /((pebble))app\/[\d\.]+\s/i // Pebble
563
+ ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
564
+
565
+ /droid.+;\s(oppo)\s?([\w\s]+)\sbuild/i // OPPO
566
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
567
+
568
+ /crkey/i // Google Chromecast
569
+ ], [[MODEL, 'Chromecast'], [VENDOR, 'Google'], [TYPE, SMARTTV]], [
570
+
571
+ /droid.+;\s(glass)\s\d/i // Google Glass
572
+ ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [
573
+
574
+ /droid.+;\s(pixel c)[\s)]/i // Google Pixel C
575
+ ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [
576
+
577
+ /droid.+;\s(pixel( [2-9]a?)?( xl)?)[\s)]/i // Google Pixel
578
+ ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [
579
+
580
+ /droid.+;\s(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
581
+ /droid.+(hm[\s\-_]?note?[\s_]?(?:\d\w)?)\sbuild/i, // Xiaomi Hongmi
582
+ /droid.+(redmi[\s\-_]?(?:note|k)?(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i,
583
+ // Xiaomi Redmi
584
+ /droid.+(mi[\s\-_]?(?:a\d|one|one[\s_]plus|note lte)?[\s_]?(?:\d?\w?)[\s_]?(?:plus)?)\sbuild/i
585
+ // Xiaomi Mi
586
+ ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [
587
+ /droid.+(mi[\s\-_]?(?:pad)(?:[\s_]?[\w\s]+))(?:\sbuild|\))/i // Mi Pad tablets
588
+ ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [
589
+ /droid.+;\s(m[1-5]\snote)\sbuild/i // Meizu
590
+ ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
591
+ /(mz)-([\w-]{2,})/i
592
+ ], [[VENDOR, 'Meizu'], MODEL, [TYPE, MOBILE]], [
593
+
594
+ /droid.+a000(1)\s+build/i, // OnePlus
595
+ /droid.+oneplus\s(a\d{4})[\s)]/i
596
+ ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
597
+
598
+ /droid.+[;\/]\s*(RCT[\d\w]+)\s+build/i // RCA Tablets
599
+ ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
600
+
601
+ /droid.+[;\/\s](Venue[\d\s]{2,7})\s+build/i // Dell Venue Tablets
602
+ ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
603
+
604
+ /droid.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet
605
+ ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
606
+
607
+ /droid.+[;\/]\s+(Barnes[&\s]+Noble\s+|BN[RT])(\S(?:.*\S)?)\s+build/i
608
+ ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [
609
+
610
+ /droid.+[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet
611
+ ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
612
+
613
+ /droid.+;\s(k88)\sbuild/i // ZTE K Series Tablet
614
+ ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
615
+
616
+ /droid.+;\s(nx\d{3}j)\sbuild/i // ZTE Nubia
617
+ ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
618
+
619
+ /droid.+[;\/]\s*(gen\d{3})\s+build.*49h/i // Swiss GEN Mobile
620
+ ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
621
+
622
+ /droid.+[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet
623
+ ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
624
+
625
+ /droid.+[;\/]\s*((Zeki)?TB.*\b)\s+build/i // Zeki Tablets
626
+ ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
627
+
628
+ /(android).+[;\/]\s+([YR]\d{2})\s+build/i,
629
+ /droid.+[;\/]\s+(Dragon[\-\s]+Touch\s+|DT)(\w{5})\sbuild/i // Dragon Touch Tablet
630
+ ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [
631
+
632
+ /droid.+[;\/]\s*(NS-?\w{0,9})\sbuild/i // Insignia Tablets
633
+ ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
634
+
635
+ /droid.+[;\/]\s*((NXA|Next)-?\w{0,9})\s+build/i // NextBook Tablets
636
+ ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
637
+
638
+ /droid.+[;\/]\s*(Xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i
639
+ ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [ // Voice Xtreme Phones
640
+
641
+ /droid.+[;\/]\s*(LVTEL\-)?(V1[12])\s+build/i // LvTel Phones
642
+ ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
643
+
644
+ /droid.+;\s(PH-1)\s/i
645
+ ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [ // Essential PH-1
646
+
647
+ /droid.+[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i // Envizen Tablets
648
+ ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
649
+
650
+ /droid.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(\w{1,9})\s+build/i // Le Pan Tablets
651
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
652
+
653
+ /droid.+[;\/]\s*(Trio[\s\w\-\.]+)\s+build/i // MachSpeed Tablets
654
+ ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
655
+
656
+ /droid.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i // Trinity Tablets
657
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
658
+
659
+ /droid.+[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets
660
+ ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [
661
+
662
+ //android.+(KS(.+))\s+build/i // Amazon Kindle Tablets
663
+ //], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [
664
+
665
+ /droid.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i // Gigaset Tablets
666
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
667
+
668
+ /[\s\/\(](android\stv|smart-?tv)[;\)\s]/i // SmartTV from Unidentified Vendors
669
+ ], [[TYPE, SMARTTV]], [
670
+ // Android Phones from Unidentified Vendors
671
+ /droid .+?; ([^;]+?)(?: build|\) applewebkit).+? mobile safari/i
672
+ ], [MODEL, [TYPE, MOBILE]], [
673
+ // Android Tablets from Unidentified Vendors
674
+ /droid .+?;\s([^;]+?)(?: build|\) applewebkit).+?(?! mobile) safari/i
675
+ ], [MODEL, [TYPE, TABLET]], [
676
+
677
+ /\s(tablet|tab)[;\/]/i, // Unidentifiable Tablet
678
+ /\s(mobile)(?:[;\/]|\ssafari)/i // Unidentifiable Mobile
679
+ ], [[TYPE, util.lowerize], VENDOR, MODEL], [
680
+
681
+ /(android[\w\.\s\-]{0,9});.+build/i // Generic Android Device
682
+ ], [MODEL, [VENDOR, 'Generic']], [
683
+
684
+ /(phone)/i
685
+ ], [[TYPE, MOBILE]]
686
+ ],
687
+
688
+ engine : [[
689
+
690
+ /windows.+\sedge\/([\w\.]+)/i // EdgeHTML
691
+ ], [VERSION, [NAME, 'EdgeHTML']], [
692
+
693
+ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
694
+ ], [VERSION, [NAME, 'Blink']], [
695
+
696
+ /(presto)\/([\w\.]+)/i, // Presto
697
+ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i,
698
+ // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
699
+ /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links
700
+ /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab
701
+ ], [NAME, VERSION], [
702
+
703
+ /rv\:([\w\.]{1,9}).+(gecko)/i // Gecko
704
+ ], [VERSION, NAME]
705
+ ],
706
+
707
+ os : [[
708
+
709
+ // Xbox, consider this before other Windows-based devices
710
+ /(xbox);\s+xbox\s([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
711
+
712
+ // Windows based
713
+ /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes)
714
+ ], [NAME, VERSION], [
715
+ /(windows)\snt\s6\.2;\s(arm)/i, // Windows RT
716
+ /(windows\sphone(?:\sos)*)[\s\/]?([\d\.\s\w]*)/i, // Windows Phone
717
+ /(windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i
718
+ ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [
719
+ /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i
720
+ ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [
721
+
722
+ // Mobile/Embedded OS
723
+ /\((bb)(10);/i // BlackBerry 10
724
+ ], [[NAME, 'BlackBerry'], VERSION], [
725
+ /(blackberry)\w*\/?([\w\.]*)/i, // Blackberry
726
+ /(tizen|kaios)[\/\s]([\w\.]+)/i, // Tizen/KaiOS
727
+ /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|sailfish|contiki)[\/\s-]?([\w\.]*)/i
728
+ // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki/Sailfish OS
729
+ ], [NAME, VERSION], [
730
+ /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]*)/i // Symbian
731
+ ], [[NAME, 'Symbian'], VERSION], [
732
+ /\((series40);/i // Series 40
733
+ ], [NAME], [
734
+ /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS
735
+ ], [[NAME, 'Firefox OS'], VERSION], [
736
+
737
+ // Google Chromecast
738
+ /crkey\/([\d\.]+)/i // Google Chromecast
739
+ ], [VERSION, [NAME, 'Chromecast']], [
740
+
741
+ // Console
742
+ /(nintendo|playstation)\s([wids345portablevuch]+)/i, // Nintendo/Playstation
743
+
744
+ // GNU/Linux based
745
+ /(mint)[\/\s\(]?(\w*)/i, // Mint
746
+ /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux
747
+ /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|(?=\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?(?!chrom)([\w\.-]*)/i,
748
+ // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
749
+ // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus
750
+ /(hurd|linux)\s?([\w\.]*)/i, // Hurd/Linux
751
+ /(gnu)\s?([\w\.]*)/i // GNU
752
+ ], [NAME, VERSION], [
753
+
754
+ /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS
755
+ ], [[NAME, 'Chromium OS'], VERSION],[
756
+
757
+ // Solaris
758
+ /(sunos)\s?([\w\.\d]*)/i // Solaris
759
+ ], [[NAME, 'Solaris'], VERSION], [
760
+
761
+ // BSD based
762
+ /\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]*)/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly
763
+ ], [NAME, VERSION],[
764
+
765
+ /(haiku)\s(\w+)/i // Haiku
766
+ ], [NAME, VERSION],[
767
+
768
+ /cfnetwork\/.+darwin/i,
769
+ /ip[honead]{2,4}(?:.*os\s([\w]+)\slike\smac|;\sopera)/i // iOS
770
+ ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
771
+
772
+ /(mac\sos\sx)\s?([\w\s\.]*)/i,
773
+ /(macintosh|mac(?=_powerpc)\s)/i // Mac OS
774
+ ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [
775
+
776
+ // Other
777
+ /((?:open)?solaris)[\/\s-]?([\w\.]*)/i, // Solaris
778
+ /(aix)\s((\d)(?=\.|\)|\s)[\w\.])*/i, // AIX
779
+ /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms|fuchsia)/i,
780
+ // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS/Fuchsia
781
+ /(unix)\s?([\w\.]*)/i // UNIX
782
+ ], [NAME, VERSION]
783
+ ]
784
+ };
785
+
786
+
787
+ /////////////////
788
+ // Constructor
789
+ ////////////////
790
+ var UAParser = function (uastring, extensions) {
791
+
792
+ if (typeof uastring === 'object') {
793
+ extensions = uastring;
794
+ uastring = undefined;
795
+ }
796
+
797
+ if (!(this instanceof UAParser)) {
798
+ return new UAParser(uastring, extensions).getResult();
799
+ }
800
+
801
+ var ua = uastring || ((typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
802
+ var rgxmap = extensions ? util.extend(regexes, extensions) : regexes;
803
+
804
+ this.getBrowser = function () {
805
+ var browser = { name: undefined, version: undefined };
806
+ mapper.rgx.call(browser, ua, rgxmap.browser);
807
+ browser.major = util.major(browser.version); // deprecated
808
+ return browser;
809
+ };
810
+ this.getCPU = function () {
811
+ var cpu = { architecture: undefined };
812
+ mapper.rgx.call(cpu, ua, rgxmap.cpu);
813
+ return cpu;
814
+ };
815
+ this.getDevice = function () {
816
+ var device = { vendor: undefined, model: undefined, type: undefined };
817
+ mapper.rgx.call(device, ua, rgxmap.device);
818
+ return device;
819
+ };
820
+ this.getEngine = function () {
821
+ var engine = { name: undefined, version: undefined };
822
+ mapper.rgx.call(engine, ua, rgxmap.engine);
823
+ return engine;
824
+ };
825
+ this.getOS = function () {
826
+ var os = { name: undefined, version: undefined };
827
+ mapper.rgx.call(os, ua, rgxmap.os);
828
+ return os;
829
+ };
830
+ this.getResult = function () {
831
+ return {
832
+ ua : this.getUA(),
833
+ browser : this.getBrowser(),
834
+ engine : this.getEngine(),
835
+ os : this.getOS(),
836
+ device : this.getDevice(),
837
+ cpu : this.getCPU()
838
+ };
839
+ };
840
+ this.getUA = function () {
841
+ return ua;
842
+ };
843
+ this.setUA = function (uastring) {
844
+ ua = uastring;
845
+ return this;
846
+ };
847
+ return this;
848
+ };
849
+
850
+ UAParser.VERSION = LIBVERSION;
851
+ UAParser.BROWSER = {
852
+ NAME : NAME,
853
+ MAJOR : MAJOR, // deprecated
854
+ VERSION : VERSION
855
+ };
856
+ UAParser.CPU = {
857
+ ARCHITECTURE : ARCHITECTURE
858
+ };
859
+ UAParser.DEVICE = {
860
+ MODEL : MODEL,
861
+ VENDOR : VENDOR,
862
+ TYPE : TYPE,
863
+ CONSOLE : CONSOLE,
864
+ MOBILE : MOBILE,
865
+ SMARTTV : SMARTTV,
866
+ TABLET : TABLET,
867
+ WEARABLE: WEARABLE,
868
+ EMBEDDED: EMBEDDED
869
+ };
870
+ UAParser.ENGINE = {
871
+ NAME : NAME,
872
+ VERSION : VERSION
873
+ };
874
+ UAParser.OS = {
875
+ NAME : NAME,
876
+ VERSION : VERSION
877
+ };
878
+
879
+ ///////////
880
+ // Export
881
+ //////////
882
+
883
+
884
+ // check js environment
885
+ if (typeof(exports) !== UNDEF_TYPE) {
886
+ // nodejs env
887
+ if (typeof module !== UNDEF_TYPE && module.exports) {
888
+ exports = module.exports = UAParser;
889
+ }
890
+ exports.UAParser = UAParser;
891
+ } else {
892
+ // requirejs env (optional)
893
+ if (typeof(define) === 'function' && define.amd) {
894
+ define(function () {
895
+ return UAParser;
896
+ });
897
+ } else if (typeof window !== 'undefined') {
898
+ // browser env
899
+ window.UAParser = UAParser;
900
+ }
901
+ }
902
+
903
+ // jQuery/Zepto specific (optional)
904
+ // Note:
905
+ // In AMD env the global scope should be kept clean, but jQuery is an exception.
906
+ // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
907
+ // and we should catch that.
908
+ var $ = typeof window !== 'undefined' && (window.jQuery || window.Zepto);
909
+ if ($ && !$.ua) {
910
+ var parser = new UAParser();
911
+ $.ua = parser.getResult();
912
+ $.ua.get = function () {
913
+ return parser.getUA();
914
+ };
915
+ $.ua.set = function (uastring) {
916
+ parser.setUA(uastring);
917
+ var result = parser.getResult();
918
+ for (var prop in result) {
919
+ $.ua[prop] = result[prop];
920
+ }
921
+ };
922
+ }
923
+
924
+ })(typeof window === 'object' ? window : this);