PageSourceSearch

https://www.commfleet.de/vue3frontend/c4u/webcmsfc/c4u_webcms_comm…/outdated-browser.js?v=3.3.0

js commfleet.de collected 2026-10-07 23:56:23 UTC 76,141 bytes, 1,726 lines download raw bytes

1/* eslint-disable */
2// https://github.com/mikemaccana/outdated-browser-rework
3
4(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.outdatedBrowserRework = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
5  /* Highly dumbed down version of https://github.com/unclechu/node-deep-extend */
6  
7  /**
8   * Extening object that entered in first argument.
9   *
10   * Returns extended object or false if have no target object or incorrect type.
11   *
12   * If you wish to clone source object (without modify it), just use empty new
13   * object as first argument, like this:
14   *   deepExtend({}, yourObj_1, [yourObj_N]);
15   */
16  module.exports = function deepExtend(/*obj_1, [obj_2], [obj_N]*/) {
17    if (arguments.length < 1 || typeof arguments[0] !== "object") {
18      return false
19    }
20  
21    if (arguments.length < 2) {
22      return arguments[0]
23    }
24  
25    var target = arguments[0]
26  
27    for (var i = 1; i < arguments.length; i++) {
28      var obj = arguments[i]
29  
30      for (var key in obj) {
31        var src = target[key]
32        var val = obj[key]
33  
34        if (typeof val !== "object" || val === null) {
35          target[key] = val
36  
37          // just clone arrays (and recursive clone objects inside)
38        } else if (typeof src !== "object" || src === null) {
39          target[key] = deepExtend({}, val)
40  
41          // source value and new value is objects both, extending...
42        } else {
43          target[key] = deepExtend(src, val)
44        }
45      }
46    }
47  
48    return target
49  }
50  
51  },{}],2:[function(require,module,exports){
52  var UserAgentParser = require("ua-parser-js")
53  var languageMessages = require("./languages.json")
54  var deepExtend = require("./extend")
55  
56  var DEFAULTS = {
57      Chrome: 80, // Includes Chrome for mobile devices
58      Chromium: 80,
59      Edge: 80,
60      Safari: 13,
61      'Mobile Safari': 14,
62      Opera: 67,
63      Firefox: 78,
64      Vivaldi: 1,
65      IE: false,
66  }
67  
68  var EDGEHTML_VS_EDGE_VERSIONS = {
69    12: 0.1,
70    13: 21,
71    14: 31,
72    15: 39,
73    16: 41,
74    17: 42,
75    18: 44
76  }
77  
78  var COLORS = {
79    salmon: "#f25648",
80    white: "white"
81  }
82  
83  var updateDefaults = function(defaults, updatedValues) {
84    for (var key in updatedValues) {
85      defaults[key] = updatedValues[key]
86    }
87  
88    return defaults
89  }
90  
91  module.exports = function(options) {
92    var main = function() {
93      // Despite the docs, UA needs to be provided to constructor explicitly:
94      // https://github.com/faisalman/ua-parser-js/issues/90
95      var parsedUserAgent = new UserAgentParser(window.navigator.userAgent).getResult()
96  
97      // Variable definition (before ajax)
98      var el = document.createElement('div');
99      el.id = "outdated";
100      document.body.appendChild(el);
101      var outdatedUI = el;
102  
103      options = options || {}
104  
105      var browserLocale = window.navigator.language || window.navigator.userLanguage // Everyone else, IE
106  
107      // Set default options
108      var browserSupport = options.browserSupport ? updateDefaults(DEFAULTS, options.browserSupport) : DEFAULTS
109      // CSS property to check for. You may also like 'borderSpacing', 'boxShadow', 'transform', 'borderImage';
110      var requiredCssProperty = options.requiredCssProperty || false
111      var backgroundColor = options.backgroundColor || COLORS.salmon
112      var textColor = options.textColor || COLORS.white
113      var fullscreen = options.fullscreen || false
114      var language = options.language || browserLocale.slice(0, 2) // Language code
115  
116      var updateSource = "web" // Other possible values are 'googlePlay' or 'appStore'. Determines where we tell users to go for upgrades.
117  
118      // Chrome mobile is still Chrome (unlike Safari which is 'Mobile Safari')
119      var isAndroid = parsedUserAgent.os.name === "Android"
120      if (isAndroid) {
121        updateSource = "googlePlay"
122      }
123  
124      var isAndroidButNotChrome
125      if (options.requireChromeOnAndroid) {
126        isAndroidButNotChrome = isAndroid && parsedUserAgent.browser.name !== "Chrome"
127      }
128  
129      if (parsedUserAgent.os.name === "iOS") {
130        updateSource = "appStore"
131      }
132  
133      var done = true
134  
135      var changeOpacity = function(opacityValue) {
136        outdatedUI.style.opacity = opacityValue / 100
137        outdatedUI.style.filter = "alpha(opacity=" + opacityValue + ")"
138      }
139  
140      var fadeIn = function(opacityValue) {
141        changeOpacity(opacityValue)
142        if (opacityValue === 1) {
143          outdatedUI.style.display = "table"
144        }
145        if (opacityValue === 100) {
146          done = true
147        }
148      }
149  
150      var parseMinorVersion = function (version) {
151        return version.replace(/[^\d.]/g,'').split(".")[1];
152      }
153  
154      var isBrowserUnsupported = function() {
155        var browserName = parsedUserAgent.browser.name
156        var isUnsupported = false
157        if (!(browserName in browserSupport)) {
158          if (!options.isUnknownBrowserOK) {
159            isUnsupported = true
160          }
161        } else if (!browserSupport[browserName]) {
162          isUnsupported = true
163        }
164        return isUnsupported;
165      }
166  
167      var isBrowserOutOfDate = function() {
168        var browserName = parsedUserAgent.browser.name
169        var browserMajorVersion = parsedUserAgent.browser.major
170        if (browserName === "Edge") {
171          browserMajorVersion = EDGEHTML_VS_EDGE_VERSIONS[browserMajorVersion]
172        }
173        var isOutOfDate = false
174        if (isBrowserUnsupported()) {
175          isOutOfDate = true;
176        } else if (browserName in browserSupport) {
177          var minVersion = browserSupport[browserName];
178          if (typeof minVersion == 'object') {
179            var minMajorVersion = minVersion.major;
180            var minMinorVersion = minVersion.minor;
181  
182            if (browserMajorVersion < minMajorVersion) {
183              isOutOfDate = true
184            } else if (browserMajorVersion == minMajorVersion) {
185              var browserMinorVersion = parseMinorVersion(parsedUserAgent.browser.version)
186  
187              if (browserMinorVersion < minMinorVersion) {
188                isOutOfDate = true
189              }
190            }
191          } else if (browserMajorVersion < minVersion) {
192            isOutOfDate = true
193          }
194        }
195        return isOutOfDate
196      }
197  
198      // Returns true if a browser supports a css3 property
199      var isPropertySupported = function(property) {
200        if (!property) {
201          return true
202        }
203        var div = document.createElement("div")
204        var vendorPrefixes = ["khtml", "ms", "o", "moz", "webkit"]
205        var count = vendorPrefixes.length
206  
207        // Note: HTMLElement.style.hasOwnProperty seems broken in Edge
208        if (property in div.style) {
209          return true
210        }
211  
212        property = property.replace(/^[a-z]/, function(val) {
213          return val.toUpperCase()
214        })
215  
216        while (count--) {
217          var prefixedProperty = vendorPrefixes[count] + property
218          // See comment re: HTMLElement.style.hasOwnProperty above
219          if (prefixedProperty in div.style) {
220            return true
221          }
222        }
223        return false
224      }
225  
226      var makeFadeInFunction = function(opacityValue) {
227        return function() {
228          fadeIn(opacityValue)
229        }
230      }
231  
232      // Style element explicitly - TODO: investigate and delete if not needed
233      var startStylesAndEvents = function() {
234        var buttonClose = document.getElementById("buttonCloseUpdateBrowser")
235  
236        //check settings attributes
237        outdatedUI.style.backgroundColor = backgroundColor
238        //way too hard to put !important on IE6
239        outdatedUI.style.color = textColor
240        outdatedUI.children[0].children[0].style.color = textColor
241        outdatedUI.children[0].children[1].style.color = textColor
242  
243        buttonClose.style.color = textColor
244  
245        buttonClose.onmousedown = function() {
246          outdatedUI.style.display = "none"
247          return false
248        }
249      }
250  
251      var getmessage = function(lang) {
252        var defaultMessages = languageMessages[lang] || languageMessages.en
253        var customMessages = options.messages && options.messages[lang]
254        var messages = deepExtend({}, defaultMessages, customMessages)
255  
256        var updateMessages = {
257          web:
258            "<p>" +
259            messages.update.web +
260            "</p>",
261          googlePlay:
262            "<p>" +
263            messages.update.googlePlay +
264            "</p>",
265          appStore: "<p>" + messages.update[updateSource] + "</p>"
266        }
267  
268        var updateMessage = updateMessages[updateSource]
269  
270        var browserSupportMessage = messages.outOfDate;
271        if (isBrowserUnsupported() && messages.unsupported) {
272          browserSupportMessage = messages.unsupported;
273        }
274  
275        return (
276          '<div class="vertical-center"><h6>' +
277          browserSupportMessage +
278          "</h6>" +
279          updateMessage +
280          '<p class="last"><a href="#" id="buttonCloseUpdateBrowser" title="' +
281          messages.close +
282          '">&times;</a></p></div>'
283        )
284      }
285  
286      // Check if browser is supported
287      if (isBrowserOutOfDate() || !isPropertySupported(requiredCssProperty) || isAndroidButNotChrome) {
288        // This is an outdated browser
289        if (done && outdatedUI.style.opacity !== "1") {
290          done = false
291  
292          for (var opacity = 1; opacity <= 100; opacity++) {
293            setTimeout(makeFadeInFunction(opacity), opacity * 8)
294          }
295        }
296  
297        if (fullscreen) {
298          outdatedUI.classList.add("fullscreen")
299        }
300        outdatedUI.innerHTML = getmessage(language)
301        startStylesAndEvents()
302      } else {
303        document.body.removeChild(outdatedUI);
304      }
305    }
306  
307    // Load main when DOM ready.
308    var oldOnload = window.onload
309    if (typeof window.onload !== "function") {
310      window.onload = main
311    } else {
312      window.onload = function() {
313        if (oldOnload) {
314          oldOnload()
315        }
316        main()
317      }
318    }
319  }
320  
321  },{"./extend":1,"./languages.json":3,"ua-parser-js":4}],3:[function(require,module,exports){
322  module.exports={
323    "br": {
324      "outOfDate": "O seu navegador est&aacute; desatualizado!",
325      "update": {
326        "web": "Atualize o seu navegador para ter uma melhor experi&ecirc;ncia e visualiza&ccedil;&atilde;o deste site. ",
327        "googlePlay": "Please install Chrome from Google Play",
328        "appStore": "Please update iOS from the Settings App"
329      },
330      "url": "http://outdatedbrowser.com/br",
331      "callToAction": "Atualize o seu navegador agora",
332      "close": "Fechar"
333    },
334    "ca": {
335      "outOfDate": "El vostre navegador no està actualitzat!",
336      "update": {
337        "web": "Actualitzeu el vostre navegador per veure correctament aquest lloc web. ",
338        "googlePlay": "Instal·leu Chrome des de Google Play",
339        "appStore": "Actualitzeu iOS des de l'aplicació Configuració"
340      },
341      "url": "http://outdatedbrowser.com/es",
342      "callToAction": "Actualitzar el meu navegador ara",
343      "close": "Tancar"
344    },
345    "cn": {
346      "outOfDate": "您的浏览器已过时",
347      "update": {
348        "web": "要正常浏览本网站请升级您的浏览器。",
349        "googlePlay": "Please install Chrome from Google Play",
350        "appStore": "Please update iOS from the Settings App"
351      },
352      "url": "http://outdatedbrowser.com/cn",
353      "callToAction": "现在升级",
354      "close": "关闭"
355    },
356    "cz": {
357      "outOfDate": "Váš prohlížeč je zastaralý!",
358      "update": {
359        "web": "Pro správné zobrazení těchto stránek aktualizujte svůj prohlížeč. ",
360        "googlePlay": "Nainstalujte si Chrome z Google Play",
361        "appStore": "Aktualizujte si systém iOS"
362      },
363      "url": "http://outdatedbrowser.com/cz",
364      "callToAction": "Aktualizovat nyní svůj prohlížeč",
365      "close": "Zavřít"
366    },
367     "da": {
368      "outOfDate": "Din browser er forældet!",
369      "update": {
370        "web": "Opdatér din browser for at få vist denne hjemmeside korrekt. ",
371        "googlePlay": "Installér venligst Chrome fra Google Play",
372        "appStore": "Opdatér venligst iOS"
373      },
374      "url": "http://outdatedbrowser.com/da",
375      "callToAction": "Opdatér din browser nu",
376      "close": "Luk"
377    },
378    "de": {
379      "outOfDate": "Ihr Browser ist veraltet!",
380      "update": {
381        "web": "Bitte aktualisieren Sie Ihren Browser, um diese Website korrekt darzustellen. ",
382        "googlePlay": "Please install Chrome from Google Play",
383        "appStore": "Please update iOS from the Settings App"
384      },
385      "url": "http://outdatedbrowser.com/de",
386      "callToAction": "Den Browser jetzt aktualisieren ",
387      "close": "Schließen"
388    },
389    "ee": {
390      "outOfDate": "Sinu veebilehitseja on vananenud!",
391      "update": {
392        "web": "Palun uuenda oma veebilehitsejat, et näha lehekülge korrektselt. ",
393        "googlePlay": "Please install Chrome from Google Play",
394        "appStore": "Please update iOS from the Settings App"
395      },
396      "url": "http://outdatedbrowser.com/ee",
397      "callToAction": "Uuenda oma veebilehitsejat kohe",
398      "close": "Sulge"
399    },
400    "en": {
401      "outOfDate": "Your browser is out-of-date!",
402      "update": {
403        "web": "Update your browser to view this website correctly. ",
404        "googlePlay": "Please install Chrome from Google Play",
405        "appStore": "Please update iOS from the Settings App"
406      },
407      "url": "http://outdatedbrowser.com/",
408      "callToAction": "Update my browser now",
409      "close": "Close"
410    },
411    "es": {
412      "outOfDate": "¡Tu navegador está anticuado!",
413      "update": {
414        "web": "Actualiza tu navegador para ver esta página correctamente. ",
415        "googlePlay": "Please install Chrome from Google Play",
416        "appStore": "Please update iOS from the Settings App"
417      },
418      "url": "http://outdatedbrowser.com/es",
419      "callToAction": "Actualizar mi navegador ahora",
420      "close": "Cerrar"
421    },
422    "fa": {
423      "rightToLeft": true,
424      "outOfDate": "مرورگر شما منسوخ شده است!",
425      "update": {
426        "web": "جهت مشاهده صحیح این وبسایت، مرورگرتان را بروز رسانی نمایید. ",
427        "googlePlay": "Please install Chrome from Google Play",
428        "appStore": "Please update iOS from the Settings App"
429      },
430      "url": "http://outdatedbrowser.com/",
431      "callToAction": "همین حالا مرورگرم را بروز کن",
432      "close": "Close"
433    },
434    "fi": {
435      "outOfDate": "Selaimesi on vanhentunut!",
436      "update": {
437        "web": "Lataa ajantasainen selain n&auml;hd&auml;ksesi t&auml;m&auml;n sivun oikein. ",
438        "googlePlay": "Asenna uusin Chrome Google Play -kaupasta",
439        "appStore": "Päivitä iOS puhelimesi asetuksista"
440      },
441      "url": "http://outdatedbrowser.com/fi",
442      "callToAction": "P&auml;ivit&auml; selaimeni nyt ",
443      "close": "Sulje"
444    },
445    "fr": {
446      "outOfDate": "Votre navigateur n'est plus compatible !",
447      "update": {
448        "web": "Mettez à jour votre navigateur pour afficher correctement ce site Web. ",
449        "googlePlay": "Merci d'installer Chrome depuis le Google Play Store",
450        "appStore": "Merci de mettre à jour iOS depuis l'application Réglages"
451      },
452      "url": "http://outdatedbrowser.com/fr",
453      "callToAction": "Mettre à jour maintenant ",
454      "close": "Fermer"
455    },
456    "hu": {
457      "outOfDate": "A böngészője elavult!",
458      "update": {
459        "web": "Firssítse vagy cserélje le a böngészőjét. ",
460        "googlePlay": "Please install Chrome from Google Play",
461        "appStore": "Please update iOS from the Settings App"
462      },
463      "url": "http://outdatedbrowser.com/hu",
464      "callToAction": "A böngészőm frissítése ",
465      "close": "Close"
466    },
467    "id":{
468      "outOfDate": "Browser yang Anda gunakan sudah ketinggalan zaman!",
469      "update": {
470        "web": "Perbaharuilah browser Anda agar bisa menjelajahi website ini dengan nyaman. ",
471        "googlePlay": "Please install Chrome from Google Play",
472        "appStore": "Please update iOS from the Settings App"
473      },
474      "url": "http://outdatedbrowser.com/",
475      "callToAction": "Perbaharui browser sekarang ",
476      "close": "Close"
477    },
478    "it": {
479      "outOfDate": "Il tuo browser non &egrave; aggiornato!",
480      "update": {
481        "web": "Aggiornalo per vedere questo sito correttamente. ",
482        "googlePlay": "Please install Chrome from Google Play",
483        "appStore": "Please update iOS from the Settings App"
484      },
485      "url": "http://outdatedbrowser.com/it",
486      "callToAction": "Aggiorna ora",
487      "close": "Chiudi"
488    },
489    "lt":{
490      "outOfDate": "Jūsų naršyklės versija yra pasenusi!",
491      "update": {
492        "web": "Atnaujinkite savo naršyklę, kad galėtumėte peržiūrėti šią svetainę tinkamai. ",
493        "googlePlay": "Please install Chrome from Google Play",
494        "appStore": "Please update iOS from the Settings App"
495      },
496      "url": "http://outdatedbrowser.com/",
497      "callToAction": "Atnaujinti naršyklę ",
498      "close": "Close"
499    },
500    "nl": {
501      "outOfDate": "Je gebruikt een oude browser!",
502      "update": {
503        "web": "Update je browser om deze website correct te bekijken. ",
504        "googlePlay": "Please install Chrome from Google Play",
505        "appStore": "Please update iOS from the Settings App"
506      },
507      "url": "http://outdatedbrowser.com/nl",
508      "callToAction": "Update mijn browser nu ",
509      "close": "Sluiten"
510    },
511    "pl": {
512      "outOfDate": "Twoja przeglądarka jest przestarzała!",
513      "update": {
514        "web": "Zaktualizuj swoją przeglądarkę, aby poprawnie wyświetlić tę stronę. ",
515        "googlePlay": "Please install Chrome from Google Play",
516        "appStore": "Please update iOS from the Settings App"
517      },
518      "url": "http://outdatedbrowser.com/pl",
519      "callToAction": "Zaktualizuj przeglądarkę już teraz",
520      "close": "Close"
521    },
522    "pt": {
523      "outOfDate": "O seu browser est&aacute; desatualizado!",
524      "update": {
525        "web": "Atualize o seu browser para ter uma melhor experi&ecirc;ncia e visualiza&ccedil;&atilde;o deste site. ",
526        "googlePlay": "Please install Chrome from Google Play",
527        "appStore": "Please update iOS from the Settings App"
528      },
529      "url": "http://outdatedbrowser.com/pt",
530      "callToAction": "Atualize o seu browser agora",
531      "close": "Fechar"
532    },
533    "ro": {
534      "outOfDate": "Browserul este învechit!",
535      "update": {
536        "web": "Actualizați browserul pentru a vizualiza corect acest site. ",
537        "googlePlay": "Please install Chrome from Google Play",
538        "appStore": "Please update iOS from the Settings App"
539      },
540      "url": "http://outdatedbrowser.com/",
541      "callToAction": "Actualizați browserul acum!",
542      "close": "Close"
543    },
544    "ru": {
545      "outOfDate": "Ваш браузер устарел!",
546      "update": {
547        "web": "Обновите ваш браузер для правильного отображения этого сайта. ",
548        "googlePlay": "Please install Chrome from Google Play",
549        "appStore": "Please update iOS from the Settings App"
550      },
551      "url": "http://outdatedbrowser.com/ru",
552      "callToAction": "Обновить мой браузер ",
553      "close": "Закрыть"
554    },
555    "si": {
556      "outOfDate": "Vaš brskalnik je zastarel!",
557      "update": {
558        "web": "Za pravilen prikaz spletne strani posodobite vaš brskalnik. ",
559        "googlePlay": "Please install Chrome from Google Play",
560        "appStore": "Please update iOS from the Settings App"
561      },
562      "url": "http://outdatedbrowser.com/si",
563      "callToAction": "Posodobi brskalnik ",
564      "close": "Zapri"
565    },
566    "sv": {
567      "outOfDate": "Din webbläsare stödjs ej längre!",
568      "update": {
569        "web": "Uppdatera din webbläsare för att webbplatsen ska visas korrekt. ",
570        "googlePlay": "Please install Chrome from Google Play",
571        "appStore": "Please update iOS from the Settings App"
572      },
573      "url": "http://outdatedbrowser.com/",
574      "callToAction": "Uppdatera min webbläsare nu",
575      "close": "Stäng"
576    },
577    "ua": {
578      "outOfDate": "Ваш браузер застарів!",
579      "update": {
580        "web": "Оновіть ваш браузер для правильного відображення цього сайта. ",
581        "googlePlay": "Please install Chrome from Google Play",
582        "appStore": "Please update iOS from the Settings App"
583      },
584      "url": "http://outdatedbrowser.com/ua",
585      "callToAction": "Оновити мій браузер ",
586      "close": "Закрити"
587    }
588  }
589  
590  },{}],4:[function(require,module,exports){
591  /*!
592   * UAParser.js v0.7.18
593   * Lightweight JavaScript-based User-Agent string parser
594   * https://github.com/faisalman/ua-parser-js
595   *
596   * Copyright © 2012-2016 Faisal Salman <[email protected]>
597   * Dual licensed under GPLv2 or MIT
598   */
599  
600  (function (window, undefined) {
601  
602      'use strict';
603  
vendor: 9,819 bytes, lines 604-862
604      //////////////
605      // Constants
606      /////////////
607  
608  
609      var LIBVERSION  = '0.7.18',
610          EMPTY       = '',
611          UNKNOWN     = '?',
612          FUNC_TYPE   = 'function',
613          UNDEF_TYPE  = 'undefined',
614          OBJ_TYPE    = 'object',
615          STR_TYPE    = 'string',
616          MAJOR       = 'major', // deprecated
617          MODEL       = 'model',
618          NAME        = 'name',
619          TYPE        = 'type',
620          VENDOR      = 'vendor',
621          VERSION     = 'version',
622          ARCHITECTURE= 'architecture',
623          CONSOLE     = 'console',
624          MOBILE      = 'mobile',
625          TABLET      = 'tablet',
626          SMARTTV     = 'smarttv',
627          WEARABLE    = 'wearable',
628          EMBEDDED    = 'embedded';
629  
630  
631      ///////////
632      // Helper
633      //////////
634  
635  
636      var util = {
637          extend : function (regexes, extensions) {
638              var margedRegexes = {};
639              for (var i in regexes) {
640                  if (extensions[i] && extensions[i].length % 2 === 0) {
641                      margedRegexes[i] = extensions[i].concat(regexes[i]);
642                  } else {
643                      margedRegexes[i] = regexes[i];
644                  }
645              }
646              return margedRegexes;
647          },
648          has : function (str1, str2) {
649            if (typeof str1 === "string") {
650              return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;
651            } else {
652              return false;
653            }
654          },
655          lowerize : function (str) {
656              return str.toLowerCase();
657          },
658          major : function (version) {
659              return typeof(version) === STR_TYPE ? version.replace(/[^\d\.]/g,'').split(".")[0] : undefined;
660          },
661          trim : function (str) {
662            return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
663          }
664      };
665  
666  
667      ///////////////
668      // Map helper
669      //////////////
670  
671  
672      var mapper = {
673  
674          rgx : function (ua, arrays) {
675  
676              //var result = {},
677              var i = 0, j, k, p, q, matches, match;//, args = arguments;
678  
679              /*// construct object barebones
680              for (p = 0; p < args[1].length; p++) {
681                  q = args[1][p];
682                  result[typeof q === OBJ_TYPE ? q[0] : q] = undefined;
683              }*/
684  
685              // loop through all regexes maps
686              while (i < arrays.length && !matches) {
687  
688                  var regex = arrays[i],       // even sequence (0,2,4,..)
689                      props = arrays[i + 1];   // odd sequence (1,3,5,..)
690                  j = k = 0;
691  
692                  // try matching uastring with regexes
693                  while (j < regex.length && !matches) {
694  
695                      matches = regex[j++].exec(ua);
696  
697                      if (!!matches) {
698                          for (p = 0; p < props.length; p++) {
699                              match = matches[++k];
700                              q = props[p];
701                              // check if given property is actually array
702                              if (typeof q === OBJ_TYPE && q.length > 0) {
703                                  if (q.length == 2) {
704                                      if (typeof q[1] == FUNC_TYPE) {
705                                          // assign modified match
706                                          this[q[0]] = q[1].call(this, match);
707                                      } else {
708                                          // assign given value, ignore regex match
709                                          this[q[0]] = q[1];
710                                      }
711                                  } else if (q.length == 3) {
712                                      // check whether function or regex
713                                      if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
714                                          // call function (usually string mapper)
715                                          this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
716                                      } else {
717                                          // sanitize match using given regex
718                                          this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
719                                      }
720                                  } else if (q.length == 4) {
721                                          this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
722                                  }
723                              } else {
724                                  this[q] = match ? match : undefined;
725                              }
726                          }
727                      }
728                  }
729                  i += 2;
730              }
731              // console.log(this);
732              //return this;
733          },
734  
735          str : function (str, map) {
736  
737              for (var i in map) {
738                  // check if array
739                  if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
740                      for (var j = 0; j < map[i].length; j++) {
741                          if (util.has(map[i][j], str)) {
742                              return (i === UNKNOWN) ? undefined : i;
743                          }
744                      }
745                  } else if (util.has(map[i], str)) {
746                      return (i === UNKNOWN) ? undefined : i;
747                  }
748              }
749              return str;
750          }
751      };
752  
753  
754      ///////////////
755      // String map
756      //////////////
757  
758  
759      var maps = {
760  
761          browser : {
762              oldsafari : {
763                  version : {
764                      '1.0'   : '/8',
765                      '1.2'   : '/1',
766                      '1.3'   : '/3',
767                      '2.0'   : '/412',
768                      '2.0.2' : '/416',
769                      '2.0.3' : '/417',
770                      '2.0.4' : '/419',
771                      '?'     : '/'
772                  }
773              }
774          },
775  
776          device : {
777              amazon : {
778                  model : {
779                      'Fire Phone' : ['SD', 'KF']
780                  }
781              },
782              sprint : {
783                  model : {
784                      'Evo Shift 4G' : '7373KT'
785                  },
786                  vendor : {
787                      'HTC'       : 'APA',
788                      'Sprint'    : 'Sprint'
789                  }
790              }
791          },
792  
793          os : {
794              windows : {
795                  version : {
796                      'ME'        : '4.90',
797                      'NT 3.11'   : 'NT3.51',
798                      'NT 4.0'    : 'NT4.0',
799                      '2000'      : 'NT 5.0',
800                      'XP'        : ['NT 5.1', 'NT 5.2'],
801                      'Vista'     : 'NT 6.0',
802                      '7'         : 'NT 6.1',
803                      '8'         : 'NT 6.2',
804                      '8.1'       : 'NT 6.3',
805                      '10'        : ['NT 6.4', 'NT 10.0'],
806                      'RT'        : 'ARM'
807                  }
808              }
809          }
810      };
811  
812  
813      //////////////
814      // Regex map
815      /////////////
816  
817  
818      var regexes = {
819  
820          browser : [[
821  
822              // Presto based
823              /(opera\smini)\/([\w\.-]+)/i,                                       // Opera Mini
824              /(opera\s[mobiletab]+).+version\/([\w\.-]+)/i,                      // Opera Mobi/Tablet
825              /(opera).+version\/([\w\.]+)/i,                                     // Opera > 9.80
826              /(opera)[\/\s]+([\w\.]+)/i                                          // Opera < 9.80
827              ], [NAME, VERSION], [
828  
829              /(opios)[\/\s]+([\w\.]+)/i                                          // Opera mini on iphone >= 8.0
830              ], [[NAME, 'Opera Mini'], VERSION], [
831  
832              /\s(opr)\/([\w\.]+)/i                                               // Opera Webkit
833              ], [[NAME, 'Opera'], VERSION], [
834  
835              // Mixed
836              /(kindle)\/([\w\.]+)/i,                                             // Kindle
837              /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]*)/i,
838                                                                                  // Lunascape/Maxthon/Netfront/Jasmine/Blazer
839  
840              // Trident based
841              /(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i,
842                                                                                  // Avant/IEMobile/SlimBrowser/Baidu
843              /(?:ms|\()(ie)\s([\w\.]+)/i,                                        // Internet Explorer
844  
845              // Webkit/KHTML based
846              /(rekonq)\/([\w\.]*)/i,                                             // Rekonq
847              /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark)\/([\w\.-]+)/i
848                                                                                  // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser
849              ], [NAME, VERSION], [
850  
851              /(trident).+rv[:\s]([\w\.]+).+like\sgecko/i                         // IE11
852              ], [[NAME, 'IE'], VERSION], [
853  
854              /(edge|edgios|edgea)\/((\d+)?[\w\.]+)/i                             // Microsoft Edge
855              ], [[NAME, 'Edge'], VERSION], [
856  
857              /(yabrowser)\/([\w\.]+)/i                                           // Yandex
858              ], [[NAME, 'Yandex'], VERSION], [
859  
860              /(puffin)\/([\w\.]+)/i                                              // Puffin
861              ], [[NAME, 'Puffin'], VERSION], [
862  
vendor: 4,124 bytes, lines 863-944
863              /((?:[\s\/])uc?\s?browser|(?:juc.+)ucweb)[\/\s]?([\w\.]+)/i
864                                                                                  // UCBrowser
865              ], [[NAME, 'UCBrowser'], VERSION], [
866  
867              /(comodo_dragon)\/([\w\.]+)/i                                       // Comodo Dragon
868              ], [[NAME, /_/g, ' '], VERSION], [
869  
870              /(micromessenger)\/([\w\.]+)/i                                      // WeChat
871              ], [[NAME, 'WeChat'], VERSION], [
872  
873              /(qqbrowserlite)\/([\w\.]+)/i                                       // QQBrowserLite
874              ], [NAME, VERSION], [
875  
876              /(QQ)\/([\d\.]+)/i                                                  // QQ, aka ShouQ
877              ], [NAME, VERSION], [
878  
879              /m?(qqbrowser)[\/\s]?([\w\.]+)/i                                    // QQBrowser
880              ], [NAME, VERSION], [
881  
882              /(BIDUBrowser)[\/\s]?([\w\.]+)/i                                    // Baidu Browser
883              ], [NAME, VERSION], [
884  
885              /(2345Explorer)[\/\s]?([\w\.]+)/i                                   // 2345 Browser
886              ], [NAME, VERSION], [
887  
888              /(MetaSr)[\/\s]?([\w\.]+)/i                                         // SouGouBrowser
889              ], [NAME], [
890  
891              /(LBBROWSER)/i                                      // LieBao Browser
892              ], [NAME], [
893  
894              /xiaomi\/miuibrowser\/([\w\.]+)/i                                   // MIUI Browser
895              ], [VERSION, [NAME, 'MIUI Browser']], [
896  
897              /;fbav\/([\w\.]+);/i                                                // Facebook App for iOS & Android
898              ], [VERSION, [NAME, 'Facebook']], [
899  
900              /headlesschrome(?:\/([\w\.]+)|\s)/i                                 // Chrome Headless
901              ], [VERSION, [NAME, 'Chrome Headless']], [
902  
903              /\swv\).+(chrome)\/([\w\.]+)/i                                      // Chrome WebView
904              ], [[NAME, /(.+)/, '$1 WebView'], VERSION], [
905  
906              /((?:oculus|samsung)browser)\/([\w\.]+)/i
907              ], [[NAME, /(.+(?:g|us))(.+)/, '$1 $2'], VERSION], [                // Oculus / Samsung Browser
908  
909              /android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)*/i        // Android Browser
910              ], [VERSION, [NAME, 'Android Browser']], [
911  
912              /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i
913                                                                                  // Chrome/OmniWeb/Arora/Tizen/Nokia
914              ], [NAME, VERSION], [
915  
916              /(dolfin)\/([\w\.]+)/i                                              // Dolphin
917              ], [[NAME, 'Dolphin'], VERSION], [
918  
919              /((?:android.+)crmo|crios)\/([\w\.]+)/i                             // Chrome for Android/iOS
920              ], [[NAME, 'Chrome'], VERSION], [
921  
922              /(coast)\/([\w\.]+)/i                                               // Opera Coast
923              ], [[NAME, 'Opera Coast'], VERSION], [
924  
925              /fxios\/([\w\.-]+)/i                                                // Firefox for iOS
926              ], [VERSION, [NAME, 'Firefox']], [
927  
928              /version\/([\w\.]+).+?mobile\/\w+\s(safari)/i                       // Mobile Safari
929              ], [VERSION, [NAME, 'Mobile Safari']], [
930  
931              /version\/([\w\.]+).+?(mobile\s?safari|safari)/i                    // Safari & Safari Mobile
932              ], [VERSION, NAME], [
933  
934              /webkit.+?(gsa)\/([\w\.]+).+?(mobile\s?safari|safari)(\/[\w\.]+)/i  // Google Search Appliance on iOS
935              ], [[NAME, 'GSA'], VERSION], [
936  
937              /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i                     // Safari < 3.0
938              ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [
939  
940              /(konqueror)\/([\w\.]+)/i,                                          // Konqueror
941              /(webkit|khtml)\/([\w\.]+)/i
942              ], [NAME, VERSION], [
943  
944              // Gecko based
945              /(navigator|netscape)\/([\w\.-]+)/i                                 // Netscape
946              ], [[NAME, 'Netscape'], VERSION], [
947              /(swiftfox)/i,                                                      // Swiftfox
948              /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,
949                                                                                  // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
950              /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([\w\.-]+)$/i,
951  
952                                                                                  // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
953              /(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i,                          // Mozilla
954  
955              // Other
956              /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i,
957                                                                                  // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir
958              /(links)\s\(([\w\.]+)/i,                                            // Links
959              /(gobrowser)\/?([\w\.]*)/i,                                         // GoBrowser
960              /(ice\s?browser)\/v?([\w\._]+)/i,                                   // ICE Browser
961              /(mosaic)[\/\s]([\w\.]+)/i                                          // Mosaic
962              ], [NAME, VERSION]
963  
964              /* /////////////////////
965              // Media players BEGIN
966              ////////////////////////
967  
968              , [
969  
970              /(apple(?:coremedia|))\/((\d+)[\w\._]+)/i,                          // Generic Apple CoreMedia
971              /(coremedia) v((\d+)[\w\._]+)/i
972              ], [NAME, VERSION], [
973  
974              /(aqualung|lyssna|bsplayer)\/((\d+)?[\w\.-]+)/i                     // Aqualung/Lyssna/BSPlayer
975              ], [NAME, VERSION], [
976  
977              /(ares|ossproxy)\s((\d+)[\w\.-]+)/i                                 // Ares/OSSProxy
978              ], [NAME, VERSION], [
979  
980              /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/((\d+)[\w\.-]+)/i,
981                                                                                  // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC
982                                                                                  // NSPlayer/PSP-InternetRadioPlayer/Videos
983              /(clementine|music player daemon)\s((\d+)[\w\.-]+)/i,               // Clementine/MPD
984              /(lg player|nexplayer)\s((\d+)[\d\.]+)/i,
985              /player\/(nexplayer|lg player)\s((\d+)[\w\.-]+)/i                   // NexPlayer/LG Player
986              ], [NAME, VERSION], [
987              /(nexplayer)\s((\d+)[\w\.-]+)/i                                     // Nexplayer
988              ], [NAME, VERSION], [
989  
990              /(flrp)\/((\d+)[\w\.-]+)/i                                          // Flip Player
991              ], [[NAME, 'Flip Player'], VERSION], [
992  
993              /(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i
994                                                                                  // FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit
995              ], [NAME], [
996  
997              /(gstreamer) souphttpsrc (?:\([^\)]+\)){0,1} libsoup\/((\d+)[\w\.-]+)/i
998                                                                                  // Gstreamer
999              ], [NAME, VERSION], [
1000  
1001              /(htc streaming player)\s[\w_]+\s\/\s((\d+)[\d\.]+)/i,              // HTC Streaming Player
1002              /(java|python-urllib|python-requests|wget|libcurl)\/((\d+)[\w\.-_]+)/i,
1003                                                                                  // Java/urllib/requests/wget/cURL
1004              /(lavf)((\d+)[\d\.]+)/i                                             // Lavf (FFMPEG)
1005              ], [NAME, VERSION], [
1006  
1007              /(htc_one_s)\/((\d+)[\d\.]+)/i                                      // HTC One S
1008              ], [[NAME, /_/g, ' '], VERSION], [
1009  
1010              /(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+){0,1})/i
1011                                                                                  // MPlayer SVN
1012              ], [NAME, VERSION], [
1013  
1014              /(mplayer)(?:\s|\/|[unkow-]+)((\d+)[\w\.-]+)/i                      // MPlayer
1015              ], [NAME, VERSION], [
1016  
1017              /(mplayer)/i,                                                       // MPlayer (no other info)
1018              /(yourmuze)/i,                                                      // YourMuze
1019              /(media player classic|nero showtime)/i                             // Media Player Classic/Nero ShowTime
1020              ], [NAME], [
1021  
1022              /(nero (?:home|scout))\/((\d+)[\w\.-]+)/i                           // Nero Home/Nero Scout
1023              ], [NAME, VERSION], [
1024  
1025              /(nokia\d+)\/((\d+)[\w\.-]+)/i                                      // Nokia
1026              ], [NAME, VERSION], [
1027  
1028              /\s(songbird)\/((\d+)[\w\.-]+)/i                                    // Songbird/Philips-Songbird
1029              ], [NAME, VERSION], [
1030  
1031              /(winamp)3 version ((\d+)[\w\.-]+)/i,                               // W
1031inamp
1032              /(winamp)\s((\d+)[\w\.-]+)/i,
1033              /(winamp)mpeg\/((\d+)[\w\.-]+)/i
1034              ], [NAME, VERSION], [
1035  
1036              /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i  // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
1037                                                                                  // inlight radio
1038              ], [NAME], [
1039  
1040              /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/((\d+)[\w\.-]+)/i
1041                                                                                  // QuickTime/RealMedia/RadioApp/RadioClientApplication/
1042                                                                                  // SoundTap/Totem/Stagefright/Streamium
1043              ], [NAME, VERSION], [
1044  
1045              /(smp)((\d+)[\d\.]+)/i                                              // SMP
1046              ], [NAME, VERSION], [
1047  
1048              /(vlc) media player - version ((\d+)[\w\.]+)/i,                     // VLC Videolan
1049              /(vlc)\/((\d+)[\w\.-]+)/i,
1050              /(xbmc|gvfs|xine|xmms|irapp)\/((\d+)[\w\.-]+)/i,                    // XBMC/gvfs/Xine/XMMS/irapp
1051              /(foobar2000)\/((\d+)[\d\.]+)/i,                                    // Foobar2000
1052              /(itunes)\/((\d+)[\d\.]+)/i                                         // iTunes
1053              ], [NAME, VERSION], [
1054  
1055              /(wmplayer)\/((\d+)[\w\.-]+)/i,                                     // W
1055indows Media Player
1056              /(windows-media-player)\/((\d+)[\w\.-]+)/i
1057              ], [[NAME, /-/g, ' '], VERSION], [
1058  
1059              /windows\/((\d+)[\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i
1060                                                                                  // Windows Media Server
1061              ], [VERSION, [NAME, 'Windows']], [
1062  
1063              /(com\.riseupradioalarm)\/((\d+)[\d\.]*)/i                          // RiseUP Radio Alarm
1064              ], [NAME, VERSION], [
1065  
1066              /(rad.io)\s((\d+)[\d\.]+)/i,                                        // Rad.io
1067              /(radio.(?:de|at|fr))\s((\d+)[\d\.]+)/i
1068              ], [[NAME, 'rad.io'], VERSION]
1069  
1070              //////////////////////
1071              // Media players END
1072              ////////////////////*/
1073  
1074          ],
1075  
1076          cpu : [[
1077  
1078              /(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i                     // AMD64
1079              ], [[ARCHITECTURE, 'amd64']], [
1080  
1081              /(ia32(?=;))/i                                                      // IA32 (quicktime)
1082              ], [[ARCHITECTURE, util.lowerize]], [
1083  
1084              /((?:i[346]|x)86)[;\)]/i                                            // IA32
1085              ], [[ARCHITECTURE, 'ia32']], [
1086  
1087              // PocketPC mistakenly identified as PowerPC
1088              /windows\s(ce|mobile);\sppc;/i
1089              ], [[ARCHITECTURE, 'arm']], [
1090  
1091              /((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i                           // PowerPC
1092              ], [[ARCHITECTURE, /ower/, '', util.lowerize]], [
1093  
1094              /(sun4\w)[;\)]/i                                                    // SPARC
1095              ], [[ARCHITECTURE, 'sparc']], [
1096  
1097              /((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i
1098                                                                                  // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
1099              ], [[ARCHITECTURE, util.lowerize]]
1100          ],
1101  
1102          device : [[
1103  
1104              /\((ipad|playbook);[\w\s\);-]+(rim|apple)/i                         // iPad/PlayBook
1105              ], [MODEL, VENDOR, [TYPE, TABLET]], [
1106  
1107              /applecoremedia\/[\w\.]+ \((ipad)/                                  // iPad
1108              ], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [
1109  
1110              /(apple\s{0,1}tv)/i                                                 // Apple TV
1111              ], [[MODEL, 'Apple TV'], [VENDOR, 'Apple']], [
1112  
1113              /(archos)\s(gamepad2?)/i,                                           // Archos
1114              /(hp).+(touchpad)/i,                                                // HP TouchPad
1115              /(hp).+(tablet)/i,                                                  // HP Tablet
1116              /(kindle)\/([\w\.]+)/i,                                             // Kindle
1117              /\s(nook)[\w\s]+build\/(\w+)/i,                                     // Nook
1118              /(dell)\s(strea[kpr\s\d]*[\dko])/i                                  // Dell Streak
1119              ], [VENDOR, MODEL, [TYPE, TABLET]], [
1120  
1121              /(kf[A-z]+)\sbuild\/.+silk\//i                                      // Kindle Fire HD
1122              ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [
1123              /(sd|kf)[0349hijorstuw]+\sbuild\/.+silk\//i                         // Fire Phone
1124              ], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [
1125  
1126              /\((ip[honed|\s\w*]+);.+(apple)/i                                   // iPod/iPhone
1127              ], [MODEL, VENDOR, [TYPE, MOBILE]], [
1128              /\((ip[honed|\s\w*]+);/i                                            // iPod/iPhone
1129              ], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [
1130  
1131              /(blackberry)[\s-]?(\w+)/i,                                         // BlackBerry
1132              /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[\s_-]?([\w-]*)/i,
1133                                                                                  // BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
1134              /(hp)\s([\w\s]+\w)/i,                                               // HP iPAQ
1135              /(asus)-?(\w+)/i                                                    // Asus
1136              ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1137              /\(bb10;\s(\w+)/i                                                   // BlackBerry 10
1138              ], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [
1139                                                                                  // Asus Tablets
1140              /android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7|padfone)/i
1141              ], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [
1142  
1143              /(sony)\s(tablet\s[ps])\sbuild\//i,                                  // Sony
1144              /(sony)?(?:sgp.+)\sbuild\//i
1145              ], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [
1146              /android.+\s([c-g]\d{4}|so[-l]\w+)\sbuild\//i
1147              ], [MODEL, [VENDOR, 'Sony'], [TYPE, MOBILE]], [
1148  
1149              /\s(ouya)\s/i,                                                      // Ouya
1150              /(nintendo)\s([wids3u]+)/i                                          // Nintendo
1151              ], [VENDOR, MODEL, [TYPE, CONSOLE]], [
1152  
1153              /android.+;\s(shield)\sbuild/i                                      // Nvidia
1154              ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
1155  
1156              /(playstation\s[34portablevi]+)/i                                   // Playstation
1157              ], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [
1158  
1159              /(sprint\s(\w+))/i                                                  // Sprint Phones
1160              ], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [
1161  
vendor: 5,556 bytes, lines 1162-1259
1162              /(lenovo)\s?(S(?:5000|6000)+(?:[-][\w+]))/i                         // Lenovo tablets
1163              ], [VENDOR, MODEL, [TYPE, TABLET]], [
1164  
1165              /(htc)[;_\s-]+([\w\s]+(?=\))|\w+)*/i,                               // HTC
1166              /(zte)-(\w*)/i,                                                     // ZTE
1167              /(alcatel|geeksphone|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]*)/i
1168                                                                                  // Alcatel/GeeksPhone/Lenovo/Nexian/Panasonic/Sony
1169              ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
1170  
1171              /(nexus\s9)/i                                                       // HTC Nexus 9
1172              ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
1173  
1174              /d\/huawei([\w\s-]+)[;\)]/i,
1175              /(nexus\s6p)/i                                                      // Huawei
1176              ], [MODEL, [VENDOR, 'Huawei'], [TYPE, MOBILE]], [
1177  
1178              /(microsoft);\s(lumia[\s\w]+)/i                                     // Microsoft Lumia
1179              ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1180  
1181              /[\s\(;](xbox(?:\sone)?)[\s\);]/i                                   // Microsoft Xbox
1182              ], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [
1183              /(kin\.[onetw]{3})/i                                                // Microsoft Kin
1184              ], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [
1185  
1186                                                                                  // Motorola
1187              /\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?:?(\s4g)?)[\w\s]+build\//i,
1188              /mot[\s-]?(\w*)/i,
1189              /(XT\d{3,4}) build\//i,
1190              /(nexus\s6)/i
1191              ], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [
1192              /android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i
1193              ], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [
1194  
1195              /hbbtv\/\d+\.\d+\.\d+\s+\([\w\s]*;\s*(\w[^;]*);([^;]*)/i            // HbbTV devices
1196              ], [[VENDOR, util.trim], [MODEL, util.trim], [TYPE, SMARTTV]], [
1197  
1198              /hbbtv.+maple;(\d+)/i
1199              ], [[MODEL, /^/, 'SmartTV'], [VENDOR, 'Samsung'], [TYPE, SMARTTV]], [
1200  
1201              /\(dtv[\);].+(aquos)/i                                              // Sharp
1202              ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
1203  
1204              /android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n\d+|sgh-t8[56]9|nexus 10))/i,
1205              /((SM-T\w+))/i
1206              ], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [                  // Samsung
1207              /smart-tv.+(samsung)/i
1208              ], [VENDOR, [TYPE, SMARTTV], MODEL], [
1209              /((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-\w[\w\d]+))/i,
1210              /(sam[sung]*)[\s-]*(\w+-?[\w-]*)/i,
1211              /sec-((sgh\w+))/i
1212              ], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [
1213  
1214              /sie-(\w*)/i                                                        // Siemens
1215              ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
1216  
1217              /(maemo|nokia).*(n900|lumia\s\d+)/i,                                // Nokia
1218              /(nokia)[\s_-]?([\w-]*)/i
1219              ], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [
1220  
1221              /android\s3\.[\s\w;-]{10}(a\d{3})/i                                 // Acer
1222              ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
1223  
1224              /android.+([vl]k\-?\d{3})\s+build/i                                 // LG Tablet
1225              ], [MODEL, [VENDOR, 'LG'], [TYPE, TABLET]], [
1226              /android\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i                     // LG Tablet
1227              ], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [
1228              /(lg) netcast\.tv/i                                                 // LG SmartTV
1229              ], [VENDOR, MODEL, [TYPE, SMARTTV]], [
1230              /(nexus\s[45])/i,                                                   // LG
1231              /lg[e;\s\/-]+(\w*)/i,
1232              /android.+lg(\-?[\d\w]+)\s+build/i
1233              ], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [
1234  
1235              /android.+(ideatab[a-z0-9\-\s]+)/i                                  // Lenovo
1236              ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
1237  
1238              /linux;.+((jolla));/i                                               // Jolla
1239              ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1240  
1241              /((pebble))app\/[\d\.]+\s/i                                         // Pebble
1242              ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
1243  
1244              /android.+;\s(oppo)\s?([\w\s]+)\sbuild/i                            // OPPO
1245              ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1246  
1247              /crkey/i                                                            // Google Chromecast
1248              ], [[MODEL, 'Chromecast'], [VENDOR, 'Google']], [
1249  
1250              /android.+;\s(glass)\s\d/i                                          // Google Glass
1251              ], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [
1252  
1253              /android.+;\s(pixel c)\s/i                                          // Google Pixel C
1254              ], [MODEL, [VENDOR, 'Google'], [TYPE, TABLET]], [
1255  
1256              /android.+;\s(pixel xl|pixel)\s/i                                   // Google Pixel
1257              ], [MODEL, [VENDOR, 'Google'], [TYPE, MOBILE]], [
1258  
1259              /android.+;\s(\w+)\s+build\/hm\1/i,                                 // Xiaomi Hongmi 'numeric' models
vendor: 4,838 bytes, lines 1260-1340
1260              /android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i,               // Xiaomi Hongmi
1261              /android.+(mi[\s\-_]*(?:one|one[\s_]plus|note lte)?[\s_]*(?:\d?\w?)[\s_]*(?:plus)?)\s+build/i,    // Xiaomi Mi
1262              /android.+(redmi[\s\-_]*(?:note)?(?:[\s_]*[\w\s]+))\s+build/i       // Redmi Phones
1263              ], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [
1264              /android.+(mi[\s\-_]*(?:pad)(?:[\s_]*[\w\s]+))\s+build/i            // Mi Pad tablets
1265              ],[[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, TABLET]], [
1266              /android.+;\s(m[1-5]\snote)\sbuild/i                                // Meizu Tablet
1267              ], [MODEL, [VENDOR, 'Meizu'], [TYPE, TABLET]], [
1268  
1269              /android.+a000(1)\s+build/i,                                        // OnePlus
1270              /android.+oneplus\s(a\d{4})\s+build/i
1271              ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
1272  
1273              /android.+[;\/]\s*(RCT[\d\w]+)\s+build/i                            // RCA Tablets
1274              ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
1275  
1276              /android.+[;\/\s]+(Venue[\d\s]{2,7})\s+build/i                      // Dell Venue Tablets
1277              ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
1278  
1279              /android.+[;\/]\s*(Q[T|M][\d\w]+)\s+build/i                         // Verizon Tablet
1280              ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
1281  
1282              /android.+[;\/]\s+(Barnes[&\s]+Noble\s+|BN[RT])(V?.*)\s+build/i     // Barnes & Noble Tablet
1283              ], [[VENDOR, 'Barnes & Noble'], MODEL, [TYPE, TABLET]], [
1284  
1285              /android.+[;\/]\s+(TM\d{3}.*\b)\s+build/i                           // Barnes & Noble Tablet
1286              ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
1287  
1288              /android.+;\s(k88)\sbuild/i                                         // ZTE K Series Tablet
1289              ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
1290  
1291              /android.+[;\/]\s*(gen\d{3})\s+build.*49h/i                         // Swiss GEN Mobile
1292              ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
1293  
1294              /android.+[;\/]\s*(zur\d{3})\s+build/i                              // Swiss ZUR Tablet
1295              ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
1296  
1297              /android.+[;\/]\s*((Zeki)?TB.*\b)\s+build/i                         // Zeki Tablets
1298              ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
1299  
1300              /(android).+[;\/]\s+([YR]\d{2})\s+build/i,
1301              /android.+[;\/]\s+(Dragon[\-\s]+Touch\s+|DT)(\w{5})\sbuild/i        // Dragon Touch Tablet
1302              ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [
1303  
1304              /android.+[;\/]\s*(NS-?\w{0,9})\sbuild/i                            // Insignia Tablets
1305              ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
1306  
1307              /android.+[;\/]\s*((NX|Next)-?\w{0,9})\s+build/i                    // NextBook Tablets
1308              ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
1309  
1310              /android.+[;\/]\s*(Xtreme\_)?(V(1[045]|2[015]|30|40|60|7[05]|90))\s+build/i
1311              ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [                    // Voice Xtreme Phones
1312  
1313              /android.+[;\/]\s*(LVTEL\-)?(V1[12])\s+build/i                     // LvTel Phones
1314              ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
1315  
1316              /android.+[;\/]\s*(V(100MD|700NA|7011|917G).*\b)\s+build/i          // Envizen Tablets
1317              ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
1318  
1319              /android.+[;\/]\s*(Le[\s\-]+Pan)[\s\-]+(\w{1,9})\s+build/i          // Le Pan Tablets
1320              ], [VENDOR, MODEL, [TYPE, TABLET]], [
1321  
1322              /android.+[;\/]\s*(Trio[\s\-]*.*)\s+build/i                         // MachSpeed Tablets
1323              ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
1324  
1325              /android.+[;\/]\s*(Trinity)[\-\s]*(T\d{3})\s+build/i                // Trinity Tablets
1326              ], [VENDOR, MODEL, [TYPE, TABLET]], [
1327  
1328              /android.+[;\/]\s*TU_(1491)\s+build/i                               // Rotor Tablets
1329              ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [
1330  
1331              /android.+(KS(.+))\s+build/i                                        // Amazon Kindle Tablets
1332              ], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [
1333  
1334              /android.+(Gigaset)[\s\-]+(Q\w{1,9})\s+build/i                      // Gigaset Tablets
1335              ], [VENDOR, MODEL, [TYPE, TABLET]], [
1336  
1337              /\s(tablet|tab)[;\/]/i,                                             // Unidentifiable Tablet
1338              /\s(mobile)(?:[;\/]|\ssafari)/i                                     // Unidentifiable Mobile
1339              ], [[TYPE, util.lowerize], VENDOR, MODEL], [
1340  
1341              /(android[\w\.\s\-]{0,9});.+build/i                                 // Generic Android Device
1342              ], [MODEL, [VENDOR, 'Generic']]
1343  
1344  
1345          /*//////////////////////////
1346              // TODO: move to string map
1347              ////////////////////////////
1348  
1349              /(C6603)/i                                                          // Sony Xperia Z C6603
1350              ], [[MODEL, 'Xperia Z C6603'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [
1351              /(C6903)/i                                                          // Sony Xperia Z 1
1352              ], [[MODEL, 'Xperia Z 1'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [
1353  
1354              /(SM-G900[F|H])/i                                                   // Samsung Galaxy S5
1355              ], [[MODEL, 'Galaxy S5'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
1356              /(SM-G7102)/i                                                       // Samsung Galaxy Grand 2
1357              ], [[MODEL, 'Galaxy Grand 2'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
1358              /(SM-G530H)/i                                                       // Samsung Galaxy Grand Prime
1359              ], [[MODEL, 'Galaxy Grand Prime'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
1360              /(SM-G313HZ)/i                                                      // Samsung Galaxy V
1361              ], [[MODEL, 'Galaxy V'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
1362              /(SM-T805)/i                                                        // Samsung Galaxy Tab S 10.5
1363              ], [[MODEL, 'Galaxy Tab S 10.5'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [
1364              /(SM-G800F)/i                                                       // Samsung Galaxy S5 Mini
1365              ], [[MODEL, 'Galaxy S5 Mini'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [
1366              /(SM-T311)/i                                                        // Samsung Galaxy Tab 3 8.0
1367              ], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [
1368  
1369              /(T3C)/i                                                            // Advan Vandroid T3C
1370              ], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [
1371              /(ADVAN T1J\+)/i                                                    // Advan Vandroid T1J+
1372              ], [[MODEL, 'Vandroid T1J+'], [VENDOR, 'Advan'], [TYPE, TABLET]], [
1373              /(ADVAN S4A)/i                                                      // Advan Vandroid S4A
1374              ], [[MODEL, 'Vandroid S4A'], [VENDOR, 'Advan'], [TYPE, MOBILE]], [
1375  
1376              /(V972M)/i                                                          // ZTE V972M
1377              ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
1378  
1379              /(i-mobile)\s(IQ\s[\d\.]+)/i                                        // i-mobile IQ
1380              ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1381              /(IQ6.3)/i                                                          // i-mobile IQ IQ 6.3
1382              ], [[MODEL, 'IQ 6.3'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [
1383              /(i-mobile)\s(i-style\s[\d\.]+)/i                                   // i-mobile i-STYLE
1384              ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1385              /(i-STYLE2.1)/i                                                     // i-mobile i-STYLE 2.1
1386              ], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [
1387  
1388              /(mobiistar touch LAI 512)/i                                        // mobiistar touch LAI 512
1389              ], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [
1390  
1391              /////////////
1392              // END TODO
1393              ///////////*/
1394  
1395          ],
1396  
1397          engine : [[
1398  
1399              /windows.+\sedge\/([\w\.]+)/i                                       // EdgeHTML
1400              ], [VERSION, [NAME, 'EdgeHTML']], [
1401  
1402              /(presto)\/([\w\.]+)/i,                                             // Presto
1403              /(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,     // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m
1404              /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,                          // KHTML/Tasman/Links
1405              /(icab)[\/\s]([23]\.[\d\.]+)/i                                      // iCab
1406              ], [NAME, VERSION], [
1407  
1408              /rv\:([\w\.]{1,9}).+(gecko)/i                                       // Gecko
1409              ], [VERSION, NAME]
1410          ],
1411  
1412          os : [[
1413  
1414              // Windows based
1415              /microsoft\s(windows)\s(vista|xp)/i                                 // Windows (iTunes)
1416              ], [NAME, VERSION], [
1417              /(windows)\snt\s6\.2;
1417\s(arm)/i,                                     // Windows RT
1418              /(windows\sphone(?:\sos)*)[\s\/]?([\d\.\s\w]*)/i,                   // Windows Phone
1419              /(windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i
1420              ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [
1421              /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i
1422              ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [
1423  
1424              // Mobile/Embedded OS
1425              /\((bb)(10);/i                                                      // BlackBerry 10
1426              ], [[NAME, 'BlackBerry'], VERSION], [
1427              /(blackberry)\w*\/?([\w\.]*)/i,                                     // Blackberry
1428              /(tizen)[\/\s]([\w\.]+)/i,                                          // Tizen
1429              /(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]*)/i,
1430                                                                                  // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki
1431              /linux;.+(sailfish);/i                                              // Sailfish OS
1432              ], [NAME, VERSION], [
1433              /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]*)/i                  // Symbian
1434              ], [[NAME, 'Symbian'], VERSION], [
1435              /\((series40);/i                                                    // Series 40
1436              ], [NAME], [
1437              /mozilla.+\(mobile;.+gecko.+firefox/i                               // Firefox OS
1438              ], [[NAME, 'Firefox OS'], VERSION], [
1439  
1440              // Console
1441              /(nintendo|playstation)\s([wids34portablevu]+)/i,                   // Nintendo
vendor: 6,103 bytes, lines 1441-1594
1441/Playstation
1442  
1443              // GNU/Linux based
1444              /(mint)[\/\s\(]?(\w*)/i,                                            // Mint
1445              /(mageia|vectorlinux)[;\s]/i,                                       // Mageia/VectorLinux
1446              /(joli|[kxln]?ubuntu|debian|suse|opensuse|gentoo|(?=\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?(?!chrom)([\w\.-]*)/i,
1447                                                                                  // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
1448                                                                                  // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus
1449              /(hurd|linux)\s?([\w\.]*)/i,                                        // Hurd/Linux
1450              /(gnu)\s?([\w\.]*)/i                                                // GNU
1451              ], [NAME, VERSION], [
1452  
1453              /(cros)\s[\w]+\s([\w\.]+\w)/i                                       // Chromium OS
1454              ], [[NAME, 'Chromium OS'], VERSION],[
1455  
1456              // Solaris
1457              /(sunos)\s?([\w\.\d]*)/i                                            // Solaris
1458              ], [[NAME, 'Solaris'], VERSION], [
1459  
1460              // BSD based
1461              /\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]*)/i                    // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly
1462              ], [NAME, VERSION],[
1463  
1464              /(haiku)\s(\w+)/i                                                   // Haiku
1465              ], [NAME, VERSION],[
1466  
1467              /cfnetwork\/.+darwin/i,
1468              /ip[honead]{2,4}(?:.*os\s([\w]+)\slike\smac|;\sopera)/i             // iOS
1469              ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
1470  
1471              /(mac\sos\sx)\s?([\w\s\.]*)/i,
1472              /(macintosh|mac(?=_powerpc)\s)/i                                    // Mac OS
1473              ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [
1474  
1475              // Other
1476              /((?:open)?solaris)[\/\s-]?([\w\.]*)/i,                             // Solaris
1477              /(aix)\s((\d)(?=\.|\)|\s)[\w\.])*/i,                                // AIX
1478              /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,
1479                                                                                  // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS
1480              /(unix)\s?([\w\.]*)/i                                               // UNIX
1481              ], [NAME, VERSION]
1482          ]
1483      };
1484  
1485  
1486      /////////////////
1487      // Constructor
1488      ////////////////
1489      /*
1490      var Browser = function (name, version) {
1491          this[NAME] = name;
1492          this[VERSION] = version;
1493      };
1494      var CPU = function (arch) {
1495          this[ARCHITECTURE] = arch;
1496      };
1497      var Device = function (vendor, model, type) {
1498          this[VENDOR] = vendor;
1499          this[MODEL] = model;
1500          this[TYPE] = type;
1501      };
1502      var Engine = Browser;
1503      var OS = Browser;
1504      */
1505      var UAParser = function (uastring, extensions) {
1506  
1507          if (typeof uastring === 'object') {
1508              extensions = uastring;
1509              uastring = undefined;
1510          }
1511  
1512          if (!(this instanceof UAParser)) {
1513              return new UAParser(uastring, extensions).getResult();
1514          }
1515  
1516          var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
1517          var rgxmap = extensions ? util.extend(regexes, extensions) : regexes;
1518          //var browser = new Browser();
1519          //var cpu = new CPU();
1520          //var device = new Device();
1521          //var engine = new Engine();
1522          //var os = new OS();
1523  
1524          this.getBrowser = function () {
1525              var browser = { name: undefined, version: undefined };
1526              mapper.rgx.call(browser, ua, rgxmap.browser);
1527              browser.major = util.major(browser.version); // deprecated
1528              return browser;
1529          };
1530          this.getCPU = function () {
1531              var cpu = { architecture: undefined };
1532              mapper.rgx.call(cpu, ua, rgxmap.cpu);
1533              return cpu;
1534          };
1535          this.getDevice = function () {
1536              var device = { vendor: undefined, model: undefined, type: undefined };
1537              mapper.rgx.call(device, ua, rgxmap.device);
1538              return device;
1539          };
1540          this.getEngine = function () {
1541              var engine = { name: undefined, version: undefined };
1542              mapper.rgx.call(engine, ua, rgxmap.engine);
1543              return engine;
1544          };
1545          this.getOS = function () {
1546              var os = { name: undefined, version: undefined };
1547              mapper.rgx.call(os, ua, rgxmap.os);
1548              return os;
1549          };
1550          this.getResult = function () {
1551              return {
1552                  ua      : this.getUA(),
1553                  browser : this.getBrowser(),
1554                  engine  : this.getEngine(),
1555                  os      : this.getOS(),
1556                  device  : this.getDevice(),
1557                  cpu     : this.getCPU()
1558              };
1559          };
1560          this.getUA = function () {
1561              return ua;
1562          };
1563          this.setUA = function (uastring) {
1564              ua = uastring;
1565              //browser = new Browser();
1566              //cpu = new CPU();
1567              //device = new Device();
1568              //engine = new Engine();
1569              //os = new OS();
1570              return this;
1571          };
1572          return this;
1573      };
1574  
1575      UAParser.VERSION = LIBVERSION;
1576      UAParser.BROWSER = {
1577          NAME    : NAME,
1578          MAJOR   : MAJOR, // deprecated
1579          VERSION : VERSION
1580      };
1581      UAParser.CPU = {
1582          ARCHITECTURE : ARCHITECTURE
1583      };
1584      UAParser.DEVICE = {
1585          MODEL   : MODEL,
1586          VENDOR  : VENDOR,
1587          TYPE    : TYPE,
1588          CONSOLE : CONSOLE,
1589          MOBILE  : MOBILE,
1590          SMARTTV : SMARTTV,
1591          TABLET  : TABLET,
1592          WEARABLE: WEARABLE,
1593          EMBEDDED: EMBEDDED
1594      };
1595      UAParser.ENGINE = {
1596          NAME    : NAME,
1597          VERSION : VERSION
1598      };
1599      UAParser.OS = {
1600          NAME    : NAME,
1601          VERSION : VERSION
1602      };
1603      //UAParser.Utils = util;
1604  
1605      ///////////
1606      // Export
1607      //////////
1608  
1609  
1610      // check js environment
1611      if (typeof(exports) !== UNDEF_TYPE) {
1612          // nodejs env
1613          if (typeof module !== UNDEF_TYPE && module.exports) {
1614              exports = module.exports = UAParser;
1615          }
1616          // TODO: test!!!!!!!!
1617          /*
1618          if (require && require.main === module && process) {
1619              // cli
1620              var jsonize = function (arr) {
1621                  var res = [];
1622                  for (var i in arr) {
1623                      res.push(new UAParser(arr[i]).getResult());
1624                  }
1625                  process.stdout.write(JSON.stringify(res, null, 2) + '\n');
1626              };
1627              if (process.stdin.isTTY) {
1628                  // via args
1629                  jsonize(process.argv.slice(2));
1630              } else {
1631                  // via pipe
1632                  var str = '';
1633                  process.stdin.on('readable', function() {
1634                      var read = process.stdin.read();
1635                      if (read !== null) {
1636                          str += read;
1637                      }
1638                  });
1639                  process.stdin.on('end', function () {
1640                      jsonize(str.replace(/\n$/, '').split('\n'));
1641                  });
1642              }
1643          }
1644          */
1645          exports.UAParser = UAParser;
1646      } else {
1647          // requirejs env (optional)
1648          if (typeof(define) === FUNC_TYPE && define.amd) {
1649              define(function () {
1650                  return UAParser;
1651              });
1652          } else if (window) {
1653              // browser env
1654              window.UAParser = UAParser;
1655          }
1656      }
1657  
1658      // jQuery/Zepto specific (optional)
1659      // Note:
1660      //   In AMD env the global scope should be kept clean, but jQuery is an exception.
1661      //   jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
1662      //   and we should catch that.
1663      var $ = window && (window.jQuery || window.Zepto);
1664      if (typeof $ !== UNDEF_TYPE) {
1665          var parser = new UAParser();
1666          $.ua = parser.getResult();
1667          $.ua.get = function () {
1668              return parser.getUA();
1669          };
1670          $.ua.set = function (uastring) {
1671              parser.setUA(uastring);
1672              var result = parser.getResult();
1673              for (var prop in result) {
1674                  $.ua[prop] = result[prop];
1675              }
1676          };
1677      }
1678  
1679  })(typeof window === 'object' ? window : this);
1680  
1681  },{}]},{},[2])(2)
1682  });
1683  
1684  outdatedBrowserRework({
1685    browserSupport: {
1686      Chrome: 80, // Includes Chrome for mobile devices
1687      Chromium: 80,
1688      Edge: 80,
1689      Safari: 13,
1690      'Mobile Safari': 14,
1691      Opera: 67,
1692      Firefox: 78,
1693      Vivaldi: 1,
1694      Yandex: 14,
1695      IE: false,
1696    },
1697    isUnknownBrowserOK: true,
1698    requiredCssProperty: 'flex',
1699    messages: {
1700      en: {
1701        outOfDate: 'Your browser is out of date!',
1702        unsupported: 'Your browser is not supported!',
1703        update: {
1704          web: 'Update your browser to view and use this website correctly.',
1705          googlePlay: 'Please install Chrome from Google Play',
1706          appStore: 'Please update iOS from the Settings App',
1707        },
1708        url: 'http://outdatedbrowser.com/',
1709        callToAction: 'Update my browser now',
1710        close: 'Close',
1711      },
1712      de: {
1713        outOfDate: 'Ihr Browser ist veraltet!',
1714        unsupported: 'Ihr Browser wird nicht unterstützt!',
1715        update: {
1716          web: 'Aktualisieren Sie Ihren Browser, um diese Website korrekt anzuzeigen und alle Funktionen nutzen zu können',
1717          googlePlay: 'Bitte installieren Sie Chrome von Google Play',
1718          appStore: 'Bitte aktualisieren Sie iOS über die Einstellungen',
1719        },
1720        url: 'http://outdatedbrowser.com/',
1721        callToAction: 'meinen Browser jetzt aktualisieren',
1722        close: 'Schließen',
1723      },
1724    },
1725    backgroundColor: '#323f67',
1726  });

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.