JAVASCRIPT   16

detect.js

Guest on 26th July 2021 04:25:16 PM

  1. /**
  2.  * Detect.js: User-Agent Parser
  3.  * https://github.com/darcyclarke/Detect.js
  4.  * Dual licensed under the MIT and GPL licenses.
  5.  *
  6.  * @version 2.2.0
  7.  * @author Darcy Clarke
  8.  * @url http://darcyclarke.me
  9.  * @createdat Mon Dec 02 2013 14:47:23 GMT+0100 (W. Europe Standard Time)
  10.  *
  11.  * Based on UA-Parser (https://github.com/tobie/ua-parser) by Tobie Langel
  12.  *
  13.  * Example Usage:
  14.  * var agentInfo = detect.parse(navigator.userAgent);
  15.  * console.log(agentInfo.browser.family); // Chrome
  16.  *
  17.  */
  18. (function (root, undefined) {
  19.     // Shim Array.prototype.map if necessary
  20.     // Production steps of ECMA-262, Edition 5, 15.4.4.19
  21.     // Reference: http://es5.github.com/#x15.4.4.19
  22.     if (!Array.prototype.map) {
  23.         Array.prototype.map = function (callback, thisArg) {
  24.             var T, A, k;
  25.             if (this == null) {
  26.                 throw new TypeError(" this is null or not defined");
  27.             }
  28.             // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
  29.             var O = Object(this);
  30.             // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
  31.             // 3. Let len be ToUint32(lenValue).
  32.             var len = O.length >>> 0;
  33.             // 4. If IsCallable(callback) is false, throw a TypeError exception.
  34.             // See: http://es5.github.com/#x9.11
  35.             if (typeof callback !== "function") {
  36.                 throw new TypeError(callback + " is not a function");
  37.             }
  38.             // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  39.             if (thisArg) {
  40.                 T = thisArg;
  41.             }
  42.             // 6. Let A be a new array created as if by the expression new Array(len) where Array is
  43.             // the standard built-in constructor with that name and len is the value of len.
  44.             A = new Array(len);
  45.             // 7. Let k be 0
  46.             k = 0;
  47.             // 8. Repeat, while k < len
  48.             while (k < len) {
  49.                 var kValue, mappedValue;
  50.                 // a. Let Pk be ToString(k).
  51.                 //   This is implicit for LHS operands of the in operator
  52.                 // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
  53.                 //   This step can be combined with c
  54.                 // c. If kPresent is true, then
  55.                 if (k in O) {
  56.                     // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
  57.                     kValue = O[k];
  58.                     // ii. Let mappedValue be the result of calling the Call internal method of callback
  59.                     // with T as the this value and argument list containing kValue, k, and O.
  60.                     mappedValue = callback.call(T, kValue, k, O);
  61.                     // iii. Call the DefineOwnProperty internal method of A with arguments
  62.                     // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
  63.                     // and false.
  64.                     // In browsers that support Object.defineProperty, use the following:
  65.                     // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
  66.                     // For best browser support, use the following:
  67.                     A[k] = mappedValue;
  68.                 }
  69.                 // d. Increase k by 1.
  70.                 k++;
  71.             }
  72.             // 9. return A
  73.             return A;
  74.         };
  75.     }
  76.     // Detect
  77.     var detect = root.detect = function () {
  78.         // Context
  79.         var _this = function () {
  80.         };
  81.         // Regexes
  82.         var regexes = {
  83.             browser_parsers: [{
  84.                     regex: "^(Opera)/(\\d+)\\.(\\d+) \\(Nintendo Wii",
  85.                     family_replacement: "Wii",
  86.                     manufacturer: "Nintendo"
  87.                 }, {
  88.                     regex: "(SeaMonkey|Camino)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)",
  89.                     family_replacement: "Camino",
  90.                     other: true
  91.                 }, {
  92.                     regex: "(Pale[Mm]oon)/(\\d+)\\.(\\d+)\\.?(\\d+)?",
  93.                     family_replacement: "Pale Moon (Firefox Variant)",
  94.                     other: true
  95.                 }, {
  96.                     regex: "(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)",
  97.                     family_replacement: "Firefox Mobile"
  98.                 }, {
  99.                     regex: "(Fennec)/(\\d+)\\.(\\d+)(pre)",
  100.                     family_replacment: "Firefox Mobile"
  101.                 }, {
  102.                     regex: "(Fennec)/(\\d+)\\.(\\d+)",
  103.                     family_replacement: "Firefox Mobile"
  104.                 }, {
  105.                     regex: "Mobile.*(Firefox)/(\\d+)\\.(\\d+)",
  106.                     family_replacement: "Firefox Mobile"
  107.                 }, {
  108.                     regex: "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?)",
  109.                     family_replacement: "Firefox ($1)"
  110.                 }, {
  111.                     regex: "(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)",
  112.                     family_replacement: "Firefox Alpha"
  113.                 }, {
  114.                     regex: "(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)",
  115.                     family_replacement: "Firefox Beta"
  116.                 }, {
  117.                     regex: "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(a\\d+[a-z]*)",
  118.                     family_replacement: "Firefox Alpha"
  119.                 }, {
  120.                     regex: "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(b\\d+[a-z]*)",
  121.                     family_replacement: "Firefox Beta"
  122.                 }, {
  123.                     regex: "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?",
  124.                     family_replacement: "Firefox ($1)"
  125.                 }, {
  126.                     regex: "(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)",
  127.                     family_replacement: "MicroB",
  128.                     tablet: true
  129.                 }, {
  130.                     regex: "(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?"
  131.                 }, {
  132.                     regex: "(Flock)/(\\d+)\\.(\\d+)(b\\d+?)",
  133.                     family_replacement: "Flock",
  134.                     other: true
  135.                 }, {
  136.                     regex: "(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)",
  137.                     family_replacement: "Rockmelt",
  138.                     other: true
  139.                 }, {
  140.                     regex: "(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)",
  141.                     family_replacement: "Netscape"
  142.                 }, {
  143.                     regex: "(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)",
  144.                     family_replacement: "Netscape"
  145.                 }, {
  146.                     regex: "(Netscape6)/(\\d+)\\.(\\d+)\\.(\\d+)",
  147.                     family_replacement: "Netscape"
  148.                 }, {
  149.                     regex: "(MyIBrow)/(\\d+)\\.(\\d+)",
  150.                     family_replacement: "My Internet Browser",
  151.                     other: true
  152.                 }, {
  153.                     regex: "(Opera Tablet).*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  154.                     family_replacement: "Opera Tablet",
  155.                     tablet: true
  156.                 }, {
  157.                     regex: "(Opera)/.+Opera Mobi.+Version/(\\d+)\\.(\\d+)",
  158.                     family_replacement: "Opera Mobile"
  159.                 }, {
  160.                     regex: "Opera Mobi",
  161.                     family_replacement: "Opera Mobile"
  162.                 }, {
  163.                     regex: "(Opera Mini)/(\\d+)\\.(\\d+)",
  164.                     family_replacement: "Opera Mini"
  165.                 }, {
  166.                     regex: "(Opera Mini)/att/(\\d+)\\.(\\d+)",
  167.                     family_replacement: "Opera Mini"
  168.                 }, {
  169.                     regex: "(Opera)/9.80.*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  170.                     family_replacement: "Opera"
  171.                 }, {
  172.                     regex: "(webOSBrowser)/(\\d+)\\.(\\d+)",
  173.                     family_replacement: "webOS"
  174.                 }, {
  175.                     regex: "(webOS)/(\\d+)\\.(\\d+)",
  176.                     family_replacement: "webOS"
  177.                 }, {
  178.                     regex: "(wOSBrowser).+TouchPad/(\\d+)\\.(\\d+)",
  179.                     family_replacement: "webOS TouchPad"
  180.                 }, {
  181.                     regex: "(luakit)",
  182.                     family_replacement: "LuaKit",
  183.                     other: true
  184.                 }, {
  185.                     regex: "(Lightning)/(\\d+)\\.(\\d+)([ab]?\\d+[a-z]*)",
  186.                     family_replacement: "Lightning",
  187.                     other: true
  188.                 }, {
  189.                     regex: "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?) \\(Swiftfox\\)",
  190.                     family_replacement: "Swiftfox",
  191.                     other: true
  192.                 }, {
  193.                     regex: "(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)? \\(Swiftfox\\)",
  194.                     family_replacement: "Swiftfox",
  195.                     other: true
  196.                 }, {
  197.                     regex: "rekonq",
  198.                     family_replacement: "Rekonq",
  199.                     other: true
  200.                 }, {
  201.                     regex: "(conkeror|Conkeror)/(\\d+)\\.(\\d+)\\.?(\\d+)?",
  202.                     family_replacement: "Conkeror",
  203.                     other: true
  204.                 }, {
  205.                     regex: "(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)",
  206.                     family_replacement: "Konqueror",
  207.                     other: true
  208.                 }, {
  209.                     regex: "(WeTab)-Browser",
  210.                     family_replacement: "WeTab",
  211.                     other: true
  212.                 }, {
  213.                     regex: "(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)",
  214.                     family_replacement: "Comodo Dragon",
  215.                     other: true
  216.                 }, {
  217.                     regex: "(YottaaMonitor)",
  218.                     family_replacement: "Yottaa Monitor",
  219.                     other: true
  220.                 }, {
  221.                     regex: "(Kindle)/(\\d+)\\.(\\d+)",
  222.                     family_replacement: "Kindle"
  223.                 }, {
  224.                     regex: "(Symphony) (\\d+).(\\d+)",
  225.                     family_replacement: "Symphony",
  226.                     other: true
  227.                 }, {
  228.                     regex: "Minimo",
  229.                     family_replacement: "Minimo",
  230.                     other: true
  231.                 }, {
  232.                     regex: "(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
  233.                     family_replacement: "Chrome Mobile"
  234.                 }, {
  235.                     regex: "(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
  236.                     family_replacement: "Chrome Mobile iOS"
  237.                 }, {
  238.                     regex: "(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile",
  239.                     family_replacement: "Chrome Mobile"
  240.                 }, {
  241.                     regex: "(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)",
  242.                     family_replacement: "Chrome Frame"
  243.                 }, {
  244.                     regex: "(UC Browser)(\\d+)\\.(\\d+)\\.(\\d+)",
  245.                     family_replacement: "UC Browser",
  246.                     other: true
  247.                 }, {
  248.                     regex: "(SLP Browser)/(\\d+)\\.(\\d+)",
  249.                     family_replacement: "Tizen Browser",
  250.                     other: true
  251.                 }, {
  252.                     regex: "(Epiphany)/(\\d+)\\.(\\d+).(\\d+)",
  253.                     family_replacement: "Epiphany",
  254.                     other: true
  255.                 }, {
  256.                     regex: "(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)",
  257.                     family_replacement: "Sogou Explorer",
  258.                     other: true
  259.                 }, {
  260.                     regex: "(Pingdom.com_bot_version_)(\\d+)\\.(\\d+)",
  261.                     family_replacement: "PingdomBot",
  262.                     other: true
  263.                 }, {
  264.                     regex: "(facebookexternalhit)/(\\d+)\\.(\\d+)",
  265.                     family_replacement: "FacebookBot"
  266.                 }, {
  267.                     regex: "(Twitterbot)/(\\d+)\\.(\\d+)",
  268.                     family_replacement: "TwitterBot"
  269.                 }, {
  270.                     regex: "(AdobeAIR|Chromium|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iron|Iris|UP\\.Browser|Bunjaloo|Google Earth|Raven for Mac)/(\\d+)\\.(\\d+)\\.(\\d+)"
  271.                 }, {
  272.                     regex: "(Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Iron|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris)/(\\d+)\\.(\\d+)"
  273.                 }, {
  274.                     regex: "(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)"
  275.                 }, {
  276.                     regex: "(iCab|Lunascape|Opera|Android|Jasmine|Polaris|BREW) (\\d+)\\.(\\d+)\\.?(\\d+)?"
  277.                 }, {
  278.                     regex: "(Android) Donut",
  279.                     v2_replacement: "2",
  280.                     v1_replacement: "1"
  281.                 }, {
  282.                     regex: "(Android) Eclair",
  283.                     v2_replacement: "1",
  284.                     v1_replacement: "2"
  285.                 }, {
  286.                     regex: "(Android) Froyo",
  287.                     v2_replacement: "2",
  288.                     v1_replacement: "2"
  289.                 }, {
  290.                     regex: "(Android) Gingerbread",
  291.                     v2_replacement: "3",
  292.                     v1_replacement: "2"
  293.                 }, {
  294.                     regex: "(Android) Honeycomb",
  295.                     v1_replacement: "3"
  296.                 }, {
  297.                     regex: "(IEMobile)[ /](\\d+)\\.(\\d+)",
  298.                     family_replacement: "IE Mobile"
  299.                 }, {
  300.                     regex: "(MSIE) (\\d+)\\.(\\d+).*XBLWP7",
  301.                     family_replacement: "IE Large Screen"
  302.                 }, {
  303.                     regex: "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)"
  304.                 }, {
  305.                     regex: "(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*)?"
  306.                 }, {
  307.                     regex: "(Obigo)InternetBrowser",
  308.                     other: true
  309.                 }, {
  310.                     regex: "(Obigo)\\-Browser",
  311.                     other: true
  312.                 }, {
  313.                     regex: "(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+))?",
  314.                     other: true
  315.                 }, {
  316.                     regex: "(MAXTHON|Maxthon) (\\d+)\\.(\\d+)",
  317.                     family_replacement: "Maxthon",
  318.                     other: true
  319.                 }, {
  320.                     regex: "(Maxthon|MyIE2|Uzbl|Shiira)",
  321.                     v1_replacement: "0",
  322.                     other: true
  323.                 }, {
  324.                     regex: "(PLAYSTATION) (\\d+)",
  325.                     family_replacement: "PlayStation",
  326.                     manufacturer: "Sony"
  327.                 }, {
  328.                     regex: "(PlayStation Portable)[^\\d]+(\\d+).(\\d+)",
  329.                     manufacturer: "Sony"
  330.                 }, {
  331.                     regex: "(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)",
  332.                     other: true
  333.                 }, {
  334.                     regex: "(POLARIS)/(\\d+)\\.(\\d+)",
  335.                     family_replacement: "Polaris",
  336.                     other: true
  337.                 }, {
  338.                     regex: "(Embider)/(\\d+)\\.(\\d+)",
  339.                     family_replacement: "Polaris",
  340.                     other: true
  341.                 }, {
  342.                     regex: "(BonEcho)/(\\d+)\\.(\\d+)\\.(\\d+)",
  343.                     family_replacement: "Bon Echo",
  344.                     other: true
  345.                 }, {
  346.                     regex: "(iPod).+Version/(\\d+)\\.(\\d+)\\.(\\d+)",
  347.                     family_replacement: "Mobile Safari",
  348.                     manufacturer: "Apple"
  349.                 }, {
  350.                     regex: "(iPod).*Version/(\\d+)\\.(\\d+)",
  351.                     family_replacement: "Mobile Safari",
  352.                     manufacturer: "Apple"
  353.                 }, {
  354.                     regex: "(iPod)",
  355.                     family_replacement: "Mobile Safari",
  356.                     manufacturer: "Apple"
  357.                 }, {
  358.                     regex: "(iPhone).*Version/(\\d+)\\.(\\d+)\\.(\\d+)",
  359.                     family_replacement: "Mobile Safari",
  360.                     manufacturer: "Apple"
  361.                 }, {
  362.                     regex: "(iPhone).*Version/(\\d+)\\.(\\d+)",
  363.                     family_replacement: "Mobile Safari",
  364.                     manufacturer: "Apple"
  365.                 }, {
  366.                     regex: "(iPhone)",
  367.                     family_replacement: "Mobile Safari",
  368.                     manufacturer: "Apple"
  369.                 }, {
  370.                     regex: "(iPad).*Version/(\\d+)\\.(\\d+)\\.(\\d+)",
  371.                     family_replacement: "Mobile Safari",
  372.                     tablet: true,
  373.                     manufacturer: "Apple"
  374.                 }, {
  375.                     regex: "(iPad).*Version/(\\d+)\\.(\\d+)",
  376.                     family_replacement: "Mobile Safari",
  377.                     tablet: true,
  378.                     manufacturer: "Apple"
  379.                 }, {
  380.                     regex: "(iPad)",
  381.                     family_replacement: "Mobile Safari",
  382.                     tablet: true,
  383.                     manufacturer: "Apple"
  384.                 }, {
  385.                     regex: "(AvantGo) (\\d+).(\\d+)",
  386.                     other: true
  387.                 }, {
  388.                     regex: "(Avant)",
  389.                     v1_replacement: "1",
  390.                     other: true
  391.                 }, {
  392.                     regex: "^(Nokia)",
  393.                     family_replacement: "Nokia Services (WAP) Browser",
  394.                     manufacturer: "Nokia"
  395.                 }, {
  396.                     regex: "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)",
  397.                     manufacturer: "Nokia"
  398.                 }, {
  399.                     regex: "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)",
  400.                     manufacturer: "Nokia"
  401.                 }, {
  402.                     regex: "(NokiaBrowser)/(\\d+)\\.(\\d+)",
  403.                     manufacturer: "Nokia"
  404.                 }, {
  405.                     regex: "(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)",
  406.                     family_replacement: "NokiaBrowser",
  407.                     manufacturer: "Nokia"
  408.                 }, {
  409.                     regex: "(Series60)/5\\.0",
  410.                     v2_replacement: "0",
  411.                     v1_replacement: "7",
  412.                     family_replacement: "NokiaBrowser",
  413.                     manufacturer: "Nokia"
  414.                 }, {
  415.                     regex: "(Series60)/(\\d+)\\.(\\d+)",
  416.                     family_replacement: "Nokia OSS Browser",
  417.                     manufacturer: "Nokia"
  418.                 }, {
  419.                     regex: "(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
  420.                     family_replacement: "Nokia Series 40 Ovi Browser",
  421.                     manufacturer: "Nokia"
  422.                 }, {
  423.                     regex: "(Nokia)[EN]?(\\d+)",
  424.                     manufacturer: "Nokia"
  425.                 }, {
  426.                     regex: "(PlayBook).+RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)",
  427.                     family_replacement: "Blackberry WebKit",
  428.                     tablet: true,
  429.                     manufacturer: "Nokia"
  430.                 }, {
  431.                     regex: "(Black[bB]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)",
  432.                     family_replacement: "Blackberry WebKit",
  433.                     manufacturer: "RIM"
  434.                 }, {
  435.                     regex: "(Black[bB]erry)\\s?(\\d+)",
  436.                     family_replacement: "Blackberry",
  437.                     manufacturer: "RIM"
  438.                 }, {
  439.                     regex: "(OmniWeb)/v(\\d+)\\.(\\d+)",
  440.                     other: true
  441.                 }, {
  442.                     regex: "(Blazer)/(\\d+)\\.(\\d+)",
  443.                     family_replacement: "Palm Blazer",
  444.                     manufacturer: "Palm"
  445.                 }, {
  446.                     regex: "(Pre)/(\\d+)\\.(\\d+)",
  447.                     family_replacement: "Palm Pre",
  448.                     manufacturer: "Palm"
  449.                 }, {
  450.                     regex: "(Links) \\((\\d+)\\.(\\d+)",
  451.                     other: true
  452.                 }, {
  453.                     regex: "(QtWeb) Internet Browser/(\\d+)\\.(\\d+)",
  454.                     other: true
  455.                 }, {
  456.                     regex: "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?",
  457.                     other: true,
  458.                     tablet: true
  459.                 }, {
  460.                     regex: "(AppleWebKit)/(\\d+)\\.?(\\d+)?\\+ .* Version/\\d+\\.\\d+.\\d+ Safari/",
  461.                     family_replacement: "WebKit Nightly"
  462.                 }, {
  463.                     regex: "(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari/",
  464.                     family_replacement: "Safari"
  465.                 }, {
  466.                     regex: "(Safari)/\\d+"
  467.                 }, {
  468.                     regex: "(OLPC)/Update(\\d+)\\.(\\d+)",
  469.                     other: true
  470.                 }, {
  471.                     regex: "(OLPC)/Update()\\.(\\d+)",
  472.                     v1_replacement: "0",
  473.                     other: true
  474.                 }, {
  475.                     regex: "(SEMC\\-Browser)/(\\d+)\\.(\\d+)",
  476.                     other: true
  477.                 }, {
  478.                     regex: "(Teleca)",
  479.                     family_replacement: "Teleca Browser",
  480.                     other: true
  481.                 }, {
  482.                     regex: "(MSIE) (\\d+)\\.(\\d+)",
  483.                     family_replacement: "IE"
  484.                 }],
  485.             os_parsers: [{
  486.                     regex: "(Android) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"
  487.                 }, {
  488.                     regex: "(Android)\\-(\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"
  489.                 }, {
  490.                     regex: "(Android) Donut",
  491.                     os_v2_replacement: "2",
  492.                     os_v1_replacement: "1"
  493.                 }, {
  494.                     regex: "(Android) Eclair",
  495.                     os_v2_replacement: "1",
  496.                     os_v1_replacement: "2"
  497.                 }, {
  498.                     regex: "(Android) Froyo",
  499.                     os_v2_replacement: "2",
  500.                     os_v1_replacement: "2"
  501.                 }, {
  502.                     regex: "(Android) Gingerbread",
  503.                     os_v2_replacement: "3",
  504.                     os_v1_replacement: "2"
  505.                 }, {
  506.                     regex: "(Android) Honeycomb",
  507.                     os_v1_replacement: "3"
  508.                 }, {
  509.                     regex: "(Silk-Accelerated=[a-z]{4,5})",
  510.                     os_replacement: "Android"
  511.                 }, {
  512.                     regex: "(Windows Phone 6\\.5)"
  513.                 }, {
  514.                     regex: "(Windows (?:NT 5\\.2|NT 5\\.1))",
  515.                     os_replacement: "Windows XP"
  516.                 }, {
  517.                     regex: "(XBLWP7)",
  518.                     os_replacement: "Windows Phone OS"
  519.                 }, {
  520.                     regex: "(Windows NT 6\\.1)",
  521.                     os_replacement: "Windows 7"
  522.                 }, {
  523.                     regex: "(Windows NT 6\\.0)",
  524.                     os_replacement: "Windows Vista"
  525.                 }, {
  526.                     regex: "(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\\.0|Windows Vista|Windows 2000)"
  527.                 }, {
  528.                     regex: "(Windows NT 6\\.2)",
  529.                     os_replacement: "Windows 8"
  530.                 }, {
  531.                     regex: "(Windows Phone 8)",
  532.                     os_replacement: "Windows Phone 8"
  533.                 }, {
  534.                     regex: "(Windows NT 5\\.0)",
  535.                     os_replacement: "Windows 2000"
  536.                 }, {
  537.                     regex: "(Windows Phone OS) (\\d+)\\.(\\d+)"
  538.                 }, {
  539.                     regex: "(Windows ?Mobile)",
  540.                     os_replacement: "Windows Mobile"
  541.                 }, {
  542.                     regex: "(WinNT4.0)",
  543.                     os_replacement: "Windows NT 4.0"
  544.                 }, {
  545.                     regex: "(Win98)",
  546.                     os_replacement: "Windows 98"
  547.                 }, {
  548.                     regex: "(Tizen)/(\\d+)\\.(\\d+)",
  549.                     other: true
  550.                 }, {
  551.                     regex: "(Mac OS X) (\\d+)[_.](\\d+)(?:[_.](\\d+))?",
  552.                     manufacturer: "Apple"
  553.                 }, {
  554.                     regex: "(?:PPC|Intel) (Mac OS X)",
  555.                     manufacturer: "Apple"
  556.                 }, {
  557.                     regex: "(CPU OS|iPhone OS) (\\d+)_(\\d+)(?:_(\\d+))?",
  558.                     os_replacement: "iOS",
  559.                     manufacturer: "Apple"
  560.                 }, {
  561.                     regex: "(iPhone|iPad|iPod); Opera",
  562.                     os_replacement: "iOS",
  563.                     manufacturer: "Apple"
  564.                 }, {
  565.                     regex: "(iPad); Opera",
  566.                     tablet: true,
  567.                     manufacturer: "Apple"
  568.                 }, {
  569.                     regex: "(iPhone|iPad|iPod).*Mac OS X.*Version/(\\d+)\\.(\\d+)",
  570.                     os_replacement: "iOS",
  571.                     manufacturer: "Apple"
  572.                 }, {
  573.                     regex: "(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  574.                     os_replacement: "Chrome OS"
  575.                 }, {
  576.                     regex: "(Debian)-(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  577.                     other: true
  578.                 }, {
  579.                     regex: "(Linux Mint)(?:/(\\d+))?",
  580.                     other: true
  581.                 }, {
  582.                     regex: "(Mandriva)(?: Linux)?/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  583.                     other: true
  584.                 }, {
  585.                     regex: "(Symbian[Oo][Ss])/(\\d+)\\.(\\d+)",
  586.                     os_replacement: "Symbian OS"
  587.                 }, {
  588.                     regex: "(Symbian/3).+NokiaBrowser/7\\.3",
  589.                     os_replacement: "Symbian^3 Anna"
  590.                 }, {
  591.                     regex: "(Symbian/3).+NokiaBrowser/7\\.4",
  592.                     os_replacement: "Symbian^3 Belle"
  593.                 }, {
  594.                     regex: "(Symbian/3)",
  595.                     os_replacement: "Symbian^3"
  596.                 }, {
  597.                     regex: "(Series 60|SymbOS|S60)",
  598.                     os_replacement: "Symbian OS"
  599.                 }, {
  600.                     regex: "(MeeGo)",
  601.                     other: true
  602.                 }, {
  603.                     regex: "Symbian [Oo][Ss]",
  604.                     os_replacement: "Symbian OS"
  605.                 }, {
  606.                     regex: "(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  607.                     os_replacement: "BlackBerry OS",
  608.                     manufacturer: "RIM"
  609.                 }, {
  610.                     regex: "(Black[Bb]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  611.                     os_replacement: "BlackBerry OS",
  612.                     manufacturer: "RIM"
  613.                 }, {
  614.                     regex: "(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)",
  615.                     os_replacement: "BlackBerry Tablet OS",
  616.                     tablet: true,
  617.                     manufacturer: "RIM"
  618.                 }, {
  619.                     regex: "(Play[Bb]ook)",
  620.                     os_replacement: "BlackBerry Tablet OS",
  621.                     tablet: true,
  622.                     manufacturer: "RIM"
  623.                 }, {
  624.                     regex: "(Black[Bb]erry)",
  625.                     os_replacement: "Blackberry OS",
  626.                     manufacturer: "RIM"
  627.                 }, {
  628.                     regex: "(webOS|hpwOS)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  629.                     os_replacement: "webOS"
  630.                 }, {
  631.                     regex: "(SUSE|Fedora|Red Hat|PCLinuxOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
  632.                     other: true
  633.                 }, {
  634.                     regex: "(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\\d+)\\.(\\d+)\\.(\\d+)",
  635.                     other: true
  636.                 }, {
  637.                     regex: "(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\\d+)\\.(\\d+)"
  638.                 }, {
  639.                     regex: "(Windows|OpenBSD|FreeBSD|NetBSD|Ubuntu|Kubuntu|Android|Arch Linux|CentOS|WeTab|Slackware)"
  640.                 }, {
  641.                     regex: "(Linux|BSD)",
  642.                     other: true
  643.                 }],
  644.             mobile_os_families: ["Windows Phone 6.5", "Windows CE", "Symbian OS"],
  645.             device_parsers: [{
  646.                     regex: "HTC ([A-Z][a-z0-9]+) Build",
  647.                     device_replacement: "HTC $1",
  648.                     manufacturer: "HTC"
  649.                 }, {
  650.                     regex: "HTC ([A-Z][a-z0-9 ]+) \\d+\\.\\d+\\.\\d+\\.\\d+",
  651.                     device_replacement: "HTC $1",
  652.                     manufacturer: "HTC"
  653.                 }, {
  654.                     regex: "HTC_Touch_([A-Za-z0-9]+)",
  655.                     device_replacement: "HTC Touch ($1)",
  656.                     manufacturer: "HTC"
  657.                 }, {
  658.                     regex: "USCCHTC(\\d+)",
  659.                     device_replacement: "HTC $1 (US Cellular)",
  660.                     manufacturer: "HTC"
  661.                 }, {
  662.                     regex: "Sprint APA(9292)",
  663.                     device_replacement: "HTC $1 (Sprint)",
  664.                     manufacturer: "HTC"
  665.                 }, {
  666.                     regex: "HTC ([A-Za-z0-9]+ [A-Z])",
  667.                     device_replacement: "HTC $1",
  668.                     manufacturer: "HTC"
  669.                 }, {
  670.                     regex: "HTC-([A-Za-z0-9]+)",
  671.                     device_replacement: "HTC $1",
  672.                     manufacturer: "HTC"
  673.                 }, {
  674.                     regex: "HTC_([A-Za-z0-9]+)",
  675.                     device_replacement: "HTC $1",
  676.                     manufacturer: "HTC"
  677.                 }, {
  678.                     regex: "HTC ([A-Za-z0-9]+)",
  679.                     device_replacement: "HTC $1",
  680.                     manufacturer: "HTC"
  681.                 }, {
  682.                     regex: "(ADR[A-Za-z0-9]+)",
  683.                     device_replacement: "HTC $1",
  684.                     manufacturer: "HTC"
  685.                 }, {
  686.                     regex: "(HTC)",
  687.                     manufacturer: "HTC"
  688.                 }, {
  689.                     regex: "SonyEricsson([A-Za-z0-9]+)/",
  690.                     device_replacement: "Ericsson $1",
  691.                     other: true,
  692.                     manufacturer: "Sony"
  693.                 }, {
  694.                     regex: "Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; WOWMobile (.+) Build"
  695.                 }, {
  696.                     regex: "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"
  697.                 }, {
  698.                     regex: "Android[\\- ][\\d]+\\.[\\d]+\\-update1\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"
  699.                 }, {
  700.                     regex: "Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"
  701.                 }, {
  702.                     regex: "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; (.+) Build"
  703.                 }, {
  704.                     regex: "NokiaN([0-9]+)",
  705.                     device_replacement: "Nokia N$1",
  706.                     manufacturer: "Nokia"
  707.                 }, {
  708.                     regex: "Nokia([A-Za-z0-9\\v-]+)",
  709.                     device_replacement: "Nokia $1",
  710.                     manufacturer: "Nokia"
  711.                 }, {
  712.                     regex: "NOKIA ([A-Za-z0-9\\-]+)",
  713.                     device_replacement: "Nokia $1",
  714.                     manufacturer: "Nokia"
  715.                 }, {
  716.                     regex: "Nokia ([A-Za-z0-9\\-]+)",
  717.                     device_replacement: "Nokia $1",
  718.                     manufacturer: "Nokia"
  719.                 }, {
  720.                     regex: "Lumia ([A-Za-z0-9\\-]+)",
  721.                     device_replacement: "Lumia $1",
  722.                     manufacturer: "Nokia"
  723.                 }, {
  724.                     regex: "Symbian",
  725.                     device_replacement: "Nokia",
  726.                     manufacturer: "Nokia"
  727.                 }, {
  728.                     regex: "(PlayBook).+RIM Tablet OS",
  729.                     device_replacement: "Blackberry Playbook",
  730.                     tablet: true,
  731.                     manufacturer: "RIM"
  732.                 }, {
  733.                     regex: "(Black[Bb]erry [0-9]+);",
  734.                     manufacturer: "RIM"
  735.                 }, {
  736.                     regex: "Black[Bb]erry([0-9]+)",
  737.                     device_replacement: "BlackBerry $1",
  738.                     manufacturer: "RIM"
  739.                 }, {
  740.                     regex: "(Pre)/(\\d+)\\.(\\d+)",
  741.                     device_replacement: "Palm Pre",
  742.                     manufacturer: "Palm"
  743.                 }, {
  744.                     regex: "(Pixi)/(\\d+)\\.(\\d+)",
  745.                     device_replacement: "Palm Pixi",
  746.                     manufacturer: "Palm"
  747.                 }, {
  748.                     regex: "(Touchpad)/(\\d+)\\.(\\d+)",
  749.                     device_replacement: "HP Touchpad",
  750.                     manufacturer: "HP"
  751.                 }, {
  752.                     regex: "HPiPAQ([A-Za-z0-9]+)/(\\d+).(\\d+)",
  753.                     device_replacement: "HP iPAQ $1",
  754.                     manufacturer: "HP"
  755.                 }, {
  756.                     regex: "Palm([A-Za-z0-9]+)",
  757.                     device_replacement: "Palm $1",
  758.                     manufacturer: "Palm"
  759.                 }, {
  760.                     regex: "Treo([A-Za-z0-9]+)",
  761.                     device_replacement: "Palm Treo $1",
  762.                     manufacturer: "Palm"
  763.                 }, {
  764.                     regex: "webOS.*(P160UNA)/(\\d+).(\\d+)",
  765.                     device_replacement: "HP Veer",
  766.                     manufacturer: "HP"
  767.                 }, {
  768.                     regex: "(Kindle Fire)",
  769.                     manufacturer: "Amazon"
  770.                 }, {
  771.                     regex: "(Kindle)",
  772.                     manufacturer: "Amazon"
  773.                 }, {
  774.                     regex: "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?",
  775.                     device_replacement: "Kindle Fire",
  776.                     tablet: true,
  777.                     manufacturer: "Amazon"
  778.                 }, {
  779.                     regex: "(iPad) Simulator;",
  780.                     manufacturer: "Apple"
  781.                 }, {
  782.                     regex: "(iPad);",
  783.                     manufacturer: "Apple"
  784.                 }, {
  785.                     regex: "(iPod);",
  786.                     manufacturer: "Apple"
  787.                 }, {
  788.                     regex: "(iPhone) Simulator;",
  789.                     manufacturer: "Apple"
  790.                 }, {
  791.                     regex: "(iPhone);",
  792.                     manufacturer: "Apple"
  793.                 }, {
  794.                     regex: "Nexus\\ ([A-Za-z0-9\\-]+)",
  795.                     device_replacement: "Nexus $1"
  796.                 }, {
  797.                     regex: "acer_([A-Za-z0-9]+)_",
  798.                     device_replacement: "Acer $1",
  799.                     manufacturer: "Acer"
  800.                 }, {
  801.                     regex: "acer_([A-Za-z0-9]+)_",
  802.                     device_replacement: "Acer $1",
  803.                     manufacturer: "Acer"
  804.                 }, {
  805.                     regex: "Amoi\\-([A-Za-z0-9]+)",
  806.                     device_replacement: "Amoi $1",
  807.                     other: true,
  808.                     manufacturer: "Amoi"
  809.                 }, {
  810.                     regex: "AMOI\\-([A-Za-z0-9]+)",
  811.                     device_replacement: "Amoi $1",
  812.                     other: true,
  813.                     manufacturer: "Amoi"
  814.                 }, {
  815.                     regex: "Asus\\-([A-Za-z0-9]+)",
  816.                     device_replacement: "Asus $1",
  817.                     manufacturer: "Asus"
  818.                 }, {
  819.                     regex: "ASUS\\-([A-Za-z0-9]+)",
  820.                     device_replacement: "Asus $1",
  821.                     manufacturer: "Asus"
  822.                 }, {
  823.                     regex: "BIRD\\-([A-Za-z0-9]+)",
  824.                     device_replacement: "Bird $1",
  825.                     other: true
  826.                 }, {
  827.                     regex: "BIRD\\.([A-Za-z0-9]+)",
  828.                     device_replacement: "Bird $1",
  829.                     other: true
  830.                 }, {
  831.                     regex: "BIRD ([A-Za-z0-9]+)",
  832.                     device_replacement: "Bird $1",
  833.                     other: true
  834.                 }, {
  835.                     regex: "Dell ([A-Za-z0-9]+)",
  836.                     device_replacement: "Dell $1",
  837.                     manufacturer: "Dell"
  838.                 }, {
  839.                     regex: "DoCoMo/2\\.0 ([A-Za-z0-9]+)",
  840.                     device_replacement: "DoCoMo $1",
  841.                     other: true
  842.                 }, {
  843.                     regex: "([A-Za-z0-9]+)\\_W\\;FOMA",
  844.                     device_replacement: "DoCoMo $1",
  845.                     other: true
  846.                 }, {
  847.                     regex: "([A-Za-z0-9]+)\\;FOMA",
  848.                     device_replacement: "DoCoMo $1",
  849.                     other: true
  850.                 }, {
  851.                     regex: "vodafone([A-Za-z0-9]+)",
  852.                     device_replacement: "Huawei Vodafone $1",
  853.                     other: true
  854.                 }, {
  855.                     regex: "i\\-mate ([A-Za-z0-9]+)",
  856.                     device_replacement: "i-mate $1",
  857.                     other: true
  858.                 }, {
  859.                     regex: "Kyocera\\-([A-Za-z0-9]+)",
  860.                     device_replacement: "Kyocera $1",
  861.                     other: true
  862.                 }, {
  863.                     regex: "KWC\\-([A-Za-z0-9]+)",
  864.                     device_replacement: "Kyocera $1",
  865.                     other: true
  866.                 }, {
  867.                     regex: "Lenovo\\-([A-Za-z0-9]+)",
  868.                     device_replacement: "Lenovo $1",
  869.                     manufacturer: "Lenovo"
  870.                 }, {
  871.                     regex: "Lenovo\\_([A-Za-z0-9]+)",
  872.                     device_replacement: "Lenovo $1",
  873.                     manufacturer: "Levovo"
  874.                 }, {
  875.                     regex: "LG/([A-Za-z0-9]+)",
  876.                     device_replacement: "LG $1",
  877.                     manufacturer: "LG"
  878.                 }, {
  879.                     regex: "LG-LG([A-Za-z0-9]+)",
  880.                     device_replacement: "LG $1",
  881.                     manufacturer: "LG"
  882.                 }, {
  883.                     regex: "LGE-LG([A-Za-z0-9]+)",
  884.                     device_replacement: "LG $1",
  885.                     manufacturer: "LG"
  886.                 }, {
  887.                     regex: "LGE VX([A-Za-z0-9]+)",
  888.                     device_replacement: "LG $1",
  889.                     manufacturer: "LG"
  890.                 }, {
  891.                     regex: "LG ([A-Za-z0-9]+)",
  892.                     device_replacement: "LG $1",
  893.                     manufacturer: "LG"
  894.                 }, {
  895.                     regex: "LGE LG\\-AX([A-Za-z0-9]+)",
  896.                     device_replacement: "LG $1",
  897.                     manufacturer: "LG"
  898.                 }, {
  899.                     regex: "LG\\-([A-Za-z0-9]+)",
  900.                     device_replacement: "LG $1",
  901.                     manufacturer: "LG"
  902.                 }, {
  903.                     regex: "LGE\\-([A-Za-z0-9]+)",
  904.                     device_replacement: "LG $1",
  905.                     manufacturer: "LG"
  906.                 }, {
  907.                     regex: "LG([A-Za-z0-9]+)",
  908.                     device_replacement: "LG $1",
  909.                     manufacturer: "LG"
  910.                 }, {
  911.                     regex: "(KIN)\\.One (\\d+)\\.(\\d+)",
  912.                     device_replacement: "Microsoft $1"
  913.                 }, {
  914.                     regex: "(KIN)\\.Two (\\d+)\\.(\\d+)",
  915.                     device_replacement: "Microsoft $1"
  916.                 }, {
  917.                     regex: "(Motorola)\\-([A-Za-z0-9]+)",
  918.                     manufacturer: "Motorola"
  919.                 }, {
  920.                     regex: "MOTO\\-([A-Za-z0-9]+)",
  921.                     device_replacement: "Motorola $1",
  922.                     manufacturer: "Motorola"
  923.                 }, {
  924.                     regex: "MOT\\-([A-Za-z0-9]+)",
  925.                     device_replacement: "Motorola $1",
  926.                     manufacturer: "Motorola"
  927.                 }, {
  928.                     regex: "Philips([A-Za-z0-9]+)",
  929.                     device_replacement: "Philips $1",
  930.                     manufacturer: "Philips"
  931.                 }, {
  932.                     regex: "Philips ([A-Za-z0-9]+)",
  933.                     device_replacement: "Philips $1",
  934.                     manufacturer: "Philips"
  935.                 }, {
  936.                     regex: "SAMSUNG-([A-Za-z0-9\\-]+)",
  937.                     device_replacement: "Samsung $1",
  938.                     manufacturer: "Samsung"
  939.                 }, {
  940.                     regex: "SAMSUNG\\; ([A-Za-z0-9\\-]+)",
  941.                     device_replacement: "Samsung $1",
  942.                     manufacturer: "Samsung"
  943.                 }, {
  944.                     regex: "Softbank/1\\.0/([A-Za-z0-9]+)",
  945.                     device_replacement: "Softbank $1",
  946.                     other: true
  947.                 }, {
  948.                     regex: "Softbank/2\\.0/([A-Za-z0-9]+)",
  949.                     device_replacement: "Softbank $1",
  950.                     other: true
  951.                 }, {
  952.                     regex: "(hiptop|avantgo|plucker|xiino|blazer|elaine|up.browser|up.link|mmp|smartphone|midp|wap|vodafone|o2|pocket|mobile|pda)",
  953.                     device_replacement: "Generic Smartphone"
  954.                 }, {
  955.                     regex: "^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\\-|airn|alav|asus|attw|au\\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw\\-n|bw\\-u|beck|benq|bilb|blac|c55/|cdm\\-|chtm|capi|comp|cond|craw|dall|dbte|dc\\-s|dica|ds\\-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\\-|fly\\_|g\\-mo|g1 u|g560|gf\\-5|grun|gene|go.w|good|grad|hcit|hd\\-m|hd\\-p|hd\\-t|hei\\-|hp i|hpip|hs\\-c|htc |htc\\-|htca|htcg)",
  956.                     device_replacement: "Generic Feature Phone"
  957.                 }, {
  958.                     regex: "^(htcp|htcs|htct|htc\\_|haie|hita|huaw|hutc|i\\-20|i\\-go|i\\-ma|i230|iac|iac\\-|iac/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt/|kpt |kwc\\-|klon|lexi|lg g|lg\\-a|lg\\-b|lg\\-c|lg\\-d|lg\\-f|lg\\-g|lg\\-k|lg\\-l|lg\\-m|lg\\-o|lg\\-p|lg\\-s|lg\\-t|lg\\-u|lg\\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\\-|lge/|lynx|leno|m1\\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\\-|nem\\-|newg|neon)",
  959.                     device_replacement: "Generic Feature Phone"
  960.                 }, {
  961.                     regex: "^(netf|noki|nzph|o2 x|o2\\-x|opwv|owg1|opti|oran|ot\\-s|p800|pand|pg\\-1|pg\\-2|pg\\-3|pg\\-6|pg\\-8|pg\\-c|pg13|phil|pn\\-2|pt\\-g|palm|pana|pire|pock|pose|psio|qa\\-a|qc\\-2|qc\\-3|qc\\-5|qc\\-7|qc07|qc12|qc21|qc32|qc60|qci\\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\\-|scp\\-|sdk/|se47|sec\\-|sec0|sec1|semc|sgh\\-|shar|sie\\-|sk\\-0|sl45|slid|smb3|smt5|sp01|sph\\-|spv |spv\\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\\-mo|t218|t250|t600|t610|t618|tcl\\-|tdg\\-|telm|tim\\-|ts70|tsm\\-|tsm3|tsm5|tx\\-9|tagt)",
  962.                     device_replacement: "Generic Feature Phone"
  963.                 }, {
  964.                     regex: "^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c |w3c\\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\\-|your|zte\\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\\-|webc|whit|wmlb|xda\\-|xda\\_)",
  965.                     device_replacement: "Generic Feature Phone"
  966.                 }, {
  967.                     regex: "(bot|borg|google(^tv)|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast\\-webcrawler|converacrawler|dataparksearch|findlinks)",
  968.                     device_replacement: "Spider"
  969.                 }],
  970.             mobile_browser_families: ["Firefox Mobile", "Opera Mobile", "Opera Mini", "Mobile Safari", "webOS", "IE Mobile", "Playstation Portable", "Nokia", "Blackberry", "Palm", "Silk", "Android", "Maemo", "Obigo", "Netfront", "AvantGo", "Teleca", "SEMC-Browser", "Bolt", "Iris", "UP.Browser", "Symphony", "Minimo", "Bunjaloo", "Jasmine", "Dolfin", "Polaris", "BREW", "Chrome Mobile", "Chrome Mobile iOS", "UC Browser", "Tizen Browser"]
  971.         };
  972.         // Parsers
  973.         _this.parsers = ["device_parsers", "browser_parsers", "os_parsers", "mobile_os_families", "mobile_browser_families"];
  974.         // Types
  975.         _this.types = ["browser", "os", "device"];
  976.         // Regular Expressions
  977.         _this.regexes = regexes || function () {
  978.             var results = {};
  979.             _this.parsers.map(function (parser) {
  980.                 results[parser] = [];
  981.             });
  982.             return results;
  983.         }();
  984.         // Families
  985.         _this.families = function () {
  986.             var results = {};
  987.             _this.types.map(function (type) {
  988.                 results[type] = [];
  989.             });
  990.             return results;
  991.         }();
  992.         // Utility Variables
  993.         var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype, nativeForEach = ArrayProto.forEach, nativeIndexOf = ArrayProto.indexOf;
  994.         // Find Utility
  995.         var find = function (ua, obj) {
  996.             var ret = {};
  997.             for (var i = 0; i < obj.length; i++) {
  998.                 ret = obj[i](ua);
  999.                 if (ret) {
  1000.                     break;
  1001.                 }
  1002.             }
  1003.             return ret;
  1004.         };
  1005.         // Remove Utility
  1006.         var remove = function (arr, props) {
  1007.             each(arr, function (obj) {
  1008.                 each(props, function (prop) {
  1009.                     delete obj[prop];
  1010.                 });
  1011.             });
  1012.         };
  1013.         // Contains Utility
  1014.         var contains = function (obj, target) {
  1015.             var found = false;
  1016.             if (obj == null)
  1017.                 return found;
  1018.             if (nativeIndexOf && obj.indexOf === nativeIndexOf)
  1019.                 return obj.indexOf(target) != -1;
  1020.             found = any(obj, function (value) {
  1021.                 return value === target;
  1022.             });
  1023.             return found;
  1024.         };
  1025.         // Each Utility
  1026.         var each = forEach = function (obj, iterator, context) {
  1027.             if (obj == null)
  1028.                 return;
  1029.             if (nativeForEach && obj.forEach === nativeForEach) {
  1030.                 obj.forEach(iterator, context);
  1031.             } else if (obj.length === +obj.length) {
  1032.                 for (var i = 0, l = obj.length; i < l; i++) {
  1033.                     iterator.call(context, obj[i], i, obj);
  1034.                 }
  1035.             } else {
  1036.                 for (var key in obj) {
  1037.                     if (_.has(obj, key)) {
  1038.                         iterator.call(context, obj[key], key, obj);
  1039.                     }
  1040.                 }
  1041.             }
  1042.         };
  1043.         // Extend Utiltiy
  1044.         var extend = function (obj) {
  1045.             each(slice.call(arguments, 1), function (source) {
  1046.                 for (var prop in source) {
  1047.                     obj[prop] = source[prop];
  1048.                 }
  1049.             });
  1050.             return obj;
  1051.         };
  1052.         // Check String Utility
  1053.         var check = function (str) {
  1054.             return !!(str && typeof str != "undefined" && str != null);
  1055.         };
  1056.         // To Version String Utility
  1057.         var toVersionString = function (obj) {
  1058.             var output = "";
  1059.             obj = obj || {};
  1060.             if (check(obj)) {
  1061.                 if (check(obj.major)) {
  1062.                     output += obj.major;
  1063.                     if (check(obj.minor)) {
  1064.                         output += "." + obj.minor;
  1065.                         if (check(obj.patch)) {
  1066.                             output += "." + obj.patch;
  1067.                         }
  1068.                     }
  1069.                 }
  1070.             }
  1071.             return output;
  1072.         };
  1073.         // To String Utility
  1074.         var toString = function (obj) {
  1075.             obj = obj || {};
  1076.             var suffix = toVersionString(obj);
  1077.             if (suffix)
  1078.                 suffix = " " + suffix;
  1079.             return obj && check(obj.family) ? obj.family + suffix : "";
  1080.         };
  1081.         // Parse User-Agent String
  1082.         _this.parse = function (ua) {
  1083.             // Parsers Utility
  1084.             var parsers = function (type) {
  1085.                 return _this.regexes[type + "_parsers"].map(function (obj) {
  1086.                     var regexp = new RegExp(obj.regex), rep = obj[(type === "browser" ? "family" : type) + "_replacement"], major_rep = obj.major_version_replacement;
  1087.                     function parser(ua) {
  1088.                         var m = ua.match(regexp);
  1089.                         if (!m)
  1090.                             return null;
  1091.                         var ret = {};
  1092.                         ret.family = (rep ? rep.replace("$1", m[1]) : m[1]) || "other";
  1093.                         ret.major = parseInt(major_rep ? major_rep : m[2]) || null;
  1094.                         ret.minor = m[3] ? parseInt(m[3]) : null;
  1095.                         ret.patch = m[4] ? parseInt(m[4]) : null;
  1096.                         ret.tablet = obj.tablet;
  1097.                         ret.man = obj.manufacturer || null;
  1098.                         return ret;
  1099.                     }
  1100.                     return parser;
  1101.                 });
  1102.             };
  1103.             // User Agent
  1104.             var UserAgent = function () {
  1105.             };
  1106.             // Browsers Parsed
  1107.             var browser_parsers = parsers("browser");
  1108.             // Operating Systems Parsed
  1109.             var os_parsers = parsers("os");
  1110.             // Devices Parsed
  1111.             var device_parsers = parsers("device");
  1112.             // Set Agent
  1113.             var a = new UserAgent();
  1114.             // Remember the original user agent string
  1115.             a.source = ua;
  1116.             // Set Browser
  1117.             a.browser = find(ua, browser_parsers);
  1118.             if (check(a.browser)) {
  1119.                 a.browser.name = toString(a.browser);
  1120.                 a.browser.version = toVersionString(a.browser);
  1121.             } else {
  1122.                 a.browser = {};
  1123.             }
  1124.             // Set OS
  1125.             a.os = find(ua, os_parsers);
  1126.             if (check(a.os)) {
  1127.                 a.os.name = toString(a.os);
  1128.                 a.os.version = toVersionString(a.os);
  1129.             } else {
  1130.                 a.os = {};
  1131.             }
  1132.             // Set Device
  1133.             a.device = find(ua, device_parsers);
  1134.             if (check(a.device)) {
  1135.                 a.device.name = toString(a.device);
  1136.                 a.device.version = toVersionString(a.device);
  1137.             } else {
  1138.                 a.device = {
  1139.                     tablet: false,
  1140.                     family: "Other"
  1141.                 };
  1142.             }
  1143.             // Determine Device Type
  1144.             var mobile_agents = {};
  1145.             var mobile_browser_families = _this.regexes.mobile_browser_families.map(function (str) {
  1146.                 mobile_agents[str] = true;
  1147.             });
  1148.             var mobile_os_families = _this.regexes.mobile_os_families.map(function (str) {
  1149.                 mobile_agents[str] = true;
  1150.             });
  1151.             // Is Spider
  1152.             if (a.browser.family === "Spider") {
  1153.                 a.device.type = "Spider";
  1154.             } else if (a.browser.tablet || a.os.tablet || a.device.tablet) {
  1155.                 a.device.type = "Tablet";
  1156.             } else if (mobile_agents.hasOwnProperty(a.browser.family)) {
  1157.                 a.device.type = "Mobile";
  1158.             } else {
  1159.                 a.device.type = "Desktop";
  1160.             }
  1161.             // Determine Device Manufacturer
  1162.             a.device.manufacturer = a.browser.man || a.os.man || a.device.man || null;
  1163.             // Cleanup Objects
  1164.             remove([a.browser, a.os, a.device], ["tablet", "man"]);
  1165.             // Return Agent
  1166.             return a;
  1167.         };
  1168.         // Return context
  1169.         return _this;
  1170.     }();
  1171.     // Export the Underscore object for **Node.js** and **"CommonJS"**,
  1172.     // backwards-compatibility for the old `require()` API. If we're not
  1173.     // CommonJS, add `_` to the global object via a string identifier
  1174.     // the Closure Compiler "advanced" mode. Registration as an AMD
  1175.     // via define() happens at the end of this file
  1176.     if (typeof exports !== "undefined") {
  1177.         if (typeof module !== "undefined" && module.exports) {
  1178.             exports = module.exports = detect;
  1179.         }
  1180.         exports.detect = detect;
  1181.     } else {
  1182.         root["detect"] = detect;
  1183.     }
  1184.     // AMD define happens at the end for compatibility with AMD
  1185.     // that don't enforce next-turn semantics on modules
  1186.     if (typeof define === "function" && define.amd) {
  1187.         define(function (require) {
  1188.             return detect;
  1189.         });
  1190.     }
  1191. })(_dfMc);

Raw Paste


Login or Register to edit or fork this paste. It's free.