ua-parser-js 0.7.9 → 0.7.13

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,9 +1,9 @@
1
1
  /**
2
- * UAParser.js v0.7.9
2
+ * UAParser.js v0.7.13
3
3
  * Lightweight JavaScript-based User-Agent string parser
4
4
  * https://github.com/faisalman/ua-parser-js
5
5
  *
6
- * Copyright © 2012-2015 Faisal Salman <fyzlman@gmail.com>
6
+ * Copyright © 2012-2016 Faisal Salman <fyzlman@gmail.com>
7
7
  * Dual licensed under GPLv2 & MIT
8
8
  */
9
9
 
@@ -16,7 +16,7 @@
16
16
  /////////////
17
17
 
18
18
 
19
- var LIBVERSION = '0.7.9',
19
+ var LIBVERSION = '0.7.13',
20
20
  EMPTY = '',
21
21
  UNKNOWN = '?',
22
22
  FUNC_TYPE = 'function',
@@ -45,12 +45,15 @@
45
45
 
46
46
  var util = {
47
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]);
48
+ var margedRegexes = {};
49
+ for (var i in regexes) {
50
+ if (extensions[i] && extensions[i].length % 2 === 0) {
51
+ margedRegexes[i] = extensions[i].concat(regexes[i]);
52
+ } else {
53
+ margedRegexes[i] = regexes[i];
51
54
  }
52
55
  }
53
- return regexes;
56
+ return margedRegexes;
54
57
  },
55
58
  has : function (str1, str2) {
56
59
  if (typeof str1 === "string") {
@@ -63,7 +66,10 @@
63
66
  return str.toLowerCase();
64
67
  },
65
68
  major : function (version) {
66
- return typeof(version) === STR_TYPE ? version.split(".")[0] : undefined;
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, '');
67
73
  }
68
74
  };
69
75
 
@@ -75,33 +81,29 @@
75
81
 
