Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / useragent / index.js
1 'use strict';
2
3 /**
4  * This is where all the magic comes from, specially crafted for `useragent`.
5  */
6 var regexps = require('./lib/regexps');
7
8 /**
9  * Reduce references by storing the lookups.
10  */
11 // OperatingSystem parsers:
12 var osparsers = regexps.os
13   , osparserslength = osparsers.length;
14
15 // UserAgent parsers:
16 var agentparsers = regexps.browser
17   , agentparserslength = agentparsers.length;
18
19 // Device parsers:
20 var deviceparsers = regexps.device
21   , deviceparserslength = deviceparsers.length;
22
23 /**
24  * The representation of a parsed user agent.
25  *
26  * @constructor
27  * @param {String} family The name of the browser
28  * @param {String} major Major version of the browser
29  * @param {String} minor Minor version of the browser
30  * @param {String} patch Patch version of the browser
31  * @param {String} source The actual user agent string
32  * @api public
33  */
34 function Agent(family, major, minor, patch, source) {
35   this.family = family || 'Other';
36   this.major = major || '0';
37   this.minor = minor || '0';
38   this.patch = patch || '0';
39   this.source = source || '';
40 }
41
42 /**
43  * OnDemand parsing of the Operating System.
44  *
45  * @type {OperatingSystem}
46  * @api public
47  */
48 Object.defineProperty(Agent.prototype, 'os', {
49   get: function lazyparse() {
50     var userAgent = this.source
51       , length = osparserslength
52       , parsers = osparsers
53       , i = 0
54       , parser
55       , res;
56
57     for (; i < length; i++) {
58       if (res = parsers[i][0].exec(userAgent)) {
59         parser = parsers[i];
60
61         if (parser[1]) res[1] = parser[1].replace('$1', res[1]);
62         break;
63       }
64     }
65
66     return Object.defineProperty(this, 'os', {
67         value: !parser || !res
68           ? new OperatingSystem()
69           : new OperatingSystem(
70                 res[1]
71               , parser[2] || res[2]
72               , parser[3] || res[3]
73               , parser[4] || res[4]
74             )
75     }).os;
76   },
77
78   /**
79    * Bypass the OnDemand parsing and set an OperatingSystem instance.
80    *
81    * @param {OperatingSystem} os
82    * @api public
83    */
84   set: function set(os) {
85     if (!(os instanceof OperatingSystem)) return false;
86
87     return Object.defineProperty(this, 'os', {
88       value: os
89     }).os;
90   }
91 });
92
93 /**
94  * OnDemand parsing of the Device type.
95  *
96  * @type {Device}
97  * @api public
98  */
99 Object.defineProperty(Agent.prototype, 'device', {
100   get: function lazyparse() {
101     var userAgent = this.source
102       , length = deviceparserslength
103       , parsers = deviceparsers
104       , i = 0
105       , parser
106       , res;
107
108     for (; i < length; i++) {
109       if (res = parsers[i][0].exec(userAgent)) {
110         parser = parsers[i];
111
112         if (parser[1]) res[1] = parser[1].replace('$1', res[1]);
113         break;
114       }
115     }
116
117     return Object.defineProperty(this, 'device', {
118         value: !parser || !res
119           ? new Device()
120           : new Device(
121                 res[1]
122               , parser[2] || res[2]
123               , parser[3] || res[3]
124               , parser[4] || res[4]
125             )
126     }).device;
127   },
128
129   /**
130    * Bypass the OnDemand parsing and set an Device instance.
131    *
132    * @param {Device} device
133    * @api public
134    */
135   set: function set(device) {
136     if (!(device instanceof Device)) return false;
137
138     return Object.defineProperty(this, 'device', {
139       value: device
140     }).device;
141   }
142 });
143 /*** Generates a string output of the parsed user agent.
144  *
145  * @returns {String}
146  * @api public
147  */
148 Agent.prototype.toAgent = function toAgent() {
149   var output = this.family
150     , version = this.toVersion();
151
152   if (version) output += ' '+ version;
153   return output;
154 };
155
156 /**
157  * Generates a string output of the parser user agent and operating system.
158  *
159  * @returns {String}  "UserAgent 0.0.0 / OS"
160  * @api public
161  */
162 Agent.prototype.toString = function toString() {
163   var agent = this.toAgent()
164     , os = this.os !== 'Other' ? this.os : false;
165
166   return agent + (os ? ' / ' + os : '');
167 };
168
169 /**
170  * Outputs a compiled veersion number of the user agent.
171  *
172  * @returns {String}
173  * @api public
174  */
175 Agent.prototype.toVersion = function toVersion() {
176   var version = '';
177
178   if (this.major) {
179     version += this.major;
180
181     if (this.minor) {
182      version += '.' + this.minor;
183
184      // Special case here, the patch can also be Alpha, Beta etc so we need
185      // to check if it's a string or not.
186      if (this.patch) {
187       version += (isNaN(+this.patch) ? ' ' : '.') + this.patch;
188      }
189     }
190   }
191
192   return version;
193 };
194
195 /**
196  * Outputs a JSON string of the Agent.
197  *
198  * @returns {String}
199  * @api public
200  */
201 Agent.prototype.toJSON = function toJSON() {
202   return {
203       family: this.family
204     , major: this.major
205     , minor: this.minor
206     , patch: this.patch
207     , device: this.device
208     , os: this.os
209   };
210 };
211
212 /**
213  * The representation of a parsed Operating System.
214  *
215  * @constructor
216  * @param {String} family The name of the os
217  * @param {String} major Major version of the os
218  * @param {String} minor Minor version of the os
219  * @param {String} patch Patch version of the os
220  * @api public
221  */
222 function OperatingSystem(family, major, minor, patch) {
223   this.family = family || 'Other';
224   this.major = major || '0';
225   this.minor = minor || '0';
226   this.patch = patch || '0';
227 }
228
229 /**
230  * Generates a stringified version of the Operating System.
231  *
232  * @returns {String} "Operating System 0.0.0"
233  * @api public
234  */
235 OperatingSystem.prototype.toString = function toString() {
236   var output = this.family
237     , version = this.toVersion();
238
239   if (version) output += ' '+ version;
240   return output;
241 };
242
243 /**
244  * Generates the version of the Operating System.
245  *
246  * @returns {String}
247  * @api public
248  */
249 OperatingSystem.prototype.toVersion = function toVersion() {
250   var version = '';
251
252   if (this.major) {
253     version += this.major;
254
255     if (this.minor) {
256      version += '.' + this.minor;
257
258      // Special case here, the patch can also be Alpha, Beta etc so we need
259      // to check if it's a string or not.
260      if (this.patch) {
261       version += (isNaN(+this.patch) ? ' ' : '.') + this.patch;
262      }
263     }
264   }
265
266   return version;
267 };
268
269 /**
270  * Outputs a JSON string of the OS, values are defaulted to undefined so they
271  * are not outputed in the stringify.
272  *
273  * @returns {String}
274  * @api public
275  */
276 OperatingSystem.prototype.toJSON = function toJSON(){
277   return {
278       family: this.family
279     , major: this.major || undefined
280     , minor: this.minor || undefined
281     , patch: this.patch || undefined
282   };
283 };
284
285 /**
286  * The representation of a parsed Device.
287  *
288  * @constructor
289  * @param {String} family The name of the device
290  * @param {String} major Major version of the device
291  * @param {String} minor Minor version of the device
292  * @param {String} patch Patch version of the device
293  * @api public
294  */
295 function Device(family, major, minor, patch) {
296   this.family = family || 'Other';
297   this.major = major || '0';
298   this.minor = minor || '0';
299   this.patch = patch || '0';
300 }
301
302 /**
303  * Generates a stringified version of the Device.
304  *
305  * @returns {String} "Device 0.0.0"
306  * @api public
307  */
308 Device.prototype.toString = function toString() {
309   var output = this.family
310     , version = this.toVersion();
311
312   if (version) output += ' '+ version;
313   return output;
314 };
315
316 /**
317  * Generates the version of the Device.
318  *
319  * @returns {String}
320  * @api public
321  */
322 Device.prototype.toVersion = function toVersion() {
323   var version = '';
324
325   if (this.major) {
326     version += this.major;
327
328     if (this.minor) {
329      version += '.' + this.minor;
330
331      // Special case here, the patch can also be Alpha, Beta etc so we need
332      // to check if it's a string or not.
333      if (this.patch) {
334       version += (isNaN(+this.patch) ? ' ' : '.') + this.patch;
335      }
336     }
337   }
338
339   return version;
340 };
341
342 /**
343  * Outputs a JSON string of the Device, values are defaulted to undefined so they
344  * are not outputed in the stringify.
345  *
346  * @returns {String}
347  * @api public
348  */
349 Device.prototype.toJSON = function toJSON() {
350   return {
351       family: this.family
352     , major: this.major || undefined
353     , minor: this.minor || undefined
354     , patch: this.patch || undefined
355   };
356 };
357
358 /**
359  * Small nifty thick that allows us to download a fresh set regexs from t3h
360  * Int3rNetz when we want to. We will be using the compiled version by default
361  * but users can opt-in for updates.
362  *
363  * @param {Boolean} refresh Refresh the dataset from the remote
364  * @api public
365  */
366 module.exports = function updater() {
367   try {
368     require('./lib/update').update(function updating(err, results) {
369       if (err) {
370         console.log('[useragent] Failed to update the parsed due to an error:');
371         console.log('[useragent] '+ (err.message ? err.message : err));
372         return;
373       }
374
375       regexps = results;
376
377       // OperatingSystem parsers:
378       osparsers = regexps.os;
379       osparserslength = osparsers.length;
380
381       // UserAgent parsers:
382       agentparsers = regexps.browser;
383       agentparserslength = agentparsers.length;
384
385       // Device parsers:
386       deviceparsers = regexps.device;
387       deviceparserslength = deviceparsers.length;
388     });
389   } catch (e) {
390     console.error('[useragent] If you want to use automatic updating, please add:');
391     console.error('[useragent]   - request (npm install request --save)');
392     console.error('[useragent]   - yamlparser (npm install yamlparser --save)');
393     console.error('[useragent] To your own package.json');
394   }
395 };
396
397 // Override the exports with our newly set module.exports
398 exports = module.exports;
399
400 /**
401  * Nao that we have setup all the different classes and configured it we can
402  * actually start assembling and exposing everything.
403  */
404 exports.Device = Device;
405 exports.OperatingSystem = OperatingSystem;
406 exports.Agent = Agent;
407
408 /**
409  * Check if the userAgent is something we want to parse with regexp's.
410  *
411  * @param {String} userAgent The userAgent.
412  * @returns {Boolean}
413  */
414 function isSafe(userAgent) {
415   var consecutive = 0
416     , code = 0;
417
418   for (var i = 0; i < userAgent.length; i++) {
419     code = userAgent.charCodeAt(i);
420     // numbers between 0 and 9
421     if (code >= 48 && code <= 57) {
422       consecutive++;
423     } else {
424       consecutive = 0;
425     }
426
427     if (consecutive >= 100) {
428       return false;
429     }
430   }
431
432   return true
433 }
434
435
436 /**
437  * Parses the user agent string with the generated parsers from the
438  * ua-parser project on google code.
439  *
440  * @param {String} userAgent The user agent string
441  * @param {String} jsAgent Optional UA from js to detect chrome frame
442  * @returns {Agent}
443  * @api public
444  */
445 exports.parse = function parse(userAgent, jsAgent) {
446   if (!userAgent || !isSafe(userAgent)) return new Agent();
447
448   var length = agentparserslength
449     , parsers = agentparsers
450     , i = 0
451     , parser
452     , res;
453
454   for (; i < length; i++) {
455     if (res = parsers[i][0].exec(userAgent)) {
456       parser = parsers[i];
457
458       if (parser[1]) res[1] = parser[1].replace('$1', res[1]);
459       if (!jsAgent) return new Agent(
460           res[1]
461         , parser[2] || res[2]
462         , parser[3] || res[3]
463         , parser[4] || res[4]
464         , userAgent
465       );
466
467       break;
468     }
469   }
470
471   // Return early if we didn't find an match, but might still be able to parse
472   // the os and device, so make sure we supply it with the source
473   if (!parser || !res) return new Agent('', '', '', '', userAgent);
474
475   // Detect Chrome Frame, but make sure it's enabled! So we need to check for
476   // the Chrome/ so we know that it's actually using Chrome under the hood.
477   if (jsAgent && ~jsAgent.indexOf('Chrome/') && ~userAgent.indexOf('chromeframe')) {
478     res[1] = 'Chrome Frame (IE '+ res[1] +'.'+ res[2] +')';
479
480     // Run the JavaScripted userAgent string through the parser again so we can
481     // update the version numbers;
482     parser = parse(jsAgent);
483     parser[2] = parser.major;
484     parser[3] = parser.minor;
485     parser[4] = parser.patch;
486   }
487
488   return new Agent(
489       res[1]
490     , parser[2] || res[2]
491     , parser[3] || res[3]
492     , parser[4] || res[4]
493     , userAgent
494   );
495 };
496
497 /**
498  * If you are doing a lot of lookups you might want to cache the results of the
499  * parsed user agent string instead, in memory.
500  *
501  * @TODO We probably want to create 2 dictionary's here 1 for the Agent
502  * instances and one for the userAgent instance mapping so we can re-use simular
503  * Agent instance and lower our memory consumption.
504  *
505  * @param {String} userAgent The user agent string
506  * @param {String} jsAgent Optional UA from js to detect chrome frame
507  * @api public
508  */
509 var LRU = require('lru-cache')(5000);
510 exports.lookup = function lookup(userAgent, jsAgent) {
511   var key = (userAgent || '')+(jsAgent || '')
512     , cached = LRU.get(key);
513
514   if (cached) return cached;
515   LRU.set(key, (cached = exports.parse(userAgent, jsAgent)));
516
517   return cached;
518 };
519
520 /**
521  * Does a more inaccurate but more common check for useragents identification.
522  * The version detection is from the jQuery.com library and is licensed under
523  * MIT.
524  *
525  * @param {String} useragent The user agent
526  * @returns {Object} matches
527  * @api public
528  */
529 exports.is = function is(useragent) {
530   var ua = (useragent || '').toLowerCase()
531     , details = {
532         chrome: false
533       , firefox: false
534       , ie: false
535       , mobile_safari: false
536       , mozilla: false
537       , opera: false
538       , safari: false
539       , webkit: false
540       , android: false
541       , version: (ua.match(exports.is.versionRE) || [0, "0"])[1]
542     };
543
544   if (~ua.indexOf('webkit')) {
545     details.webkit = true;
546
547     if (~ua.indexOf('android')){
548       details.android = true;
549     }
550
551     if (~ua.indexOf('chrome')) {
552       details.chrome = true;
553     } else if (~ua.indexOf('safari')) {
554       details.safari = true;
555
556       if (~ua.indexOf('mobile') && ~ua.indexOf('apple')) {
557         details.mobile_safari = true;
558       }
559     }
560   } else if (~ua.indexOf('opera')) {
561     details.opera = true;
562   } else if (~ua.indexOf('trident') || ~ua.indexOf('msie')) {
563     details.ie = true;
564   } else if (~ua.indexOf('mozilla') && !~ua.indexOf('compatible')) {
565     details.mozilla = true;
566
567     if (~ua.indexOf('firefox')) details.firefox = true;
568   }
569
570
571   return details;
572 };
573
574 /**
575  * Parses out the version numbers.
576  *
577  * @type {RegExp}
578  * @api private
579  */
580 exports.is.versionRE = /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/;
581
582 /**
583  * Transform a JSON object back to a valid userAgent string
584  *
585  * @param {Object} details
586  * @returns {Agent}
587  */
588 exports.fromJSON = function fromJSON(details) {
589   if (typeof details === 'string') details = JSON.parse(details);
590
591   var agent = new Agent(details.family, details.major, details.minor, details.patch)
592     , os = details.os;
593
594   // The device family was added in v2.0
595   if ('device' in details) {
596     agent.device = new Device(details.device.family);
597   } else {
598     agent.device = new Device();
599   }
600
601   if ('os' in details && os) {
602     // In v1.1.0 we only parsed out the Operating System name, not the full
603     // version which we added in v2.0. To provide backwards compatible we should
604     // we should set the details.os as family
605     if (typeof os === 'string') {
606       agent.os = new OperatingSystem(os);
607     } else {
608       agent.os = new OperatingSystem(os.family, os.major, os.minor, os.patch);
609     }
610   }
611
612   return agent;
613 };
614
615 /**
616  * Library version.
617  *
618  * @type {String}
619  * @api public
620  */
621 exports.version = require('./package.json').version;