ua-parser-js 0.7.17 → 1.0.2
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.
- package/.github/FUNDING.yml +12 -0
- package/.github/workflows/run-test.yml +17 -0
- package/.jshintrc +3 -0
- package/.travis.yml +6 -1
- package/bower.json +2 -2
- package/changelog.md +3 -0
- package/dist/ua-parser.min.js +4 -9
- package/dist/ua-parser.pack.js +4 -9
- package/license.md +21 -0
- package/package.js +1 -1
- package/package.json +92 -15
- package/readme.md +115 -136
- package/security.md +5 -0
- package/src/ua-parser.js +566 -764
- package/test/browser-test.json +489 -4
- package/test/cpu-test.json +105 -1
- package/test/device-test.json +2335 -230
- package/test/engine-test.json +81 -0
- package/test/os-test.json +628 -151
- package/test/test.js +66 -11
- package/.npmignore +0 -24
package/src/ua-parser.js
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
*/
|
1
|
+
/////////////////////////////////////////////////////////////////////////////////
|
2
|
+
/* UAParser.js v1.0.2
|
3
|
+
Copyright © 2012-2021 Faisal Salman <f@faisalman.com>
|
4
|
+
MIT License *//*
|
5
|
+
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
6
|
+
Supports browser & node.js environment.
|
7
|
+
Demo : https://faisalman.github.io/ua-parser-js
|
8
|
+
Source : https://github.com/faisalman/ua-parser-js */
|
9
|
+
/////////////////////////////////////////////////////////////////////////////////
|
9
10
|
|
10
11
|
(function (window, undefined) {
|
11
12
|
|
@@ -16,14 +17,14 @@
|
|
16
17
|
/////////////
|
17
18
|
|
18
19
|
|
19
|
-
var LIBVERSION = '0.
|
20
|
+
var LIBVERSION = '1.0.2',
|
20
21
|
EMPTY = '',
|
21
22
|
UNKNOWN = '?',
|
22
23
|
FUNC_TYPE = 'function',
|
23
24
|
UNDEF_TYPE = 'undefined',
|
24
25
|
OBJ_TYPE = 'object',
|
25
26
|
STR_TYPE = 'string',
|
26
|
-
MAJOR = 'major',
|
27
|
+
MAJOR = 'major',
|
27
28
|
MODEL = 'model',
|
28
29
|
NAME = 'name',
|
29
30
|
TYPE = 'type',
|
@@ -35,62 +36,74 @@
|
|
35
36
|
TABLET = 'tablet',
|
36
37
|
SMARTTV = 'smarttv',
|
37
38
|
WEARABLE = 'wearable',
|
38
|
-
EMBEDDED = 'embedded'
|
39
|
-
|
39
|
+
EMBEDDED = 'embedded',
|
40
|
+
UA_MAX_LENGTH = 255;
|
41
|
+
|
42
|
+
var AMAZON = 'Amazon',
|
43
|
+
APPLE = 'Apple',
|
44
|
+
ASUS = 'ASUS',
|
45
|
+
BLACKBERRY = 'BlackBerry',
|
46
|
+
BROWSER = 'Browser',
|
47
|
+
CHROME = 'Chrome',
|
48
|
+
EDGE = 'Edge',
|
49
|
+
FIREFOX = 'Firefox',
|
50
|
+
GOOGLE = 'Google',
|
51
|
+
HUAWEI = 'Huawei',
|
52
|
+
LG = 'LG',
|
53
|
+
MICROSOFT = 'Microsoft',
|
54
|
+
MOTOROLA = 'Motorola',
|
55
|
+
OPERA = 'Opera',
|
56
|
+
SAMSUNG = 'Samsung',
|
57
|
+
SONY = 'Sony',
|
58
|
+
XIAOMI = 'Xiaomi',
|
59
|
+
ZEBRA = 'Zebra',
|
60
|
+
FACEBOOK = 'Facebook';
|
40
61
|
|
41
62
|
///////////
|
42
63
|
// Helper
|
43
64
|
//////////
|
44
65
|
|
45
|
-
|
46
|
-
|
47
|
-
extend : function (regexes, extensions) {
|
48
|
-
var margedRegexes = {};
|
66
|
+
var extend = function (regexes, extensions) {
|
67
|
+
var mergedRegexes = {};
|
49
68
|
for (var i in regexes) {
|
50
69
|
if (extensions[i] && extensions[i].length % 2 === 0) {
|
51
|
-
|
70
|
+
mergedRegexes[i] = extensions[i].concat(regexes[i]);
|
52
71
|
} else {
|
53
|
-
|
72
|
+
mergedRegexes[i] = regexes[i];
|
54
73
|
}
|
55
74
|
}
|
56
|
-
return
|
75
|
+
return mergedRegexes;
|
76
|
+
},
|
77
|
+
enumerize = function (arr) {
|
78
|
+
var enums = {};
|
79
|
+
for (var i=0; i<arr.length; i++) {
|
80
|
+
enums[arr[i].toUpperCase()] = arr[i];
|
81
|
+
}
|
82
|
+
return enums;
|
57
83
|
},
|
58
|
-
has
|
59
|
-
|
60
|
-
return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;
|
61
|
-
} else {
|
62
|
-
return false;
|
63
|
-
}
|
84
|
+
has = function (str1, str2) {
|
85
|
+
return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
64
86
|
},
|
65
|
-
lowerize
|
87
|
+
lowerize = function (str) {
|
66
88
|
return str.toLowerCase();
|
67
89
|
},
|
68
|
-
|
69
|
-
return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g,
|
90
|
+
majorize = function (version) {
|
91
|
+
return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split('.')[0] : undefined;
|
70
92
|
},
|
71
|
-
trim
|
72
|
-
|
73
|
-
|
93
|
+
trim = function (str, len) {
|
94
|
+
if (typeof(str) === STR_TYPE) {
|
95
|
+
str = str.replace(/^\s\s*/, EMPTY).replace(/\s\s*$/, EMPTY);
|
96
|
+
return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
97
|
+
}
|
74
98
|
};
|
75
99
|
|
76
|
-
|
77
100
|
///////////////
|
78
101
|
// Map helper
|
79
102
|
//////////////
|
80
103
|
|
104
|
+
var rgxMapper = function (ua, arrays) {
|
81
105
|
|
82
|
-
|
83
|
-
|
84
|
-
rgx : function (ua, arrays) {
|
85
|
-
|
86
|
-
//var result = {},
|
87
|
-
var i = 0, j, k, p, q, matches, match;//, args = arguments;
|
88
|
-
|
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
|
-
}*/
|
106
|
+
var i = 0, j, k, p, q, matches, match;
|
94
107
|
|
95
108
|
// loop through all regexes maps
|
96
109
|
while (i < arrays.length && !matches) {
|
@@ -110,7 +123,7 @@
|
|
110
123
|
q = props[p];
|
111
124
|
// check if given property is actually array
|
112
125
|
if (typeof q === OBJ_TYPE && q.length > 0) {
|
113
|
-
if (q.length
|
126
|
+
if (q.length === 2) {
|
114
127
|
if (typeof q[1] == FUNC_TYPE) {
|
115
128
|
// assign modified match
|
116
129
|
this[q[0]] = q[1].call(this, match);
|
@@ -118,7 +131,7 @@
|
|
118
131
|
// assign given value, ignore regex match
|
119
132
|
this[q[0]] = q[1];
|
120
133
|
}
|
121
|
-
} else if (q.length
|
134
|
+
} else if (q.length === 3) {
|
122
135
|
// check whether function or regex
|
123
136
|
if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
|
124
137
|
// call function (usually string mapper)
|
@@ -127,7 +140,7 @@
|
|
127
140
|
// sanitize match using given regex
|
128
141
|
this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
|
129
142
|
}
|
130
|
-
} else if (q.length
|
143
|
+
} else if (q.length === 4) {
|
131
144
|
this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
|
132
145
|
}
|
133
146
|
} else {
|
@@ -138,807 +151,654 @@
|
|
138
151
|
}
|
139
152
|
i += 2;
|
140
153
|
}
|
141
|
-
// console.log(this);
|
142
|
-
//return this;
|
143
154
|
},
|
144
155
|
|
145
|
-
|
156
|
+
strMapper = function (str, map) {
|
146
157
|
|
147
158
|
for (var i in map) {
|
148
|
-
// check if array
|
159
|
+
// check if current value is array
|
149
160
|
if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
|
150
161
|
for (var j = 0; j < map[i].length; j++) {
|
151
|
-
if (
|
162
|
+
if (has(map[i][j], str)) {
|
152
163
|
return (i === UNKNOWN) ? undefined : i;
|
153
164
|
}
|
154
165
|
}
|
155
|
-
} else if (
|
166
|
+
} else if (has(map[i], str)) {
|
156
167
|
return (i === UNKNOWN) ? undefined : i;
|
157
168
|
}
|
158
169
|
}
|
159
170
|
return str;
|
160
|
-
}
|
161
171
|
};
|
162
172
|
|
163
|
-
|
164
173
|
///////////////
|
165
174
|
// String map
|
166
175
|
//////////////
|
167
176
|
|
168
|
-
|
169
|
-
var
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
'2.0.2' : '/416',
|
179
|
-
'2.0.3' : '/417',
|
180
|
-
'2.0.4' : '/419',
|
181
|
-
'?' : '/'
|
182
|
-
}
|
183
|
-
}
|
177
|
+
// Safari < 3.0
|
178
|
+
var oldSafariMap = {
|
179
|
+
'1.0' : '/8',
|
180
|
+
'1.2' : '/1',
|
181
|
+
'1.3' : '/3',
|
182
|
+
'2.0' : '/412',
|
183
|
+
'2.0.2' : '/416',
|
184
|
+
'2.0.3' : '/417',
|
185
|
+
'2.0.4' : '/419',
|
186
|
+
'?' : '/'
|
184
187
|
},
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
'HTC' : 'APA',
|
198
|
-
'Sprint' : 'Sprint'
|
199
|
-
}
|
200
|
-
}
|
201
|
-
},
|
202
|
-
|
203
|
-
os : {
|
204
|
-
windows : {
|
205
|
-
version : {
|
206
|
-
'ME' : '4.90',
|
207
|
-
'NT 3.11' : 'NT3.51',
|
208
|
-
'NT 4.0' : 'NT4.0',
|
209
|
-
'2000' : 'NT 5.0',
|
210
|
-
'XP' : ['NT 5.1', 'NT 5.2'],
|
211
|
-
'Vista' : 'NT 6.0',
|
212
|
-
'7' : 'NT 6.1',
|
213
|
-
'8' : 'NT 6.2',
|
214
|
-
'8.1' : 'NT 6.3',
|
215
|
-
'10' : ['NT 6.4', 'NT 10.0'],
|
216
|
-
'RT' : 'ARM'
|
217
|
-
}
|
218
|
-
}
|
219
|
-
}
|
188
|
+
windowsVersionMap = {
|
189
|
+
'ME' : '4.90',
|
190
|
+
'NT 3.11' : 'NT3.51',
|
191
|
+
'NT 4.0' : 'NT4.0',
|
192
|
+
'2000' : 'NT 5.0',
|
193
|
+
'XP' : ['NT 5.1', 'NT 5.2'],
|
194
|
+
'Vista' : 'NT 6.0',
|
195
|
+
'7' : 'NT 6.1',
|
196
|
+
'8' : 'NT 6.2',
|
197
|
+
'8.1' : 'NT 6.3',
|
198
|
+
'10' : ['NT 6.4', 'NT 10.0'],
|
199
|
+
'RT' : 'ARM'
|
220
200
|
};
|
221
201
|
|
222
|
-
|
223
202
|
//////////////
|
224
203
|
// Regex map
|
225
204
|
/////////////
|
226
205
|
|
227
|
-
|
228
206
|
var regexes = {
|
229
207
|
|
230
208
|
browser : [[
|
231
209
|
|
210
|
+
/\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
|
211
|
+
], [VERSION, [NAME, 'Chrome']], [
|
212
|
+
/edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge
|
213
|
+
], [VERSION, [NAME, 'Edge']], [
|
214
|
+
|
232
215
|
// Presto based
|
233
|
-
/(opera
|
234
|
-
/(opera
|
235
|
-
/(opera)
|
236
|
-
/(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80
|
216
|
+
/(opera mini)\/([-\w\.]+)/i, // Opera Mini
|
217
|
+
/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet
|
218
|
+
/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera
|
237
219
|
], [NAME, VERSION], [
|
238
|
-
|
239
|
-
|
240
|
-
]
|
241
|
-
|
242
|
-
/\s(opr)\/([\w\.]+)/i // Opera Webkit
|
243
|
-
], [[NAME, 'Opera'], VERSION], [
|
220
|
+
/opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
|
221
|
+
], [VERSION, [NAME, OPERA+' Mini']], [
|
222
|
+
/\bopr\/([\w\.]+)/i // Opera Webkit
|
223
|
+
], [VERSION, [NAME, OPERA]], [
|
244
224
|
|
245
225
|
// Mixed
|
246
226
|
/(kindle)\/([\w\.]+)/i, // Kindle
|
247
|
-
/(lunascape|maxthon|netfront|jasmine|blazer)[
|
248
|
-
// Lunascape/Maxthon/Netfront/Jasmine/Blazer
|
249
|
-
|
227
|
+
/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
|
250
228
|
// Trident based
|
251
|
-
/(avant
|
252
|
-
|
253
|
-
/(?:ms|\()(ie)
|
254
|
-
|
255
|
-
// Webkit/KHTML based
|
256
|
-
/(rekonq)\/([
|
257
|
-
|
258
|
-
|
229
|
+
/(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
|
230
|
+
/(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser
|
231
|
+
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
232
|
+
|
233
|
+
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
|
234
|
+
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([-\w\.]+)/i,
|
235
|
+
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ
|
236
|
+
/(weibo)__([\d\.]+)/i // Weibo
|
259
237
|
], [NAME, VERSION], [
|
260
|
-
|
261
|
-
|
262
|
-
]
|
263
|
-
|
264
|
-
/
|
265
|
-
], [NAME,
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
/
|
271
|
-
], [[NAME, '
|
272
|
-
|
273
|
-
/(
|
274
|
-
|
275
|
-
], [[NAME, '
|
276
|
-
|
238
|
+
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
239
|
+
], [VERSION, [NAME, 'UC'+BROWSER]], [
|
240
|
+
/\bqbcore\/([\w\.]+)/i // WeChat Desktop for Windows Built-in Browser
|
241
|
+
], [VERSION, [NAME, 'WeChat(Win) Desktop']], [
|
242
|
+
/micromessenger\/([\w\.]+)/i // WeChat
|
243
|
+
], [VERSION, [NAME, 'WeChat']], [
|
244
|
+
/konqueror\/([\w\.]+)/i // Konqueror
|
245
|
+
], [VERSION, [NAME, 'Konqueror']], [
|
246
|
+
/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11
|
247
|
+
], [VERSION, [NAME, 'IE']], [
|
248
|
+
/yabrowser\/([\w\.]+)/i // Yandex
|
249
|
+
], [VERSION, [NAME, 'Yandex']], [
|
250
|
+
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
|
251
|
+
], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [
|
252
|
+
/\bfocus\/([\w\.]+)/i // Firefox Focus
|
253
|
+
], [VERSION, [NAME, FIREFOX+' Focus']], [
|
254
|
+
/\bopt\/([\w\.]+)/i // Opera Touch
|
255
|
+
], [VERSION, [NAME, OPERA+' Touch']], [
|
256
|
+
/coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser
|
257
|
+
], [VERSION, [NAME, 'Coc Coc']], [
|
258
|
+
/dolfin\/([\w\.]+)/i // Dolphin
|
259
|
+
], [VERSION, [NAME, 'Dolphin']], [
|
260
|
+
/coast\/([\w\.]+)/i // Opera Coast
|
261
|
+
], [VERSION, [NAME, OPERA+' Coast']], [
|
262
|
+
/miuibrowser\/([\w\.]+)/i // MIUI Browser
|
263
|
+
], [VERSION, [NAME, 'MIUI '+BROWSER]], [
|
264
|
+
/fxios\/([-\w\.]+)/i // Firefox for iOS
|
265
|
+
], [VERSION, [NAME, FIREFOX]], [
|
266
|
+
/\bqihu|(qi?ho?o?|360)browser/i // 360
|
267
|
+
], [[NAME, '360 '+BROWSER]], [
|
268
|
+
/(oculus|samsung|sailfish)browser\/([\w\.]+)/i
|
269
|
+
], [[NAME, /(.+)/, '$1 '+BROWSER], VERSION], [ // Oculus/Samsung/Sailfish Browser
|
277
270
|
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
|
278
271
|
], [[NAME, /_/g, ' '], VERSION], [
|
279
|
-
|
280
|
-
/(
|
281
|
-
|
282
|
-
|
283
|
-
/(QQ)\/([\d\.]+)/i // QQ, aka ShouQ
|
272
|
+
/(electron)\/([\w\.]+) safari/i, // Electron-based App
|
273
|
+
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
274
|
+
/m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser
|
284
275
|
], [NAME, VERSION], [
|
276
|
+
/(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser
|
277
|
+
/(lbbrowser)/i // LieBao Browser
|
278
|
+
], [NAME], [
|
285
279
|
|
286
|
-
|
280
|
+
// WebView
|
281
|
+
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
|
282
|
+
], [[NAME, FACEBOOK], VERSION], [
|
283
|
+
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
284
|
+
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
285
|
+
/(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram
|
287
286
|
], [NAME, VERSION], [
|
287
|
+
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
288
|
+
], [VERSION, [NAME, 'GSA']], [
|
288
289
|
|
289
|
-
/
|
290
|
-
], [VERSION, [NAME, '
|
291
|
-
|
292
|
-
/;fbav\/([\w\.]+);/i // Facebook App for iOS & Android
|
293
|
-
], [VERSION, [NAME, 'Facebook']], [
|
294
|
-
|
295
|
-
/headlesschrome(?:\/([\w\.]+)|\s)/i // Chrome Headless
|
296
|
-
], [VERSION, [NAME, 'Chrome Headless']], [
|
290
|
+
/headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
|
291
|
+
], [VERSION, [NAME, CHROME+' Headless']], [
|
297
292
|
|
298
|
-
|
299
|
-
], [[NAME,
|
293
|
+
/ wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
|
294
|
+
], [[NAME, CHROME+' WebView'], VERSION], [
|
300
295
|
|
301
|
-
/
|
302
|
-
], [[NAME,
|
296
|
+
/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
|
297
|
+
], [VERSION, [NAME, 'Android '+BROWSER]], [
|
303
298
|
|
304
|
-
/
|
305
|
-
], [VERSION, [NAME, 'Android Browser']], [
|
306
|
-
|
307
|
-
/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i
|
308
|
-
// Chrome/OmniWeb/Arora/Tizen/Nokia
|
299
|
+
/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia
|
309
300
|
], [NAME, VERSION], [
|
310
301
|
|
311
|
-
/
|
312
|
-
], [[NAME, 'Dolphin'], VERSION], [
|
313
|
-
|
314
|
-
/((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
|
315
|
-
], [[NAME, 'Chrome'], VERSION], [
|
316
|
-
|
317
|
-
/(coast)\/([\w\.]+)/i // Opera Coast
|
318
|
-
], [[NAME, 'Opera Coast'], VERSION], [
|
319
|
-
|
320
|
-
/fxios\/([\w\.-]+)/i // Firefox for iOS
|
321
|
-
], [VERSION, [NAME, 'Firefox']], [
|
322
|
-
|
323
|
-
/version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari
|
302
|
+
/version\/([\w\.]+) .*mobile\/\w+ (safari)/i // Mobile Safari
|
324
303
|
], [VERSION, [NAME, 'Mobile Safari']], [
|
325
|
-
|
326
|
-
/version\/([\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile
|
304
|
+
/version\/([\w\.]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile
|
327
305
|
], [VERSION, NAME], [
|
306
|
+
/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
|
307
|
+
], [NAME, [VERSION, strMapper, oldSafariMap]], [
|
328
308
|
|
329
|
-
/webkit.+?(gsa)\/([\w\.]+).+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Google Search Appliance on iOS
|
330
|
-
], [[NAME, 'GSA'], VERSION], [
|
331
|
-
|
332
|
-
/webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
|
333
|
-
], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [
|
334
|
-
|
335
|
-
/(konqueror)\/([\w\.]+)/i, // Konqueror
|
336
309
|
/(webkit|khtml)\/([\w\.]+)/i
|
337
310
|
], [NAME, VERSION], [
|
338
311
|
|
339
312
|
// Gecko based
|
340
|
-
/(navigator|netscape)\/([
|
313
|
+
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
|
341
314
|
], [[NAME, 'Netscape'], VERSION], [
|
315
|
+
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
|
316
|
+
], [VERSION, [NAME, FIREFOX+' Reality']], [
|
317
|
+
/ekiohf.+(flow)\/([\w\.]+)/i, // Flow
|
342
318
|
/(swiftfox)/i, // Swiftfox
|
343
|
-
/(icedragon|iceweasel|camino|chimera|fennec|maemo
|
344
|
-
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
345
|
-
/(
|
319
|
+
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
|
320
|
+
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
|
321
|
+
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
346
322
|
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
347
|
-
/(
|
323
|
+
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
324
|
+
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
|
348
325
|
|
349
326
|
// Other
|
350
|
-
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[
|
351
|
-
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir
|
352
|
-
/(links)\
|
353
|
-
/(gobrowser)\/?([\w\.]+)*/i, // GoBrowser
|
354
|
-
/(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser
|
355
|
-
/(mosaic)[\/\s]([\w\.]+)/i // Mosaic
|
327
|
+
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
328
|
+
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
|
329
|
+
/(links) \(([\w\.]+)/i // Links
|
356
330
|
], [NAME, VERSION]
|
357
|
-
|
358
|
-
/* /////////////////////
|
359
|
-
// Media players BEGIN
|
360
|
-
////////////////////////
|
361
|
-
|
362
|
-
, [
|
363
|
-
|
364
|
-
/(apple(?:coremedia|))\/((\d+)[\w\._]+)/i, // Generic Apple CoreMedia
|
365
|
-
/(coremedia) v((\d+)[\w\._]+)/i
|
366
|
-
], [NAME, VERSION], [
|
367
|
-
|
368
|
-
/(aqualung|lyssna|bsplayer)\/((\d+)?[\w\.-]+)/i // Aqualung/Lyssna/BSPlayer
|
369
|
-
], [NAME, VERSION], [
|
370
|
-
|
371
|
-
/(ares|ossproxy)\s((\d+)[\w\.-]+)/i // Ares/OSSProxy
|
372
|
-
], [NAME, VERSION], [
|
373
|
-
|
374
|
-
/(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/((\d+)[\w\.-]+)/i,
|
375
|
-
// Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC
|
376
|
-
// NSPlayer/PSP-InternetRadioPlayer/Videos
|
377
|
-
/(clementine|music player daemon)\s((\d+)[\w\.-]+)/i, // Clementine/MPD
|
378
|
-
/(lg player|nexplayer)\s((\d+)[\d\.]+)/i,
|
379
|
-
/player\/(nexplayer|lg player)\s((\d+)[\w\.-]+)/i // NexPlayer/LG Player
|
380
|
-
], [NAME, VERSION], [
|
381
|
-
/(nexplayer)\s((\d+)[\w\.-]+)/i // Nexplayer
|
382
|
-
], [NAME, VERSION], [
|
383
|
-
|
384
|
-
/(flrp)\/((\d+)[\w\.-]+)/i // Flip Player
|
385
|
-
], [[NAME, 'Flip Player'], VERSION], [
|
386
|
-
|
387
|
-
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i
|
388
|
-
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit
|
389
|
-
], [NAME], [
|
390
|
-
|
391
|
-
/(gstreamer) souphttpsrc (?:\([^\)]+\)){0,1} libsoup\/((\d+)[\w\.-]+)/i
|
392
|
-
// Gstreamer
|
393
|
-
], [NAME, VERSION], [
|
394
|
-
|
395
|
-
/(htc streaming player)\s[\w_]+\s\/\s((\d+)[\d\.]+)/i, // HTC Streaming Player
|
396
|
-
/(java|python-urllib|python-requests|wget|libcurl)\/((\d+)[\w\.-_]+)/i,
|
397
|
-
// Java/urllib/requests/wget/cURL
|
398
|
-
/(lavf)((\d+)[\d\.]+)/i // Lavf (FFMPEG)
|
399
|
-
], [NAME, VERSION], [
|
400
|
-
|
401
|
-
/(htc_one_s)\/((\d+)[\d\.]+)/i // HTC One S
|
402
|
-
], [[NAME, /_/g, ' '], VERSION], [
|
403
|
-
|
404
|
-
/(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+){0,1})/i
|
405
|
-
// MPlayer SVN
|
406
|
-
], [NAME, VERSION], [
|
407
|
-
|
408
|
-
/(mplayer)(?:\s|\/|[unkow-]+)((\d+)[\w\.-]+)/i // MPlayer
|
409
|
-
], [NAME, VERSION], [
|
410
|
-
|
411
|
-
/(mplayer)/i, // MPlayer (no other info)
|
412
|
-
/(yourmuze)/i, // YourMuze
|
413
|
-
/(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime
|
414
|
-
], [NAME], [
|
415
|
-
|
416
|
-
/(nero (?:home|scout))\/((\d+)[\w\.-]+)/i // Nero Home/Nero Scout
|
417
|
-
], [NAME, VERSION], [
|
418
|
-
|
419
|
-
/(nokia\d+)\/((\d+)[\w\.-]+)/i // Nokia
|
420
|
-
], [NAME, VERSION], [
|
421
|
-
|
422
|
-
/\s(songbird)\/((\d+)[\w\.-]+)/i // Songbird/Philips-Songbird
|
423
|
-
], [NAME, VERSION], [
|
424
|
-
|
425
|
-
/(winamp)3 version ((\d+)[\w\.-]+)/i, // Winamp
|
426
|
-
/(winamp)\s((\d+)[\w\.-]+)/i,
|
427
|
-
/(winamp)mpeg\/((\d+)[\w\.-]+)/i
|
428
|
-
], [NAME, VERSION], [
|
429
|
-
|
430
|
-
/(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
|
431
|
-
// inlight radio
|
432
|
-
], [NAME], [
|
433
|
-
|
434
|
-
/(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/((\d+)[\w\.-]+)/i
|
435
|
-
// QuickTime/RealMedia/RadioApp/RadioClientApplication/
|
436
|
-
// SoundTap/Totem/Stagefright/Streamium
|
437
|
-
], [NAME, VERSION], [
|
438
|
-
|
439
|
-
/(smp)((\d+)[\d\.]+)/i // SMP
|
440
|
-
], [NAME, VERSION], [
|
441
|
-
|
442
|
-
/(vlc) media player - version ((\d+)[\w\.]+)/i, // VLC Videolan
|
443
|
-
/(vlc)\/((\d+)[\w\.-]+)/i,
|
444
|
-
/(xbmc|gvfs|xine|xmms|irapp)\/((\d+)[\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp
|
445
|
-
/(foobar2000)\/((\d+)[\d\.]+)/i, // Foobar2000
|
446
|
-
/(itunes)\/((\d+)[\d\.]+)/i // iTunes
|
447
|
-
], [NAME, VERSION], [
|
448
|
-
|
449
|
-
/(wmplayer)\/((\d+)[\w\.-]+)/i, // Windows Media Player
|
450
|
-
/(windows-media-player)\/((\d+)[\w\.-]+)/i
|
451
|
-
], [[NAME, /-/g, ' '], VERSION], [
|
452
|
-
|
453
|
-
/windows\/((\d+)[\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i
|
454
|
-
// Windows Media Server
|
455
|
-
], [VERSION, [NAME, 'Windows']], [
|
456
|
-
|
457
|
-
/(com\.riseupradioalarm)\/((\d+)[\d\.]*)/i // RiseUP Radio Alarm
|
458
|
-
], [NAME, VERSION], [
|
459
|
-
|
460
|
-
/(rad.io)\s((\d+)[\d\.]+)/i, // Rad.io
|
461
|
-
/(radio.(?:de|at|fr))\s((\d+)[\d\.]+)/i
|
462
|
-
], [[NAME, 'rad.io'], VERSION]
|
463
|
-
|
464
|
-
//////////////////////
|
465
|
-
// Media players END
|
466
|
-
////////////////////*/
|
467
|
-
|
468
331
|
],
|
469
332
|
|
470
333
|
cpu : [[
|
471
334
|
|
472
|
-
/(?:(amd|x(?:(?:86|64)[_
|
335
|
+
/(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i // AMD64 (x64)
|
473
336
|
], [[ARCHITECTURE, 'amd64']], [
|
474
337
|
|
475
338
|
/(ia32(?=;))/i // IA32 (quicktime)
|
476
|
-
], [[ARCHITECTURE,
|
339
|
+
], [[ARCHITECTURE, lowerize]], [
|
477
340
|
|
478
|
-
/((?:i[346]|x)86)[;\)]/i // IA32
|
341
|
+
/((?:i[346]|x)86)[;\)]/i // IA32 (x86)
|
479
342
|
], [[ARCHITECTURE, 'ia32']], [
|
480
343
|
|
344
|
+
/\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64
|
345
|
+
], [[ARCHITECTURE, 'arm64']], [
|
346
|
+
|
347
|
+
/\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF
|
348
|
+
], [[ARCHITECTURE, 'armhf']], [
|
349
|
+
|
481
350
|
// PocketPC mistakenly identified as PowerPC
|
482
|
-
/windows
|
351
|
+
/windows (ce|mobile); ppc;/i
|
483
352
|
], [[ARCHITECTURE, 'arm']], [
|
484
353
|
|
485
|
-
/((?:ppc|powerpc)(?:64)?)(
|
486
|
-
], [[ARCHITECTURE, /ower/,
|
354
|
+
/((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC
|
355
|
+
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
|
487
356
|
|
488
357
|
/(sun4\w)[;\)]/i // SPARC
|
489
358
|
], [[ARCHITECTURE, 'sparc']], [
|
490
359
|
|
491
|
-
/((?:avr32|ia64(?=;))|68k(?=\))
|
360
|
+
/((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i
|
492
361
|
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
|
493
|
-
], [[ARCHITECTURE,
|
362
|
+
], [[ARCHITECTURE, lowerize]]
|
494
363
|
],
|
495
364
|
|
496
365
|
device : [[
|
497
366
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
], [
|
506
|
-
|
507
|
-
/(
|
508
|
-
/(
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
], [VENDOR,
|
514
|
-
|
515
|
-
/
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
/\((
|
521
|
-
], [MODEL, VENDOR, [TYPE,
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
/\(
|
532
|
-
], [MODEL,
|
533
|
-
|
534
|
-
/
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
], [
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
/\
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
], [MODEL, [VENDOR, '
|
549
|
-
|
550
|
-
|
551
|
-
]
|
552
|
-
|
553
|
-
/(
|
554
|
-
], [
|
367
|
+
//////////////////////////
|
368
|
+
// MOBILES & TABLETS
|
369
|
+
// Ordered by popularity
|
370
|
+
/////////////////////////
|
371
|
+
|
372
|
+
// Samsung
|
373
|
+
/\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
|
374
|
+
], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
|
375
|
+
/\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i,
|
376
|
+
/samsung[- ]([-\w]+)/i,
|
377
|
+
/sec-(sgh\w+)/i
|
378
|
+
], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
|
379
|
+
|
380
|
+
// Apple
|
381
|
+
/\((ip(?:hone|od)[\w ]*);/i // iPod/iPhone
|
382
|
+
], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [
|
383
|
+
/\((ipad);[-\w\),; ]+apple/i, // iPad
|
384
|
+
/applecoremedia\/[\w\.]+ \((ipad)/i,
|
385
|
+
/\b(ipad)\d\d?,\d\d?[;\]].+ios/i
|
386
|
+
], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [
|
387
|
+
|
388
|
+
// Huawei
|
389
|
+
/\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
|
390
|
+
], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
|
391
|
+
/(?:huawei|honor)([-\w ]+)[;\)]/i,
|
392
|
+
/\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i
|
393
|
+
], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
|
394
|
+
|
395
|
+
// Xiaomi
|
396
|
+
/\b(poco[\w ]+)(?: bui|\))/i, // Xiaomi POCO
|
397
|
+
/\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
|
398
|
+
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
|
399
|
+
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
|
400
|
+
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
|
401
|
+
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
402
|
+
/\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
|
403
|
+
],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
|
404
|
+
|
405
|
+
// OPPO
|
406
|
+
/; (\w+) bui.+ oppo/i,
|
407
|
+
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
408
|
+
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
|
409
|
+
|
410
|
+
// Vivo
|
411
|
+
/vivo (\w+)(?: bui|\))/i,
|
412
|
+
/\b(v[12]\d{3}\w?[at])(?: bui|;)/i
|
413
|
+
], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [
|
414
|
+
|
415
|
+
// Realme
|
416
|
+
/\b(rmx[12]\d{3})(?: bui|;|\))/i
|
417
|
+
], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
|
418
|
+
|
419
|
+
// Motorola
|
420
|
+
/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
|
421
|
+
/\bmot(?:orola)?[- ](\w*)/i,
|
422
|
+
/((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i
|
423
|
+
], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [
|
424
|
+
/\b(mz60\d|xoom[2 ]{0,2}) build\//i
|
425
|
+
], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [
|
426
|
+
|
427
|
+
// LG
|
428
|
+
/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
|
429
|
+
], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [
|
430
|
+
/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
|
431
|
+
/\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i,
|
432
|
+
/\blg-?([\d\w]+) bui/i
|
433
|
+
], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [
|
434
|
+
|
435
|
+
// Lenovo
|
436
|
+
/(ideatab[-\w ]+)/i,
|
437
|
+
/lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
|
438
|
+
], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
|
555
439
|
|
556
|
-
|
557
|
-
|
440
|
+
// Nokia
|
441
|
+
/(?:maemo|nokia).*(n900|lumia \d+)/i,
|
442
|
+
/nokia[-_ ]?([-\w\.]*)/i
|
443
|
+
], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [
|
444
|
+
|
445
|
+
// Google
|
446
|
+
/(pixel c)\b/i // Google Pixel C
|
447
|
+
], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [
|
448
|
+
/droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel
|
449
|
+
], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
|
450
|
+
|
451
|
+
// Sony
|
452
|
+
/droid.+ ([c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
|
453
|
+
], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
|
454
|
+
/sony tablet [ps]/i,
|
455
|
+
/\b(?:sony)?sgp\w+(?: bui|\))/i
|
456
|
+
], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [
|
457
|
+
|
458
|
+
// OnePlus
|
459
|
+
/ (kb2005|in20[12]5|be20[12][59])\b/i,
|
460
|
+
/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
|
461
|
+
], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
|
558
462
|
|
559
|
-
|
560
|
-
/(
|
561
|
-
/(
|
562
|
-
|
563
|
-
], [
|
463
|
+
// Amazon
|
464
|
+
/(alexa)webm/i,
|
465
|
+
/(kf[a-z]{2}wi)( bui|\))/i, // Kindle Fire without Silk
|
466
|
+
/(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
|
467
|
+
], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
|
468
|
+
/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
|
469
|
+
], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [
|
564
470
|
|
565
|
-
|
471
|
+
// BlackBerry
|
472
|
+
/(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook
|
473
|
+
], [MODEL, VENDOR, [TYPE, TABLET]], [
|
474
|
+
/\b((?:bb[a-f]|st[hv])100-\d)/i,
|
475
|
+
/\(bb10; (\w+)/i // BlackBerry 10
|
476
|
+
], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [
|
477
|
+
|
478
|
+
// Asus
|
479
|
+
/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
|
480
|
+
], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [
|
481
|
+
/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
|
482
|
+
], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [
|
483
|
+
|
484
|
+
// HTC
|
485
|
+
/(nexus 9)/i // HTC Nexus 9
|
566
486
|
], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
|
487
|
+
/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC
|
567
488
|
|
568
|
-
|
569
|
-
/(
|
570
|
-
|
571
|
-
|
572
|
-
/(microsoft);\s(lumia[\s\w]+)/i // Microsoft Lumia
|
573
|
-
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
574
|
-
|
575
|
-
/[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox
|
576
|
-
], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [
|
577
|
-
/(kin\.[onetw]{3})/i // Microsoft Kin
|
578
|
-
], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [
|
579
|
-
|
580
|
-
// Motorola
|
581
|
-
/\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?)[\w\s]+build\//i,
|
582
|
-
/mot[\s-]?(\w+)*/i,
|
583
|
-
/(XT\d{3,4}) build\//i,
|
584
|
-
/(nexus\s6)/i
|
585
|
-
], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [
|
586
|
-
/android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i
|
587
|
-
], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [
|
588
|
-
|
589
|
-
/hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i // HbbTV devices
|
590
|
-
], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [
|
591
|
-
|
592
|
-
/hbbtv.+maple;(\d+)/i
|
593
|
-
], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [
|
594
|
-
|
595
|
-
/\(dtv[\);].+(aquos)/i // Sharp
|
596
|
-
], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
|
597
|
-
|
598
|
-
/android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i,
|
599
|
-
/((SM-T\w+))/i
|
600
|
-
], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung
|
601
|
-
/smart-tv.+(samsung)/i
|
602
|
-
], [VENDOR, [TYPE, SMARTTV], MODEL], [
|
603
|
-
/((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+))/i,
|
604
|
-
/(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i,
|
605
|
-
/sec-((sgh\w+))/i
|
606
|
-
], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [
|
607
|
-
|
608
|
-
/sie-(\w+)*/i // Siemens
|
609
|
-
], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
|
610
|
-
|
611
|
-
/(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia
|
612
|
-
/(nokia)[\s_-]?([\w-]+)*/i
|
613
|
-
], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [
|
489
|
+
// ZTE
|
490
|
+
/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
|
491
|
+
/(alcatel|geeksphone|nexian|panasonic|sony)[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
|
492
|
+
], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
|
614
493
|
|
615
|
-
|
494
|
+
// Acer
|
495
|
+
/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
|
616
496
|
], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
|
617
497
|
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
], [[VENDOR, '
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
/
|
498
|
+
// Meizu
|
499
|
+
/droid.+; (m[1-5] note) bui/i,
|
500
|
+
/\bmz-([-\w]{2,})/i
|
501
|
+
], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
|
502
|
+
|
503
|
+
// Sharp
|
504
|
+
/\b(sh-?[altvz]?\d\d[a-ekm]?)/i
|
505
|
+
], [MODEL, [VENDOR, 'Sharp'], [TYPE, MOBILE]], [
|
506
|
+
|
507
|
+
// MIXED
|
508
|
+
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i,
|
509
|
+
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
|
510
|
+
/(hp) ([\w ]+\w)/i, // HP iPAQ
|
511
|
+
/(asus)-?(\w+)/i, // Asus
|
512
|
+
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
|
513
|
+
/(lenovo)[-_ ]?([-\w]+)/i, // Lenovo
|
514
|
+
/(jolla)/i, // Jolla
|
515
|
+
/(oppo) ?([\w ]+) bui/i // OPPO
|
633
516
|
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
634
517
|
|
635
|
-
/((
|
636
|
-
|
637
|
-
|
638
|
-
/
|
639
|
-
|
640
|
-
|
641
|
-
/
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [
|
646
|
-
|
647
|
-
/android.+;\s(pixel c)\s/i // Google Pixel C
|
648
|
-
], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [
|
649
|
-
|
650
|
-
/android.+;\s(pixel xl|pixel)\s/i // Google Pixel
|
651
|
-
], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [
|
652
|
-
|
653
|
-
/android.+(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
|
654
|
-
/android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi
|
655
|
-
/android.+(mi[\s\-_]*(?:one|one[\s_]plus|note lte)?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Mi
|
656
|
-
/android.+(redmi[\s\-_]*(?:note)?(?:[\s_]*[\w\s]+)?)\s+build/i // Redmi Phones
|
657
|
-
], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [
|
658
|
-
/android.+(mi[\s\-_]*(?:pad)?(?:[\s_]*[\w\s]+)?)\s+build/i // Mi Pad tablets
|
659
|
-
],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [
|
660
|
-
/android.+;\s(m[1-5]\snote)\sbuild/i // Meizu Tablet
|
661
|
-
], [MODEL, [VENDOR, 'Meizu'], [TYPE, TABLET]], [
|
662
|
-
|
663
|
-
/android.+a000(1)\s+build/i // OnePlus
|
664
|
-
], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
|
518
|
+
/(archos) (gamepad2?)/i, // Archos
|
519
|
+
/(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
|
520
|
+
/(kindle)\/([\w\.]+)/i, // Kindle
|
521
|
+
/(nook)[\w ]+build\/(\w+)/i, // Nook
|
522
|
+
/(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak
|
523
|
+
/(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets
|
524
|
+
/(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets
|
525
|
+
/(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets
|
526
|
+
/(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone
|
527
|
+
], [VENDOR, MODEL, [TYPE, TABLET]], [
|
665
528
|
|
666
|
-
/
|
529
|
+
/(surface duo)/i // Surface Duo
|
530
|
+
], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [
|
531
|
+
/droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone
|
532
|
+
], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [
|
533
|
+
/(u304aa)/i // AT&T
|
534
|
+
], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [
|
535
|
+
/\bsie-(\w*)/i // Siemens
|
536
|
+
], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
|
537
|
+
/\b(rct\w+) b/i // RCA Tablets
|
667
538
|
], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
|
668
|
-
|
669
|
-
/android.+[;\/]\s*(Venue[\d\s]*)\s+build/i // Dell Venue Tablets
|
539
|
+
/\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets
|
670
540
|
], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
|
671
|
-
|
672
|
-
/android.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i // Verizon Tablet
|
541
|
+
/\b(q(?:mv|ta)\w+) b/i // Verizon Tablet
|
673
542
|
], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
/android.+[;\/]\s+(TM\d{3}.*\b)\s+build/i // Barnes & Noble Tablet
|
543
|
+
/\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet
|
544
|
+
], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [
|
545
|
+
/\b(tm\d{3}\w+) b/i
|
679
546
|
], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
547
|
+
/\b(k88) b/i // ZTE K Series Tablet
|
548
|
+
], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
|
549
|
+
/\b(nx\d{3}j) b/i // ZTE Nubia
|
550
|
+
], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
|
551
|
+
/\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile
|
685
552
|
], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
|
686
|
-
|
687
|
-
/android.+[;\/]\s*(zur\d{3})\s+build/i // Swiss ZUR Tablet
|
553
|
+
/\b(zur\d{3}) b/i // Swiss ZUR Tablet
|
688
554
|
], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
|
689
|
-
|
690
|
-
/android.+[;\/]\s*((Zeki)?TB.*\b)\s+build/i // Zeki Tablets
|
555
|
+
/\b((zeki)?tb.*\b) b/i // Zeki Tablets
|
691
556
|
], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
|
692
|
-
|
693
|
-
|
694
|
-
/android.+[;\/]\s+(Dragon[\-\s]+Touch\s+|DT)(.+)\s+build/i // Dragon Touch Tablet
|
557
|
+
/\b([yr]\d{2}) b/i,
|
558
|
+
/\b(dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet
|
695
559
|
], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [
|
696
|
-
|
697
|
-
/android.+[;\/]\s*(NS-?.+)\s+build/i // Insignia Tablets
|
560
|
+
/\b(ns-?\w{0,9}) b/i // Insignia Tablets
|
698
561
|
], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
|
699
|
-
|
700
|
-
/android.+[;\/]\s*((NX|Next)-?.+)\s+build/i // NextBook Tablets
|
562
|
+
/\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets
|
701
563
|
], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
/android.+[;\/]\s*(LVTEL\-?)?(V1[12])\s+build/i // LvTel Phones
|
564
|
+
/\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones
|
565
|
+
], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [
|
566
|
+
/\b(lvtel\-)?(v1[12]) b/i // LvTel Phones
|
707
567
|
], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
|
708
|
-
|
709
|
-
|
568
|
+
/\b(ph-1) /i // Essential PH-1
|
569
|
+
], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [
|
570
|
+
/\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets
|
710
571
|
], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
|
711
|
-
|
712
|
-
/android.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(.*\b)\s+build/i // Le Pan Tablets
|
713
|
-
], [VENDOR, MODEL, [TYPE, TABLET]], [
|
714
|
-
|
715
|
-
/android.+[;\/]\s*(Trio[\s\-]*.*)\s+build/i // MachSpeed Tablets
|
572
|
+
/\b(trio[-\w\. ]+) b/i // MachSpeed Tablets
|
716
573
|
], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
|
717
|
-
|
718
|
-
/android.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i // Trinity Tablets
|
719
|
-
], [VENDOR, MODEL, [TYPE, TABLET]], [
|
720
|
-
|
721
|
-
/android.+[;\/]\s*TU_(1491)\s+build/i // Rotor Tablets
|
574
|
+
/\btu_(1491) b/i // Rotor Tablets
|
722
575
|
], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [
|
576
|
+
/(shield[\w ]+) b/i // Nvidia Shield Tablets
|
577
|
+
], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [
|
578
|
+
/(sprint) (\w+)/i // Sprint Phones
|
579
|
+
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
580
|
+
/(kin\.[onetw]{3})/i // Microsoft Kin
|
581
|
+
], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [
|
582
|
+
/droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra
|
583
|
+
], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [
|
584
|
+
/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
|
585
|
+
], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [
|
586
|
+
|
587
|
+
///////////////////
|
588
|
+
// CONSOLES
|
589
|
+
///////////////////
|
590
|
+
|
591
|
+
/(ouya)/i, // Ouya
|
592
|
+
/(nintendo) ([wids3utch]+)/i // Nintendo
|
593
|
+
], [VENDOR, MODEL, [TYPE, CONSOLE]], [
|
594
|
+
/droid.+; (shield) bui/i // Nvidia
|
595
|
+
], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
|
596
|
+
/(playstation [345portablevi]+)/i // Playstation
|
597
|
+
], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [
|
598
|
+
/\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox
|
599
|
+
], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [
|
723
600
|
|
724
|
-
|
725
|
-
|
601
|
+
///////////////////
|
602
|
+
// SMARTTVS
|
603
|
+
///////////////////
|
726
604
|
|
727
|
-
/
|
728
|
-
], [VENDOR,
|
605
|
+
/smart-tv.+(samsung)/i // Samsung
|
606
|
+
], [VENDOR, [TYPE, SMARTTV]], [
|
607
|
+
/hbbtv.+maple;(\d+)/i
|
608
|
+
], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [
|
609
|
+
/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV
|
610
|
+
], [[VENDOR, LG], [TYPE, SMARTTV]], [
|
611
|
+
/(apple) ?tv/i // Apple TV
|
612
|
+
], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
|
613
|
+
/crkey/i // Google Chromecast
|
614
|
+
], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
|
615
|
+
/droid.+aft(\w)( bui|\))/i // Fire TV
|
616
|
+
], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
|
617
|
+
/\(dtv[\);].+(aquos)/i // Sharp
|
618
|
+
], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
|
619
|
+
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
|
620
|
+
/hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i // HbbTV devices
|
621
|
+
], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [
|
622
|
+
/\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors
|
623
|
+
], [[TYPE, SMARTTV]], [
|
729
624
|
|
730
|
-
|
731
|
-
|
732
|
-
|
625
|
+
///////////////////
|
626
|
+
// WEARABLES
|
627
|
+
///////////////////
|
733
628
|
|
734
|
-
/(
|
629
|
+
/((pebble))app/i // Pebble
|
630
|
+
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
|
631
|
+
/droid.+; (glass) \d/i // Google Glass
|
632
|
+
], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
|
633
|
+
/droid.+; (wt63?0{2,3})\)/i
|
634
|
+
], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
|
635
|
+
/(quest( 2)?)/i // Oculus Quest
|
636
|
+
], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [
|
637
|
+
|
638
|
+
///////////////////
|
639
|
+
// EMBEDDED
|
640
|
+
///////////////////
|
641
|
+
|
642
|
+
/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla
|
643
|
+
], [VENDOR, [TYPE, EMBEDDED]], [
|
644
|
+
|
645
|
+
////////////////////
|
646
|
+
// MIXED (GENERIC)
|
647
|
+
///////////////////
|
648
|
+
|
649
|
+
/droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
|
650
|
+
], [MODEL, [TYPE, MOBILE]], [
|
651
|
+
/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
|
652
|
+
], [MODEL, [TYPE, TABLET]], [
|
653
|
+
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
|
654
|
+
], [[TYPE, TABLET]], [
|
655
|
+
/(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile
|
656
|
+
], [[TYPE, MOBILE]], [
|
657
|
+
/(android[-\w\. ]{0,9});.+buil/i // Generic Android Device
|
735
658
|
], [MODEL, [VENDOR, 'Generic']]
|
736
|
-
|
737
|
-
|
738
|
-
/*//////////////////////////
|
739
|
-
// TODO: move to string map
|
740
|
-
////////////////////////////
|
741
|
-
|
742
|
-
/(C6603)/i // Sony Xperia Z C6603
|
743
|
-
], [[MODEL, 'Xperia Z C6603'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [
|
744
|
-
/(C6903)/i // Sony Xperia Z 1
|
745
|
-
], [[MODEL, 'Xperia Z 1'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [
|
746
|
-
|
747
|
-
/(SM-G900[F|H])/i // Samsung Galaxy S5
|
748
|
-
], [[MODEL, 'Galaxy S5'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
|
749
|
-
/(SM-G7102)/i // Samsung Galaxy Grand 2
|
750
|
-
], [[MODEL, 'Galaxy Grand 2'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
|
751
|
-
/(SM-G530H)/i // Samsung Galaxy Grand Prime
|
752
|
-
], [[MODEL, 'Galaxy Grand Prime'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
|
753
|
-
/(SM-G313HZ)/i // Samsung Galaxy V
|
754
|
-
], [[MODEL, 'Galaxy V'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
|
755
|
-
/(SM-T805)/i // Samsung Galaxy Tab S 10.5
|
756
|
-
], [[MODEL, 'Galaxy Tab S 10.5'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [
|
757
|
-
/(SM-G800F)/i // Samsung Galaxy S5 Mini
|
758
|
-
], [[MODEL, 'Galaxy S5 Mini'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
|
759
|
-
/(SM-T311)/i // Samsung Galaxy Tab 3 8.0
|
760
|
-
], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [
|
761
|
-
|
762
|
-
/(T3C)/i // Advan Vandroid T3C
|
763
|
-
], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [
|
764
|
-
/(ADVAN T1J\+)/i // Advan Vandroid T1J+
|
765
|
-
], [[MODEL, 'Vandroid T1J+'], [VENDOR, 'Advan'], [TYPE, TABLET]], [
|
766
|
-
/(ADVAN S4A)/i // Advan Vandroid S4A
|
767
|
-
], [[MODEL, 'Vandroid S4A'], [VENDOR, 'Advan'], [TYPE, MOBILE]], [
|
768
|
-
|
769
|
-
/(V972M)/i // ZTE V972M
|
770
|
-
], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
|
771
|
-
|
772
|
-
/(i-mobile)\s(IQ\s[\d\.]+)/i // i-mobile IQ
|
773
|
-
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
774
|
-
/(IQ6.3)/i // i-mobile IQ IQ 6.3
|
775
|
-
], [[MODEL, 'IQ 6.3'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [
|
776
|
-
/(i-mobile)\s(i-style\s[\d\.]+)/i // i-mobile i-STYLE
|
777
|
-
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
778
|
-
/(i-STYLE2.1)/i // i-mobile i-STYLE 2.1
|
779
|
-
], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [
|
780
|
-
|
781
|
-
/(mobiistar touch LAI 512)/i // mobiistar touch LAI 512
|
782
|
-
], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [
|
783
|
-
|
784
|
-
/////////////
|
785
|
-
// END TODO
|
786
|
-
///////////*/
|
787
|
-
|
788
659
|
],
|
789
660
|
|
790
661
|
engine : [[
|
791
662
|
|
792
|
-
/windows
|
793
|
-
], [VERSION, [NAME, '
|
663
|
+
/windows.+ edge\/([\w\.]+)/i // EdgeHTML
|
664
|
+
], [VERSION, [NAME, EDGE+'HTML']], [
|
665
|
+
|
666
|
+
/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
|
667
|
+
], [VERSION, [NAME, 'Blink']], [
|
794
668
|
|
795
669
|
/(presto)\/([\w\.]+)/i, // Presto
|
796
|
-
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,
|
797
|
-
/(
|
798
|
-
/(
|
670
|
+
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
|
671
|
+
/ekioh(flow)\/([\w\.]+)/i, // Flow
|
672
|
+
/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
|
673
|
+
/(icab)[\/ ]([23]\.[\d\.]+)/i // iCab
|
799
674
|
], [NAME, VERSION], [
|
800
675
|
|
801
|
-
/rv\:([\w\.]
|
676
|
+
/rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko
|
802
677
|
], [VERSION, NAME]
|
803
678
|
],
|
804
679
|
|
805
680
|
os : [[
|
806
681
|
|
807
|
-
// Windows
|
808
|
-
/microsoft
|
682
|
+
// Windows
|
683
|
+
/microsoft (windows) (vista|xp)/i // Windows (iTunes)
|
809
684
|
], [NAME, VERSION], [
|
810
|
-
/(windows)
|
811
|
-
/(windows
|
812
|
-
/(windows
|
813
|
-
], [NAME, [VERSION,
|
814
|
-
/(win(?=3|9|n)|win
|
815
|
-
], [[NAME, 'Windows'], [VERSION,
|
816
|
-
|
817
|
-
//
|
818
|
-
|
819
|
-
|
820
|
-
/
|
821
|
-
/(
|
822
|
-
/(
|
823
|
-
|
824
|
-
/linux;.+(sailfish);/i // Sailfish OS
|
825
|
-
], [NAME, VERSION], [
|
826
|
-
/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian
|
827
|
-
], [[NAME, 'Symbian'], VERSION], [
|
828
|
-
/\((series40);/i // Series 40
|
829
|
-
], [NAME], [
|
830
|
-
/mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS
|
831
|
-
], [[NAME, 'Firefox OS'], VERSION], [
|
685
|
+
/(windows) nt 6\.2; (arm)/i, // Windows RT
|
686
|
+
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone
|
687
|
+
/(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
|
688
|
+
], [NAME, [VERSION, strMapper, windowsVersionMap]], [
|
689
|
+
/(win(?=3|9|n)|win 9x )([nt\d\.]+)/i
|
690
|
+
], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [
|
691
|
+
|
692
|
+
// iOS/macOS
|
693
|
+
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
|
694
|
+
/cfnetwork\/.+darwin/i
|
695
|
+
], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
|
696
|
+
/(mac os x) ?([\w\. ]*)/i,
|
697
|
+
/(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS
|
698
|
+
], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [
|
832
699
|
|
833
|
-
//
|
834
|
-
/(
|
835
|
-
|
836
|
-
|
837
|
-
/(
|
838
|
-
/(
|
839
|
-
|
840
|
-
// Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
|
841
|
-
// Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus
|
842
|
-
/(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux
|
843
|
-
/(gnu)\s?([\w\.]+)*/i // GNU
|
700
|
+
// Mobile OSes
|
701
|
+
/droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86
|
702
|
+
], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
|
703
|
+
/(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
|
704
|
+
/(blackberry)\w*\/([\w\.]*)/i, // Blackberry
|
705
|
+
/(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS
|
706
|
+
/\((series40);/i // Series 40
|
844
707
|
], [NAME, VERSION], [
|
845
|
-
|
846
|
-
|
708
|
+
/\(bb(10);/i // BlackBerry 10
|
709
|
+
], [VERSION, [NAME, BLACKBERRY]], [
|
710
|
+
/(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian
|
711
|
+
], [VERSION, [NAME, 'Symbian']], [
|
712
|
+
/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS
|
713
|
+
], [VERSION, [NAME, FIREFOX+' OS']], [
|
714
|
+
/web0s;.+rt(tv)/i,
|
715
|
+
/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS
|
716
|
+
], [VERSION, [NAME, 'webOS']], [
|
717
|
+
|
718
|
+
// Google Chromecast
|
719
|
+
/crkey\/([\d\.]+)/i // Google Chromecast
|
720
|
+
], [VERSION, [NAME, CHROME+'cast']], [
|
721
|
+
/(cros) [\w]+ ([\w\.]+\w)/i // Chromium OS
|
847
722
|
], [[NAME, 'Chromium OS'], VERSION],[
|
848
723
|
|
849
|
-
//
|
850
|
-
/(
|
851
|
-
],
|
852
|
-
|
853
|
-
// BSD based
|
854
|
-
/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly
|
855
|
-
], [NAME, VERSION],[
|
856
|
-
|
857
|
-
/(haiku)\s(\w+)/i // Haiku
|
858
|
-
], [NAME, VERSION],[
|
859
|
-
|
860
|
-
/cfnetwork\/.+darwin/i,
|
861
|
-
/ip[honead]+(?:.*os\s([\w]+)\slike\smac|;\sopera)/i // iOS
|
862
|
-
], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
|
863
|
-
|
864
|
-
/(mac\sos\sx)\s?([\w\s\.]+\w)*/i,
|
865
|
-
/(macintosh|mac(?=_powerpc)\s)/i // Mac OS
|
866
|
-
], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [
|
724
|
+
// Console
|
725
|
+
/(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation
|
726
|
+
/(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
|
867
727
|
|
868
728
|
// Other
|
869
|
-
|
870
|
-
/(
|
871
|
-
/(
|
872
|
-
|
873
|
-
|
729
|
+
/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
|
730
|
+
/(mint)[\/\(\) ]?(\w*)/i, // Mint
|
731
|
+
/(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux
|
732
|
+
/([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
|
733
|
+
// Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire
|
734
|
+
/(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux
|
735
|
+
/(gnu) ?([\w\.]*)/i, // GNU
|
736
|
+
/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
|
737
|
+
/(haiku) (\w+)/i // Haiku
|
738
|
+
], [NAME, VERSION], [
|
739
|
+
/(sunos) ?([\w\.\d]*)/i // Solaris
|
740
|
+
], [[NAME, 'Solaris'], VERSION], [
|
741
|
+
/((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris
|
742
|
+
/(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX
|
743
|
+
/\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX
|
744
|
+
/(unix) ?([\w\.]*)/i // UNIX
|
874
745
|
], [NAME, VERSION]
|
875
746
|
]
|
876
747
|
};
|
877
748
|
|
878
|
-
|
879
749
|
/////////////////
|
880
750
|
// Constructor
|
881
751
|
////////////////
|
882
|
-
|
883
|
-
var
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
this[ARCHITECTURE] = arch;
|
889
|
-
};
|
890
|
-
var Device = function (vendor, model, type) {
|
891
|
-
this[VENDOR] = vendor;
|
892
|
-
this[MODEL] = model;
|
893
|
-
this[TYPE] = type;
|
894
|
-
};
|
895
|
-
var Engine = Browser;
|
896
|
-
var OS = Browser;
|
897
|
-
*/
|
898
|
-
var UAParser = function (uastring, extensions) {
|
899
|
-
|
900
|
-
if (typeof uastring === 'object') {
|
901
|
-
extensions = uastring;
|
902
|
-
uastring = undefined;
|
752
|
+
|
753
|
+
var UAParser = function (ua, extensions) {
|
754
|
+
|
755
|
+
if (typeof ua === OBJ_TYPE) {
|
756
|
+
extensions = ua;
|
757
|
+
ua = undefined;
|
903
758
|
}
|
904
759
|
|
905
760
|
if (!(this instanceof UAParser)) {
|
906
|
-
return new UAParser(
|
761
|
+
return new UAParser(ua, extensions).getResult();
|
907
762
|
}
|
908
763
|
|
909
|
-
var
|
910
|
-
var
|
911
|
-
//var browser = new Browser();
|
912
|
-
//var cpu = new CPU();
|
913
|
-
//var device = new Device();
|
914
|
-
//var engine = new Engine();
|
915
|
-
//var os = new OS();
|
764
|
+
var _ua = ua || ((typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
|
765
|
+
var _rgxmap = extensions ? extend(regexes, extensions) : regexes;
|
916
766
|
|
917
767
|
this.getBrowser = function () {
|
918
|
-
var
|
919
|
-
|
920
|
-
|
921
|
-
|
768
|
+
var _browser = {};
|
769
|
+
_browser[NAME] = undefined;
|
770
|
+
_browser[VERSION] = undefined;
|
771
|
+
rgxMapper.call(_browser, _ua, _rgxmap.browser);
|
772
|
+
_browser.major = majorize(_browser.version);
|
773
|
+
return _browser;
|
922
774
|
};
|
923
775
|
this.getCPU = function () {
|
924
|
-
var
|
925
|
-
|
926
|
-
|
776
|
+
var _cpu = {};
|
777
|
+
_cpu[ARCHITECTURE] = undefined;
|
778
|
+
rgxMapper.call(_cpu, _ua, _rgxmap.cpu);
|
779
|
+
return _cpu;
|
927
780
|
};
|
928
781
|
this.getDevice = function () {
|
929
|
-
var
|
930
|
-
|
931
|
-
|
782
|
+
var _device = {};
|
783
|
+
_device[VENDOR] = undefined;
|
784
|
+
_device[MODEL] = undefined;
|
785
|
+
_device[TYPE] = undefined;
|
786
|
+
rgxMapper.call(_device, _ua, _rgxmap.device);
|
787
|
+
return _device;
|
932
788
|
};
|
933
789
|
this.getEngine = function () {
|
934
|
-
var
|
935
|
-
|
936
|
-
|
790
|
+
var _engine = {};
|
791
|
+
_engine[NAME] = undefined;
|
792
|
+
_engine[VERSION] = undefined;
|
793
|
+
rgxMapper.call(_engine, _ua, _rgxmap.engine);
|
794
|
+
return _engine;
|
937
795
|
};
|
938
796
|
this.getOS = function () {
|
939
|
-
var
|
940
|
-
|
941
|
-
|
797
|
+
var _os = {};
|
798
|
+
_os[NAME] = undefined;
|
799
|
+
_os[VERSION] = undefined;
|
800
|
+
rgxMapper.call(_os, _ua, _rgxmap.os);
|
801
|
+
return _os;
|
942
802
|
};
|
943
803
|
this.getResult = function () {
|
944
804
|
return {
|
@@ -951,90 +811,32 @@
|
|
951
811
|
};
|
952
812
|
};
|
953
813
|
this.getUA = function () {
|
954
|
-
return
|
814
|
+
return _ua;
|
955
815
|
};
|
956
|
-
this.setUA = function (
|
957
|
-
|
958
|
-
//browser = new Browser();
|
959
|
-
//cpu = new CPU();
|
960
|
-
//device = new Device();
|
961
|
-
//engine = new Engine();
|
962
|
-
//os = new OS();
|
816
|
+
this.setUA = function (ua) {
|
817
|
+
_ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;
|
963
818
|
return this;
|
964
819
|
};
|
820
|
+
this.setUA(_ua);
|
965
821
|
return this;
|
966
822
|
};
|
967
823
|
|
968
824
|
UAParser.VERSION = LIBVERSION;
|
969
|
-
UAParser.BROWSER =
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
};
|
974
|
-
UAParser.CPU = {
|
975
|
-
ARCHITECTURE : ARCHITECTURE
|
976
|
-
};
|
977
|
-
UAParser.DEVICE = {
|
978
|
-
MODEL : MODEL,
|
979
|
-
VENDOR : VENDOR,
|
980
|
-
TYPE : TYPE,
|
981
|
-
CONSOLE : CONSOLE,
|
982
|
-
MOBILE : MOBILE,
|
983
|
-
SMARTTV : SMARTTV,
|
984
|
-
TABLET : TABLET,
|
985
|
-
WEARABLE: WEARABLE,
|
986
|
-
EMBEDDED: EMBEDDED
|
987
|
-
};
|
988
|
-
UAParser.ENGINE = {
|
989
|
-
NAME : NAME,
|
990
|
-
VERSION : VERSION
|
991
|
-
};
|
992
|
-
UAParser.OS = {
|
993
|
-
NAME : NAME,
|
994
|
-
VERSION : VERSION
|
995
|
-
};
|
996
|
-
//UAParser.Utils = util;
|
825
|
+
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
|
826
|
+
UAParser.CPU = enumerize([ARCHITECTURE]);
|
827
|
+
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
828
|
+
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|
997
829
|
|
998
830
|
///////////
|
999
831
|
// Export
|
1000
832
|
//////////
|
1001
833
|
|
1002
|
-
|
1003
834
|
// check js environment
|
1004
835
|
if (typeof(exports) !== UNDEF_TYPE) {
|
1005
836
|
// nodejs env
|
1006
837
|
if (typeof module !== UNDEF_TYPE && module.exports) {
|
1007
838
|
exports = module.exports = UAParser;
|
1008
839
|
}
|
1009
|
-
// TODO: test!!!!!!!!
|
1010
|
-
/*
|
1011
|
-
if (require && require.main === module && process) {
|
1012
|
-
// cli
|
1013
|
-
var jsonize = function (arr) {
|
1014
|
-
var res = [];
|
1015
|
-
for (var i in arr) {
|
1016
|
-
res.push(new UAParser(arr[i]).getResult());
|
1017
|
-
}
|
1018
|
-
process.stdout.write(JSON.stringify(res, null, 2) + '\n');
|
1019
|
-
};
|
1020
|
-
if (process.stdin.isTTY) {
|
1021
|
-
// via args
|
1022
|
-
jsonize(process.argv.slice(2));
|
1023
|
-
} else {
|
1024
|
-
// via pipe
|
1025
|
-
var str = '';
|
1026
|
-
process.stdin.on('readable', function() {
|
1027
|
-
var read = process.stdin.read();
|
1028
|
-
if (read !== null) {
|
1029
|
-
str += read;
|
1030
|
-
}
|
1031
|
-
});
|
1032
|
-
process.stdin.on('end', function () {
|
1033
|
-
jsonize(str.replace(/\n$/, '').split('\n'));
|
1034
|
-
});
|
1035
|
-
}
|
1036
|
-
}
|
1037
|
-
*/
|
1038
840
|
exports.UAParser = UAParser;
|
1039
841
|
} else {
|
1040
842
|
// requirejs env (optional)
|
@@ -1042,7 +844,7 @@
|
|
1042
844
|
define(function () {
|
1043
845
|
return UAParser;
|
1044
846
|
});
|
1045
|
-
} else if (window) {
|
847
|
+
} else if (typeof window !== UNDEF_TYPE) {
|
1046
848
|
// browser env
|
1047
849
|
window.UAParser = UAParser;
|
1048
850
|
}
|
@@ -1053,15 +855,15 @@
|
|
1053
855
|
// In AMD env the global scope should be kept clean, but jQuery is an exception.
|
1054
856
|
// jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
|
1055
857
|
// and we should catch that.
|
1056
|
-
var $ = window && (window.jQuery || window.Zepto);
|
1057
|
-
if (
|
858
|
+
var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto);
|
859
|
+
if ($ && !$.ua) {
|
1058
860
|
var parser = new UAParser();
|
1059
861
|
$.ua = parser.getResult();
|
1060
862
|
$.ua.get = function () {
|
1061
863
|
return parser.getUA();
|
1062
864
|
};
|
1063
|
-
$.ua.set = function (
|
1064
|
-
parser.setUA(
|
865
|
+
$.ua.set = function (ua) {
|
866
|
+
parser.setUA(ua);
|
1065
867
|
var result = parser.getResult();
|
1066
868
|
for (var prop in result) {
|
1067
869
|
$.ua[prop] = result[prop];
|