76
82
  var mapper = {
77
83
 
78
- rgx : function () {
84
+ rgx : function (ua, arrays) {
85
+
86
+ //var result = {},
87
+ var i = 0, j, k, p, q, matches, match;//, args = arguments;
79
88
 
80
- var result, i = 0, j, k, p, q, matches, match, args = arguments;
89
+ /*// construct object barebones
90
+ for (p = 0; p < args[1].length; p++) {
91
+ q = args[1][p];
92
+ result[typeof q === OBJ_TYPE ? q[0] : q] = undefined;
93
+ }*/
81
94
 
82
95
  // 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
- }
96
+ while (i < arrays.length && !matches) {
100
97
 
101
- // try matching uastring with regexes
98
+ var regex = arrays[i], // even sequence (0,2,4,..)
99
+ props = arrays[i + 1]; // odd sequence (1,3,5,..)
102
100
  j = k = 0;
101
+
102
+ // try matching uastring with regexes
103
103
  while (j < regex.length && !matches) {
104
- matches = regex[j++].exec(this.getUA());
104
+
105
+ matches = regex[j++].exec(ua);
106
+
105
107
  if (!!matches) {
106
108
  for (p = 0; p < props.length; p++) {
107
109
  match = matches[++k];
@@ -111,32 +113,33 @@
111
113
  if (q.length == 2) {
112
114
  if (typeof q[1] == FUNC_TYPE) {
113
115
  // assign modified match
114
- result[q[0]] = q[1].call(this, match);
116
+ this[q[0]] = q[1].call(this, match);
115
117
  } else {
116
118
  // assign given value, ignore regex match
117
- result[q[0]] = q[1];
119
+ this[q[0]] = q[1];
118
120
  }
119
121
  } else if (q.length == 3) {
120
122
  // check whether function or regex
121
123
  if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
122
124
  // call function (usually string mapper)
123
- result[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
125
+ this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
124
126
  } else {
125
127
  // sanitize match using given regex
126
- result[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
128
+ this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
127
129
  }
128
130
  } else if (q.length == 4) {
129
- result[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
131
+ this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
130
132
  }
131
133
  } else {
132
- result[q] = match ? match : undefined;
134
+ this[q] = match ? match : undefined;
133
135
  }
134
136
  }
135
137
  }
136
138
  }
137
139
  i += 2;
138
140
  }
139
- return result;
141
+ //console.log(this);
142
+ //return this;
140
143
  },
141
144
 
142
145
  str : function (str, map) {
@@ -231,9 +234,11 @@
231
234
  /(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet
232
235
  /(opera).+version\/([\w\.]+)/i, // Opera > 9.80
233
236
  /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80
234
-
235
237
  ], [NAME, VERSION], [
236
238
 
239
+ /(opios)[\/\s]+([\w\.]+)/i // Opera mini on iphone >= 8.0
240
+ ], [[NAME, 'Opera Mini'], VERSION], [
241
+
237
242
  /\s(opr)\/([\w\.]+)/i // Opera Webkit
238
243
  ], [[NAME, 'Opera'], VERSION], [
239
244
 
@@ -249,8 +254,8 @@
249
254
 
250
255
  // Webkit/KHTML based
251
256
  /(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
257
+ /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser)\/([\w\.-]+)/i
258
+ // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser
254
259
  ], [NAME, VERSION], [
255
260
 
256
261
  /(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11
@@ -262,13 +267,43 @@
262
267
  /(yabrowser)\/([\w\.]+)/i // Yandex
263
268
  ], [[NAME, 'Yandex'], VERSION], [
264
269
 
270
+ /(puffin)\/([\w\.]+)/i // Puffin
271
+ ], [[NAME, 'Puffin'], VERSION], [
272
+
273
+ /(uc\s?browser)[\/\s]?([\w\.]+)/i,
274
+ /ucweb.+(ucbrowser)[\/\s]?([\w\.]+)/i,
275
+ /juc.+(ucweb)[\/\s]?([\w\.]+)/i,
276
+ /(ucbrowser)\/([\w\.]+)/i
277
+ // UCBrowser
278
+ ], [[NAME, 'UCBrowser'], VERSION], [
279
+
265
280
  /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
266
281
  ], [[NAME, /_/g, ' '], VERSION], [
267
282
 
268
- /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i,
283
+ /(micromessenger)\/([\w\.]+)/i // WeChat
284
+ ], [[NAME, 'WeChat'], VERSION], [
285
+
286
+ /m?(qqbrowser)[\/\s]?([\w\.]+)/i // QQBrowser
287
+ ], [NAME, VERSION], [
288
+
289
+ /xiaomi\/miuibrowser\/([\w\.]+)/i // MIUI Browser
290
+ ], [VERSION, [NAME, 'MIUI Browser']], [
291
+
292
+ /;fbav\/([\w\.]+);/i // Facebook App for iOS & Android
293
+ ], [VERSION, [NAME, 'Facebook']], [
294
+
295
+ /(headlesschrome) ([\w\.]+)/i // Chrome Headless
296
+ ], [VERSION, [NAME, 'Chrome Headless']], [
297
+
298
+ /\swv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
299
+ ], [[NAME, /(.+)/, '$1 WebView'], VERSION], [
300
+
301
+ /android.+samsungbrowser\/([\w\.]+)/i,
302
+ /android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)*/i // Android Browser
303
+ ], [VERSION, [NAME, 'Android Browser']], [
304
+
305
+ /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i
269
306
  // Chrome/OmniWeb/Arora/Tizen/Nokia
270
- /(uc\s?browser|qqbrowser)[\/\s]?([\w\.]+)/i
271
- // UCBrowser/QQBrowser
272
307
  ], [NAME, VERSION], [
273
308
 
274
309
  /(dolfin)\/([\w\.]+)/i // Dolphin
@@ -277,14 +312,11 @@
277
312
  /((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
278
313
  ], [[NAME, 'Chrome'], VERSION], [
279
314
 
280
- /XiaoMi\/MiuiBrowser\/([\w\.]+)/i // MIUI Browser
281
- ], [VERSION, [NAME, 'MIUI Browser']], [
315
+ /(coast)\/([\w\.]+)/i // Opera Coast
316
+ ], [[NAME, 'Opera Coast'], VERSION], [
282
317
 
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']], [
318
+ /fxios\/([\w\.-]+)/i // Firefox for iOS
319
+ ], [VERSION, [NAME, 'Firefox']], [
288
320
 
289
321
  /version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari
290
322
  ], [VERSION, [NAME, 'Mobile Safari']], [
@@ -302,8 +334,6 @@
302
334
  // Gecko based
303
335
  /(navigator|netscape)\/([\w\.-]+)/i // Netscape
304
336
  ], [[NAME, 'Netscape'], VERSION], [
305
- /fxios\/([\w\.-]+)/i // Firefox for iOS
306
- ], [VERSION, [NAME, 'Firefox']], [
307
337
  /(swiftfox)/i, // Swiftfox
308
338
  /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,
309
339
  // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
@@ -312,8 +342,8 @@
312
342
  /(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla
313
343
 
314
344
  // Other
315
- /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?([\w\.]+)/i,
316
- // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf
345
+ /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i,
346
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir
317
347
  /(links)\s\(([\w\.]+)/i, // Links
318
348
  /(gobrowser)\/?([\w\.]+)*/i, // GoBrowser
319
349
  /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser
@@ -471,6 +501,7 @@
471
501
 
472
502
  /(archos)\s(gamepad2?)/i, // Archos
473
503
  /(hp).+(touchpad)/i, // HP TouchPad
504
+ /(hp).+(tablet)/i, // HP Tablet
474
505
  /(kindle)\/([\w\.]+)/i, // Kindle
475
506
  /\s(nook)[\w\s]+build\/(\w+)/i, // Nook
476
507
  /(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak
@@ -495,7 +526,7 @@
495
526
  /\(bb10;\s(\w+)/i // BlackBerry 10
496
527
  ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [
497
528
  // Asus Tablets
498
- /android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7)/i
529
+ /android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone)/i
499
530
  ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [
500
531
 
501
532
  /(sony)\s(tablet\s[ps])\sbuild\//i, // Sony
@@ -511,7 +542,7 @@
511
542
  /android.+;\s(shield)\sbuild/i // Nvidia
512
543
  ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
513
544
 
514
- /(playstation\s[3portablevi]+)/i // Playstation
545
+ /(playstation\s[34portablevi]+)/i // Playstation
515
546
  ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [
516
547
 
517
548
  /(sprint\s(\w+))/i // Sprint Phones
@@ -525,10 +556,16 @@
525
556
  /(alcatel|geeksphone|huawei|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]+)*/i
526
557
  // Alcatel/GeeksPhone/Huawei/Lenovo/Nexian/Panasonic/Sony
527
558
  ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
528
-
559
+
529
560
  /(nexus\s9)/i // HTC Nexus 9
530
561
  ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
531
562
 
563
+ /(nexus\s6p)/i // Huawei Nexus 6P
564
+ ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [
565
+
566
+ /(microsoft);\s(lumia[\s\w]+)/i // Microsoft Lumia
567
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
568
+
532
569
  /[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox
533
570
  ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [
534
571
  /(kin\.[onetw]{3})/i // Microsoft Kin
@@ -537,23 +574,31 @@
537
574
  // Motorola
538
575
  /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?)[\w\s]+build\//i,
539
576
  /mot[\s-]?(\w+)*/i,
540
- /(XT\d{3,4}) build\//i
577
+ /(XT\d{3,4}) build\//i,
578
+ /(nexus\s6)/i
541
579
  ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [
542
580
  /android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i
543
581
  ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [
544
582
 
545
- /android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n8000|sgh-t8[56]9|nexus 10))/i,
583
+ /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices
584
+ ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [
585
+
586
+ /hbbtv.+maple;(\d+)/i
587
+ ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [
588
+
589
+ /\(dtv[\);].+(aquos)/i // Sharp
590
+ ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
591
+
592
+ /android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i,
546
593
  /((SM-T\w+))/i
547
594
  ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung
548
- /((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-n900))/i,
595
+ /smart-tv.+(samsung)/i
596
+ ], [VENDOR, [TYPE, SMARTTV], MODEL], [
597
+ /((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+))/i,
549
598
  /(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i,
550
599
  /sec-((sgh\w+))/i
551
600
  ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [
552
- /(samsung);smarttv/i
553
- ], [VENDOR, MODEL, [TYPE, SMARTTV]], [
554
601
 
555
- /\(dtv[\);].+(aquos)/i // Sharp
556
- ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
557
602
  /sie-(\w+)*/i // Siemens
558
603
  ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
559
604
 
@@ -581,15 +626,31 @@
581
626
  /((pebble))app\/[\d\.]+\s/i // Pebble
582
627
  ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
583
628
 
629
+ /android.+;\s(oppo)\s?([\w\s]+)\sbuild/i // OPPO
630
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
631
+
632
+ /crkey/i // Google Chromecast
633
+ ], [[MODEL, 'Chromecast'], [VENDOR, 'Google']], [
634
+
584
635
  /android.+;\s(glass)\s\d/i // Google Glass
585
636
  ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [
586
637
 
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
638
+ /android.+;\s(pixel c)\s/i // Google Pixel C
639
+ ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [
640
+
641
+ /android.+;\s(pixel xl|pixel)\s/i // Google Pixel
642
+ ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [
643
+
644
+ /android.+(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
645
+ /android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi
646
+ /android.+(mi[\s\-_]*(?:one|one[\s_]plus|note lte)?[\s_]*(?:\d\w)?)\s+build/i // Xiaomi Mi
590
647
  ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [
591
648
 
592
- /(mobile|tablet);.+rv\:.+gecko\//i // Unidentifiable
649
+ /android.+a000(1)\s+build/i // OnePlus
650
+ ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
651
+
652
+ /\s(tablet)[;\/]/i, // Unidentifiable Tablet
653
+ /\s(mobile)(?:[;\/]|\ssafari)/i // Unidentifiable Mobile
593
654
  ], [[TYPE, util.lowerize], VENDOR, MODEL]
594
655
 
595
656
  /*//////////////////////////
@@ -616,17 +677,6 @@
616
677
  /(SM-T311)/i // Samsung Galaxy Tab 3 8.0
617
678
  ], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [
618
679
 
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
680
  /(T3C)/i // Advan Vandroid T3C
631
681
  ], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [
632
682
  /(ADVAN T1J\+)/i // Advan Vandroid T1J+
@@ -645,7 +695,7 @@
645
695
  ], [VENDOR, MODEL, [TYPE, MOBILE]], [
646
696
  /(i-STYLE2.1)/i // i-mobile i-STYLE 2.1
647
697
  ], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [
648
-
698
+
649
699
  /(mobiistar touch LAI 512)/i // mobiistar touch LAI 512
650
700
  ], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [
651
701
 
@@ -676,7 +726,8 @@
676
726
  /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes)
677
727
  ], [NAME, VERSION], [
678
728
  /(windows)\snt\s6\.2;\s(arm)/i, // Windows RT
679
- /(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i
729
+ /(windows\sphone(?:\sos)*)[\s\/]?([\d\.\s]+\w)*/i, // Windows Phone
730
+ /(windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i
680
731
  ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [
681
732
  /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i
682
733
  ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [
@@ -698,12 +749,12 @@
698
749
  ], [[NAME, 'Firefox OS'], VERSION], [
699
750
 
700
751
  // Console
701
- /(nintendo|playstation)\s([wids3portablevu]+)/i, // Nintendo/Playstation
752
+ /(nintendo|playstation)\s([wids34portablevu]+)/i, // Nintendo/Playstation
702
753
 
703
754
  // GNU/Linux based
704
755
  /(mint)[\/\s\(]?(\w+)*/i, // Mint
705
756
  /(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,
757
+ /(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|(?=\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?(?!chrom)([\w\.-]+)*/i,
707
758
  // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
708
759
  // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus
709
760
  /(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux
@@ -721,7 +772,10 @@
721
772
  /\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly
722
773
  ], [NAME, VERSION],[
723
774
 
724
- /(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i // iOS
775
+ /(haiku)\s(\w+)/i // Haiku
776
+ ], [NAME, VERSION],[
777
+
778
+ /(ip[honead]+)(?:.*os\s([\w]+)*\slike\smac|;\sopera)/i // iOS
725
779
  ], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [
726
780
 
727
781
  /(mac\sos\sx)\s?([\w\s\.]+\w)*/i,
@@ -730,7 +784,6 @@
730
784
 
731
785
  // Other
732
786
  /((?:open)?solaris)[\/\s-]?([\w\.]+)*/i, // Solaris
733
- /(haiku)\s(\w+)/i, // Haiku
734
787
  /(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i, // AIX
735
788
  /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,
736
789
  // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS
@@ -744,6 +797,20 @@
744
797
  // Constructor
745
798
  ////////////////
746
799
 
800
+ var Browser = function (name, version) {
801
+ this[NAME] = name;
802
+ this[VERSION] = version;
803
+ };
804
+ var CPU = function (arch) {
805
+ this[ARCHITECTURE] = arch;
806
+ };
807
+ var Device = function (vendor, model, type) {
808
+ this[VENDOR] = vendor;
809
+ this[MODEL] = model;
810
+ this[TYPE] = type;
811
+ };
812
+ var Engine = Browser;
813
+ var OS = Browser;
747
814
 
748
815
  var UAParser = function (uastring, extensions) {
749
816
 
@@ -753,25 +820,34 @@
753
820
 
754
821
  var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
755
822
  var rgxmap = extensions ? util.extend(regexes, extensions) : regexes;
823
+ var browser = new Browser();
824
+ var cpu = new CPU();
825
+ var device = new Device();
826
+ var engine = new Engine();
827
+ var os = new OS();
756
828
 
757
829
  this.getBrowser = function () {
758
- var browser = mapper.rgx.apply(this, rgxmap.browser);
759
- browser.major = util.major(browser.version);
830
+ mapper.rgx.call(browser, ua, rgxmap.browser);
831
+ browser.major = util.major(browser.version); // deprecated
760
832
  return browser;
761
833
  };
762
834
  this.getCPU = function () {
763
- return mapper.rgx.apply(this, rgxmap.cpu);
835
+ mapper.rgx.call(cpu, ua, rgxmap.cpu);
836
+ return cpu;
764
837
  };
765
838
  this.getDevice = function () {
766
- return mapper.rgx.apply(this, rgxmap.device);
839
+ mapper.rgx.call(device, ua, rgxmap.device);
840
+ return device;
767
841
  };
768
842
  this.getEngine = function () {
769
- return mapper.rgx.apply(this, rgxmap.engine);
843
+ mapper.rgx.call(engine, ua, rgxmap.engine);
844
+ return engine;
770
845
  };
771
846
  this.getOS = function () {
772
- return mapper.rgx.apply(this, rgxmap.os);
847
+ mapper.rgx.call(os, ua, rgxmap.os);
848
+ return os;
773
849
  };
774
- this.getResult = function() {
850
+ this.getResult = function () {
775
851
  return {
776
852
  ua : this.getUA(),
777
853
  browser : this.getBrowser(),
@@ -786,9 +862,13 @@
786
862
  };
787
863
  this.setUA = function (uastring) {
788
864
  ua = uastring;
865
+ browser = new Browser();
866
+ cpu = new CPU();
867
+ device = new Device();
868
+ engine = new Engine();
869
+ os = new OS();
789
870
  return this;
790
871
  };
791
- this.setUA(ua);
792
872
  return this;
793
873
  };
794
874
 
@@ -820,7 +900,7 @@
820
900
  NAME : NAME,
821
901
  VERSION : VERSION
822
902
  };
823
-
903
+ //UAParser.Utils = util;
824
904
 
825
905
  ///////////
826
906
  // Export
@@ -847,7 +927,7 @@
847
927
  }
848
928
 
849
929
  // jQuery/Zepto specific (optional)
850
- // Note:
930
+ // Note:
851
931
  // In AMD env the global scope should be kept clean, but jQuery is an exception.
852
932
  // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
853
933
  // and we should catch that.
@@ -855,7 +935,7 @@
855
935
  if (typeof $ !== UNDEF_TYPE) {
856
936
  var parser = new UAParser();
857
937
  $.ua = parser.getResult();
858
- $.ua.get = function() {
938
+ $.ua.get = function () {
859
939
  return parser.getUA();
860
940
  };
861
941
  $.ua.set = function (uastring) {