From e5341b11589bdb686d9988cd73280fbb35e4d4bf Mon Sep 17 00:00:00 2001 From: Sam Brown Date: Thu, 9 Sep 2021 16:25:46 -0700 Subject: [PATCH 1/4] Configurable remote, update tests. --- bin/update.js | 2 +- index.js | 28 +- lib/regexps.js | 3906 +++++++++++++++++++++++++------------------ lib/update.js | 61 +- test/parser.test.js | 4 +- 5 files changed, 2302 insertions(+), 1699 deletions(-) diff --git a/bin/update.js b/bin/update.js index 28c2501..e5ae941 100755 --- a/bin/update.js +++ b/bin/update.js @@ -5,7 +5,7 @@ /** * Update our definition file. */ -require('../lib/update').update(function updating(err, data) { +require('../lib/update').update(undefined, function updating(err, data) { if (err) { console.error('Update unsuccessfull due to reasons'); console.log(err.message); diff --git a/index.js b/index.js index 344259b..bfe8919 100644 --- a/index.js +++ b/index.js @@ -356,16 +356,16 @@ Device.prototype.toJSON = function toJSON() { }; /** - * Small nifty thick that allows us to download a fresh set regexs from t3h - * Int3rNetz when we want to. We will be using the compiled version by default - * but users can opt-in for updates. + * Small nifty thick that allows us to download a fresh set regexs from a remote + * source. Package uses the compiled version by default, but allow for updating from + * the default source (no args) or a custom source, via the `remote` parameter. * - * @param {Boolean} refresh Refresh the dataset from the remote + * @param {String} remote optionally specify a custom URL for regex sourcing * @api public */ -module.exports = function updater() { +module.exports = function updater(remote) { try { - require('./lib/update').update(function updating(err, results) { + require('./lib/update').update(remote, function updating(err, results) { if (err) { console.log('[useragent] Failed to update the parsed due to an error:'); console.log('[useragent] '+ (err.message ? err.message : err)); @@ -415,15 +415,10 @@ function isSafe(userAgent) { var consecutive = 0 , code = 0; - if (userAgent.length > 1000) return false; - for (var i = 0; i < userAgent.length; i++) { code = userAgent.charCodeAt(i); - if ((code >= 48 && code <= 57) || // numbers - (code >= 65 && code <= 90) || // letters A-Z - (code >= 97 && code <= 122) || // letters a-z - code <= 32 // spaces and control - ) { + // numbers between 0 and 9, letters between a and z + if ((code >= 48 && code <= 57) || (code >= 97 && code <= 122)) { consecutive++; } else { consecutive = 0; @@ -448,10 +443,6 @@ function isSafe(userAgent) { * @api public */ exports.parse = function parse(userAgent, jsAgent) { - if (userAgent && userAgent.length > 1000) { - userAgent = userAgent.substring(0, 1000); - } - if (!userAgent || !isSafe(userAgent)) return new Agent(); var length = agentparserslength @@ -515,8 +506,7 @@ exports.parse = function parse(userAgent, jsAgent) { * @param {String} jsAgent Optional UA from js to detect chrome frame * @api public */ -var lruCache = require('lru-cache'); -var LRU = new lruCache(5000); +var LRU = require('lru-cache')(5000); exports.lookup = function lookup(userAgent, jsAgent) { var key = (userAgent || '')+(jsAgent || '') , cached = LRU.get(key); diff --git a/lib/regexps.js b/lib/regexps.js index a4cd10d..8c5a576 100644 --- a/lib/regexps.js +++ b/lib/regexps.js @@ -30,2037 +30,2373 @@ parser[3] = 0; parser[4] = 0; exports.browser[0] = parser; parser = Object.create(null); -parser[0] = new RegExp("(ESPN)[%20| ]+Radio/(\\d+)\\.(\\d+)\\.(\\d+) CFNetwork"); +parser[0] = new RegExp("(GeoEvent Server) (\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.browser[1] = parser; parser = Object.create(null); +parser[0] = new RegExp("(ArcGIS Pro)(?: (\\d+)\\.(\\d+)\\.([^ ]+)|)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[2] = parser; +parser = Object.create(null); +parser[0] = new RegExp("ArcGIS Client Using WinInet"); +parser[1] = "ArcMap"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[3] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(OperationsDashboard)-(?:Windows)-(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = "Operations Dashboard for ArcGIS"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[4] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(arcgisearth)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "ArcGIS Earth"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[5] = parser; +parser = Object.create(null); +parser[0] = new RegExp("com.esri.(earth).phone/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "ArcGIS Earth"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[6] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(arcgis-explorer)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = "Explorer for ArcGIS"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[7] = parser; +parser = Object.create(null); +parser[0] = new RegExp("arcgis-(collector|aurora)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = "Collector for ArcGIS"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[8] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(arcgis-workforce)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = "Workforce for ArcGIS"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[9] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Collector|Explorer|Workforce)-(?:Android|iOS)-(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "$1 for ArcGIS"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[10] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Explorer|Collector)/(\\d+) CFNetwork"); +parser[1] = "$1 for ArcGIS"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[11] = parser; +parser = Object.create(null); +parser[0] = new RegExp("ArcGISRuntime-(Android|iOS|NET|Qt)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "ArcGIS Runtime SDK for $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[12] = parser; +parser = Object.create(null); +parser[0] = new RegExp("ArcGIS\\.?(iOS|Android|NET|Qt)(?:-|\\.)(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "ArcGIS Runtime SDK for $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[13] = parser; +parser = Object.create(null); +parser[0] = new RegExp("ArcGIS\\.Runtime\\.(Qt)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "ArcGIS Runtime SDK for $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[14] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(Luminary)[Stage]+/(\\d+) CFNetwork"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[15] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(ESPN)[%20| ]+Radio/(\\d+)\\.(\\d+)\\.(\\d+) CFNetwork"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[16] = parser; +parser = Object.create(null); parser[0] = new RegExp("(Antenna)/(\\d+) CFNetwork"); parser[1] = "AntennaPod"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[2] = parser; +exports.browser[17] = parser; parser = Object.create(null); parser[0] = new RegExp("(TopPodcasts)Pro/(\\d+) CFNetwork"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[3] = parser; +exports.browser[18] = parser; parser = Object.create(null); parser[0] = new RegExp("(MusicDownloader)Lite/(\\d+)\\.(\\d+)\\.(\\d+) CFNetwork"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[4] = parser; +exports.browser[19] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(.*)-iPad\\/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork"); +parser[0] = new RegExp("^(.{0,200})-iPad\\/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[5] = parser; +exports.browser[20] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(.*)-iPhone/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork"); +parser[0] = new RegExp("^(.{0,200})-iPhone/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[6] = parser; +exports.browser[21] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(.*)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork"); +parser[0] = new RegExp("^(.{0,200})/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[7] = parser; +exports.browser[22] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(Luminary)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[23] = parser; parser = Object.create(null); parser[0] = new RegExp("(espn\\.go)"); parser[1] = "ESPN"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[8] = parser; +exports.browser[24] = parser; parser = Object.create(null); parser[0] = new RegExp("(espnradio\\.com)"); parser[1] = "ESPN"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[9] = parser; +exports.browser[25] = parser; parser = Object.create(null); parser[0] = new RegExp("ESPN APP$"); parser[1] = "ESPN"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[10] = parser; +exports.browser[26] = parser; parser = Object.create(null); parser[0] = new RegExp("(audioboom\\.com)"); parser[1] = "AudioBoom"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[11] = parser; +exports.browser[27] = parser; parser = Object.create(null); parser[0] = new RegExp(" (Rivo) RHYTHM"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[12] = parser; +exports.browser[28] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)(?:/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)"); parser[1] = "CFNetwork"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[13] = parser; +exports.browser[29] = parser; parser = Object.create(null); parser[0] = new RegExp("(Pingdom\\.com_bot_version_)(\\d+)\\.(\\d+)"); parser[1] = "PingdomBot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[14] = parser; +exports.browser[30] = parser; parser = Object.create(null); parser[0] = new RegExp("(PingdomTMS)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "PingdomBot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[15] = parser; +exports.browser[31] = parser; parser = Object.create(null); parser[0] = new RegExp(" (PTST)/(\\d+)(?:\\.(\\d+)|)$"); parser[1] = "WebPageTest.org bot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[16] = parser; +exports.browser[32] = parser; parser = Object.create(null); parser[0] = new RegExp("X11; (Datanyze); Linux"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[17] = parser; +exports.browser[33] = parser; parser = Object.create(null); parser[0] = new RegExp("(NewRelicPinger)/(\\d+)\\.(\\d+)"); parser[1] = "NewRelicPingerBot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[18] = parser; +exports.browser[34] = parser; parser = Object.create(null); parser[0] = new RegExp("(Tableau)/(\\d+)\\.(\\d+)"); parser[1] = "Tableau"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[19] = parser; +exports.browser[35] = parser; +parser = Object.create(null); +parser[0] = new RegExp("AppleWebKit/\\d{1,10}\\.\\d{1,10}.{0,200} Safari.{0,200} (CreativeCloud)/(\\d+)\\.(\\d+).(\\d+)"); +parser[1] = "Adobe CreativeCloud"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[36] = parser; parser = Object.create(null); parser[0] = new RegExp("(Salesforce)(?:.)\\/(\\d+)\\.(\\d?)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[20] = parser; +exports.browser[37] = parser; parser = Object.create(null); parser[0] = new RegExp("(\\(StatusCake\\))"); parser[1] = "StatusCakeBot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[21] = parser; +exports.browser[38] = parser; parser = Object.create(null); parser[0] = new RegExp("(facebookexternalhit)/(\\d+)\\.(\\d+)"); parser[1] = "FacebookBot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[22] = parser; +exports.browser[39] = parser; parser = Object.create(null); -parser[0] = new RegExp("Google.*/\\+/web/snippet"); +parser[0] = new RegExp("Google.{0,50}/\\+/web/snippet"); parser[1] = "GooglePlusBot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[23] = parser; +exports.browser[40] = parser; parser = Object.create(null); parser[0] = new RegExp("via ggpht\\.com GoogleImageProxy"); parser[1] = "GmailImageProxy"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[24] = parser; +exports.browser[41] = parser; parser = Object.create(null); parser[0] = new RegExp("YahooMailProxy; https://help\\.yahoo\\.com/kb/yahoo-mail-proxy-SLN28749\\.html"); parser[1] = "YahooMailProxy"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[25] = parser; +exports.browser[42] = parser; parser = Object.create(null); parser[0] = new RegExp("(Twitterbot)/(\\d+)\\.(\\d+)"); -parser[1] = "TwitterBot"; +parser[1] = "Twitterbot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[26] = parser; +exports.browser[43] = parser; parser = Object.create(null); parser[0] = new RegExp("/((?:Ant-|)Nutch|[A-z]+[Bb]ot|[A-z]+[Ss]pider|Axtaris|fetchurl|Isara|ShopSalad|Tailsweep)[ \\-](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[27] = parser; +exports.browser[44] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\b(008|Altresium|Argus|BaiduMobaider|BoardReader|DNSGroup|DataparkSearch|EDI|Goodzer|Grub|INGRID|Infohelfer|LinkedInBot|LOOQ|Nutch|PathDefender|Peew|PostPost|Steeler|Twitterbot|VSE|WebCrunch|WebZIP|Y!J-BR[A-Z]|YahooSeeker|envolk|sproose|wminer)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); +parser[0] = new RegExp("\\b(008|Altresium|Argus|BaiduMobaider|BoardReader|DNSGroup|DataparkSearch|EDI|Goodzer|Grub|INGRID|Infohelfer|LinkedInBot|LOOQ|Nutch|OgScrper|Pandora|PathDefender|Peew|PostPost|Steeler|Twitterbot|VSE|WebCrunch|WebZIP|Y!J-BR[A-Z]|YahooSeeker|envolk|sproose|wminer)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[28] = parser; +exports.browser[45] = parser; parser = Object.create(null); -parser[0] = new RegExp("(MSIE) (\\d+)\\.(\\d+)([a-z]\\d|[a-z]|);.* MSIECrawler"); +parser[0] = new RegExp("(MSIE) (\\d+)\\.(\\d+)([a-z]\\d|[a-z]|);.{0,200} MSIECrawler"); parser[1] = "MSIECrawler"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[29] = parser; +exports.browser[46] = parser; parser = Object.create(null); parser[0] = new RegExp("(DAVdroid)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[30] = parser; +exports.browser[47] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Google-HTTP-Java-Client|Apache-HttpClient|Go-http-client|scalaj-http|http%20client|Python-urllib|HttpMonitor|TLSProber|WinHTTP|JNLP|okhttp|aihttp|reqwest)(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[0] = new RegExp("(Google-HTTP-Java-Client|Apache-HttpClient|Go-http-client|scalaj-http|http%20client|Python-urllib|HttpMonitor|TLSProber|WinHTTP|JNLP|okhttp|aihttp|reqwest|axios|unirest-(?:java|python|ruby|nodejs|php|net))(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[31] = parser; +exports.browser[48] = parser; parser = Object.create(null); parser[0] = new RegExp("(Pinterest(?:bot|))/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)[;\\s(]+\\+https://www.pinterest.com/bot.html"); parser[1] = "Pinterestbot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[32] = parser; +exports.browser[49] = parser; parser = Object.create(null); -parser[0] = new RegExp("(CSimpleSpider|Cityreview Robot|CrawlDaddy|CrawlFire|Finderbots|Index crawler|Job Roboter|KiwiStatus Spider|Lijit Crawler|QuerySeekerSpider|ScollSpider|Trends Crawler|USyd-NLP-Spider|SiteCat Webbot|BotName\\/\\$BotVersion|123metaspider-Bot|1470\\.net crawler|50\\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]{1,30}-Agent|AdsBot-Google(?:-[a-z]{1,30}|)|altavista|AppEngine-Google|archive.{0,30}\\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]{1,30})(?:-[A-Za-z]{1,30}|)|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader Blog Indexer|BoardReader Favicon Fetcher|boitho.com-dc|BotSeer|BUbiNG|\\b\\w{0,30}favicon\\w{0,30}\\b|\\bYeti(?:-[a-z]{1,30}|)|Catchpoint(?: bot|)|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\\(S\\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher|)|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]{1,30}-|)Googlebot(?:-[a-zA-Z]{1,30}|)|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile|)|IconSurf|IlTrovatore(?:-Setaccio|)|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]{1,30}Bot|jbot\\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .{0,30} Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media {0,2}|)|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]{0,30}|^NING|Nutch[^/]{0,30}|Nymesis|ObjectsSearch|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\\.ru|Tiny Tiny RSS|TwitterBot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]{1,30}|WhatWeb|WIRE|WordPress|Wotbox|www\\.almaden\\.ibm\\.com|Xenu(?:.s|) Link Sleuth|Xerka [A-z]{1,30}Bot|yacy(?:bot|)|YahooSeeker|Yahoo! Slurp|Yandex\\w{1,30}|YodaoBot(?:-[A-z]{1,30}|)|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\\.ze\\.bz|ZooShot|ZyBorg)(?:[ /]v?(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)|)"); +parser[0] = new RegExp("(CSimpleSpider|Cityreview Robot|CrawlDaddy|CrawlFire|Finderbots|Index crawler|Job Roboter|KiwiStatus Spider|Lijit Crawler|QuerySeekerSpider|ScollSpider|Trends Crawler|USyd-NLP-Spider|SiteCat Webbot|BotName\\/\\$BotVersion|123metaspider-Bot|1470\\.net crawler|50\\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]{1,30}-Agent|AdsBot-Google(?:-[a-z]{1,30}|)|altavista|AppEngine-Google|archive.{0,30}\\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]{1,30})(?:-[A-Za-z]{1,30}|)|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader Blog Indexer|BoardReader Favicon Fetcher|boitho.com-dc|BotSeer|BUbiNG|\\b\\w{0,30}favicon\\w{0,30}\\b|\\bYeti(?:-[a-z]{1,30}|)|Catchpoint(?: bot|)|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\\(S\\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher|)|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]{1,30}-|)Googlebot(?:-[a-zA-Z]{1,30}|)|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile|)|IconSurf|IlTrovatore(?:-Setaccio|)|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]{1,30}Bot|jbot\\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .{0,30} Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media {0,2}|)|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]{0,30}|^NING|Nutch[^/]{0,30}|Nymesis|ObjectsSearch|OgScrper|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PHPCrawl|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\\.ru|Tiny Tiny RSS|Twitterbot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]{1,30}|WhatWeb|WIRE|WordPress|Wotbox|www\\.almaden\\.ibm\\.com|Xenu(?:.s|) Link Sleuth|Xerka [A-z]{1,30}Bot|yacy(?:bot|)|YahooSeeker|Yahoo! Slurp|Yandex\\w{1,30}|YodaoBot(?:-[A-z]{1,30}|)|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\\.ze\\.bz|ZooShot|ZyBorg|ArcGIS Hub Indexer)(?:[ /]v?(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[33] = parser; +exports.browser[50] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\b(Boto3?|JetS3t|aws-(?:cli|sdk-(?:cpp|go|java|nodejs|ruby2?))|s3fs)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[0] = new RegExp("\\b(Boto3?|JetS3t|aws-(?:cli|sdk-(?:cpp|go|java|nodejs|ruby2?|dotnet-(?:\\d{1,2}|core)))|s3fs)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[34] = parser; +exports.browser[51] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:\\/[A-Za-z0-9\\.]+|) {0,5}([A-Za-z0-9 \\-_\\!\\[\\]:]{0,50}(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]{0,50}))[/ ](\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)"); +parser[0] = new RegExp("(FME)\\/(\\d+\\.\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[35] = parser; +exports.browser[52] = parser; parser = Object.create(null); -parser[0] = new RegExp("((?:[A-Za-z][A-Za-z0-9 -]{0,50}|)[^C][^Uu][Bb]ot)\\b(?:(?:[ /]| v)(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[0] = new RegExp("(QGIS)\\/(\\d)\\.?0?(\\d{1,2})\\.?0?(\\d{1,2})"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[36] = parser; +exports.browser[53] = parser; parser = Object.create(null); -parser[0] = new RegExp("((?:[A-z0-9]{1,50}|[A-z\\-]{1,50} ?|)(?: the |)(?:[Ss][Pp][Ii][Dd][Ee][Rr]|[Ss]crape|[Cc][Rr][Aa][Ww][Ll])[A-z0-9]{0,50})(?:(?:[ /]| v)(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[0] = new RegExp("(JOSM)/(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[37] = parser; +exports.browser[54] = parser; parser = Object.create(null); -parser[0] = new RegExp("(HbbTV)/(\\d+)\\.(\\d+)\\.(\\d+) \\("); +parser[0] = new RegExp("(Tygron Platform) \\((\\d+)\\.(\\d+)\\.(\\d+(?:\\.\\d+| RC \\d+\\.\\d+))"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[38] = parser; +exports.browser[55] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Chimera|SeaMonkey|Camino|Waterfox)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*|)"); +parser[0] = new RegExp("\\[(FBAN/MessengerForiOS|FB_IAB/MESSENGER);FBAV/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)|)"); +parser[1] = "Facebook Messenger"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[56] = parser; +parser = Object.create(null); +parser[0] = new RegExp("\\[FB.{0,300};(FBAV)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); +parser[1] = "Facebook"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[57] = parser; +parser = Object.create(null); +parser[0] = new RegExp("\\[FB.{0,300};"); +parser[1] = "Facebook"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[58] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^.{0,200}?(?:\\/[A-Za-z0-9\\.]{0,50}|) {0,2}([A-Za-z0-9 \\-_\\!\\[\\]:]{0,50}(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]{0,50}))[/ ](\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[39] = parser; +exports.browser[59] = parser; parser = Object.create(null); -parser[0] = new RegExp("(SailfishBrowser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); -parser[1] = "Sailfish Browser"; +parser[0] = new RegExp("^.{0,200}?((?:[A-Za-z][A-Za-z0-9 -]{0,50}|)[^C][^Uu][Bb]ot)\\b(?:(?:[ /]| v)(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[40] = parser; +exports.browser[60] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\[(FBAN/MessengerForiOS|FB_IAB/MESSENGER);FBAV/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)"); -parser[1] = "Facebook Messenger"; +parser[0] = new RegExp("^.{0,200}?((?:[A-z0-9]{1,50}|[A-z\\-]{1,50} ?|)(?: the |)(?:[Ss][Pp][Ii][Dd][Ee][Rr]|[Ss]crape|[Cc][Rr][Aa][Ww][Ll])[A-z0-9]{0,50})(?:(?:[ /]| v)(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[41] = parser; +exports.browser[61] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\[FB.*;(FBAV)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); -parser[1] = "Facebook"; +parser[0] = new RegExp("(HbbTV)/(\\d+)\\.(\\d+)\\.(\\d+) \\("); +parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[42] = parser; +exports.browser[62] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\[FB.*;"); -parser[1] = "Facebook"; +parser[0] = new RegExp("(Chimera|SeaMonkey|Camino|Waterfox)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*|)"); +parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[43] = parser; +exports.browser[63] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\[(Pinterest)/[^\\]]+\\]"); +parser[0] = new RegExp("(SailfishBrowser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "Sailfish Browser"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[64] = parser; +parser = Object.create(null); +parser[0] = new RegExp("\\[(Pinterest)/[^\\]]{1,50}\\]"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[44] = parser; +exports.browser[65] = parser; parser = Object.create(null); parser[0] = new RegExp("(Pinterest)(?: for Android(?: Tablet|)|)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[45] = parser; +exports.browser[66] = parser; parser = Object.create(null); -parser[0] = new RegExp("Mozilla.*Mobile.*(Instagram).(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("Mozilla.{1,200}Mobile.{1,100}(Instagram).(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[46] = parser; +exports.browser[67] = parser; parser = Object.create(null); -parser[0] = new RegExp("Mozilla.*Mobile.*(Flipboard).(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("Mozilla.{1,200}Mobile.{1,100}(Flipboard).(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[47] = parser; +exports.browser[68] = parser; parser = Object.create(null); -parser[0] = new RegExp("Mozilla.*Mobile.*(Flipboard-Briefing).(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("Mozilla.{1,200}Mobile.{1,100}(Flipboard-Briefing).(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[48] = parser; +exports.browser[69] = parser; parser = Object.create(null); -parser[0] = new RegExp("Mozilla.*Mobile.*(Onefootball)\\/Android.(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("Mozilla.{1,200}Mobile.{1,100}(Onefootball)\\/Android.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[49] = parser; +exports.browser[70] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Snapchat)\\/(\\d+)\\.(\\d+)\\.(\\d+).(\\d+)"); +parser[0] = new RegExp("(Snapchat)\\/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[50] = parser; +exports.browser[71] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Twitter for (?:iPhone|iPad)|TwitterAndroid)(?:\\/(\\d+)\\.(\\d+)|)"); +parser[1] = "Twitter"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[72] = parser; +parser = Object.create(null); +parser[0] = new RegExp("Mozilla.{1,100}Mobile.{1,100}AspiegelBot"); +parser[1] = "Spider"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[73] = parser; +parser = Object.create(null); +parser[0] = new RegExp("AspiegelBot"); +parser[1] = "Spider"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[74] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+) Basilisk/(\\d+)"); parser[1] = "Basilisk"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[51] = parser; +exports.browser[75] = parser; parser = Object.create(null); parser[0] = new RegExp("(PaleMoon)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "Pale Moon"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[52] = parser; +exports.browser[76] = parser; parser = Object.create(null); parser[0] = new RegExp("(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)"); parser[1] = "Firefox Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[53] = parser; +exports.browser[77] = parser; parser = Object.create(null); parser[0] = new RegExp("(Fennec)/(\\d+)\\.(\\d+)(pre)"); parser[1] = "Firefox Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[54] = parser; +exports.browser[78] = parser; parser = Object.create(null); parser[0] = new RegExp("(Fennec)/(\\d+)\\.(\\d+)"); parser[1] = "Firefox Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[55] = parser; +exports.browser[79] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:Mobile|Tablet);.*(Firefox)/(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(?:Mobile|Tablet);.{0,200}(Firefox)/(\\d+)\\.(\\d+)"); parser[1] = "Firefox Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[56] = parser; +exports.browser[80] = parser; parser = Object.create(null); parser[0] = new RegExp("(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre|))"); parser[1] = "Firefox ($1)"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[57] = parser; +exports.browser[81] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)"); parser[1] = "Firefox Alpha"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[58] = parser; +exports.browser[82] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)"); parser[1] = "Firefox Beta"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[59] = parser; +exports.browser[83] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)-(?:\\d+\\.\\d+|)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)"); parser[1] = "Firefox Alpha"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[60] = parser; +exports.browser[84] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)-(?:\\d+\\.\\d+|)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)"); parser[1] = "Firefox Beta"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[61] = parser; +exports.browser[85] = parser; parser = Object.create(null); parser[0] = new RegExp("(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*|)"); parser[1] = "Firefox ($1)"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[62] = parser; +exports.browser[86] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(Firefox).{0,200}Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "MicroB"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[63] = parser; +exports.browser[87] = parser; parser = Object.create(null); parser[0] = new RegExp("(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[64] = parser; +exports.browser[88] = parser; parser = Object.create(null); parser[0] = new RegExp("(FxiOS)/(\\d+)\\.(\\d+)(\\.(\\d+)|)(\\.(\\d+)|)"); parser[1] = "Firefox iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[65] = parser; +exports.browser[89] = parser; parser = Object.create(null); parser[0] = new RegExp("(Flock)/(\\d+)\\.(\\d+)(b\\d+?)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[66] = parser; +exports.browser[90] = parser; parser = Object.create(null); parser[0] = new RegExp("(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[67] = parser; +exports.browser[91] = parser; parser = Object.create(null); parser[0] = new RegExp("(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Netscape"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[68] = parser; +exports.browser[92] = parser; parser = Object.create(null); parser[0] = new RegExp("(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)"); parser[1] = "Netscape"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[69] = parser; +exports.browser[93] = parser; parser = Object.create(null); parser[0] = new RegExp("(Netscape6)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+|)"); parser[1] = "Netscape"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[70] = parser; +exports.browser[94] = parser; parser = Object.create(null); parser[0] = new RegExp("(MyIBrow)/(\\d+)\\.(\\d+)"); parser[1] = "My Internet Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[71] = parser; +exports.browser[95] = parser; parser = Object.create(null); parser[0] = new RegExp("(UC? ?Browser|UCWEB|U3)[ /]?(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "UC Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[72] = parser; +exports.browser[96] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Opera Tablet).*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[0] = new RegExp("(Opera Tablet).{0,200}Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[73] = parser; +exports.browser[97] = parser; parser = Object.create(null); parser[0] = new RegExp("(Opera Mini)(?:/att|)/?(\\d+|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[74] = parser; +exports.browser[98] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Opera)/.+Opera Mobi.+Version/(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(Opera)/.{1,100}Opera Mobi.{1,100}Version/(\\d+)\\.(\\d+)"); parser[1] = "Opera Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[75] = parser; +exports.browser[99] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Opera)/(\\d+)\\.(\\d+).+Opera Mobi"); +parser[0] = new RegExp("(Opera)/(\\d+)\\.(\\d+).{1,100}Opera Mobi"); parser[1] = "Opera Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[76] = parser; +exports.browser[100] = parser; parser = Object.create(null); -parser[0] = new RegExp("Opera Mobi.+(Opera)(?:/|\\s+)(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("Opera Mobi.{1,100}(Opera)(?:/|\\s+)(\\d+)\\.(\\d+)"); parser[1] = "Opera Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[77] = parser; +exports.browser[101] = parser; parser = Object.create(null); parser[0] = new RegExp("Opera Mobi"); parser[1] = "Opera Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[78] = parser; +exports.browser[102] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Opera)/9.80.*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[0] = new RegExp("(Opera)/9.80.{0,200}Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[79] = parser; +exports.browser[103] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:Mobile Safari).*(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(?:Mobile Safari).{1,300}(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Opera Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[80] = parser; +exports.browser[104] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:Chrome).*(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(?:Chrome).{1,300}(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Opera"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[81] = parser; +exports.browser[105] = parser; parser = Object.create(null); parser[0] = new RegExp("(Coast)/(\\d+).(\\d+).(\\d+)"); parser[1] = "Opera Coast"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[82] = parser; +exports.browser[106] = parser; parser = Object.create(null); parser[0] = new RegExp("(OPiOS)/(\\d+).(\\d+).(\\d+)"); parser[1] = "Opera Mini"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[83] = parser; +exports.browser[107] = parser; parser = Object.create(null); -parser[0] = new RegExp("Chrome/.+( MMS)/(\\d+).(\\d+).(\\d+)"); +parser[0] = new RegExp("Chrome/.{1,200}( MMS)/(\\d+).(\\d+).(\\d+)"); parser[1] = "Opera Neon"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[84] = parser; +exports.browser[108] = parser; parser = Object.create(null); parser[0] = new RegExp("(hpw|web)OS/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "webOS Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[85] = parser; +exports.browser[109] = parser; parser = Object.create(null); parser[0] = new RegExp("(luakit)"); parser[1] = "LuaKit"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[86] = parser; +exports.browser[110] = parser; parser = Object.create(null); parser[0] = new RegExp("(Snowshoe)/(\\d+)\\.(\\d+).(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[87] = parser; +exports.browser[111] = parser; parser = Object.create(null); parser[0] = new RegExp("Gecko/\\d+ (Lightning)/(\\d+)\\.(\\d+)\\.?((?:[ab]?\\d+[a-z]*)|(?:\\d*))"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[88] = parser; +exports.browser[112] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre|)) \\(Swiftfox\\)"); parser[1] = "Swiftfox"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[89] = parser; +exports.browser[113] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*|) \\(Swiftfox\\)"); parser[1] = "Swiftfox"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[90] = parser; +exports.browser[114] = parser; parser = Object.create(null); parser[0] = new RegExp("(rekonq)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|) Safari"); parser[1] = "Rekonq"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[91] = parser; +exports.browser[115] = parser; parser = Object.create(null); parser[0] = new RegExp("rekonq"); parser[1] = "Rekonq"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[92] = parser; +exports.browser[116] = parser; parser = Object.create(null); parser[0] = new RegExp("(conkeror|Conkeror)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "Conkeror"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[93] = parser; +exports.browser[117] = parser; parser = Object.create(null); parser[0] = new RegExp("(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Konqueror"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[94] = parser; +exports.browser[118] = parser; parser = Object.create(null); parser[0] = new RegExp("(WeTab)-Browser"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[95] = parser; +exports.browser[119] = parser; parser = Object.create(null); parser[0] = new RegExp("(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Comodo Dragon"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[96] = parser; +exports.browser[120] = parser; parser = Object.create(null); parser[0] = new RegExp("(Symphony) (\\d+).(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[97] = parser; +exports.browser[121] = parser; parser = Object.create(null); -parser[0] = new RegExp("PLAYSTATION 3.+WebKit"); +parser[0] = new RegExp("PLAYSTATION 3.{1,200}WebKit"); parser[1] = "NetFront NX"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[98] = parser; +exports.browser[122] = parser; parser = Object.create(null); parser[0] = new RegExp("PLAYSTATION 3"); parser[1] = "NetFront"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[99] = parser; +exports.browser[123] = parser; parser = Object.create(null); parser[0] = new RegExp("(PlayStation Portable)"); parser[1] = "NetFront"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[100] = parser; +exports.browser[124] = parser; parser = Object.create(null); parser[0] = new RegExp("(PlayStation Vita)"); parser[1] = "NetFront NX"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[101] = parser; +exports.browser[125] = parser; parser = Object.create(null); -parser[0] = new RegExp("AppleWebKit.+ (NX)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("AppleWebKit.{1,200} (NX)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "NetFront NX"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[102] = parser; +exports.browser[126] = parser; parser = Object.create(null); parser[0] = new RegExp("(Nintendo 3DS)"); parser[1] = "NetFront NX"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[103] = parser; +exports.browser[127] = parser; parser = Object.create(null); parser[0] = new RegExp("(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+)|)"); parser[1] = "Amazon Silk"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[104] = parser; +exports.browser[128] = parser; parser = Object.create(null); parser[0] = new RegExp("(Puffin)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[105] = parser; +exports.browser[129] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone .*(Edge)/(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("Windows Phone .{0,200}(Edge)/(\\d+)\\.(\\d+)"); parser[1] = "Edge Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[106] = parser; +exports.browser[130] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(EdgiOS|EdgA)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = "Edge Mobile"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[131] = parser; parser = Object.create(null); parser[0] = new RegExp("(SamsungBrowser)/(\\d+)\\.(\\d+)"); parser[1] = "Samsung Internet"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[107] = parser; +exports.browser[132] = parser; parser = Object.create(null); parser[0] = new RegExp("(SznProhlizec)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "Seznam prohlížeč"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[108] = parser; +exports.browser[133] = parser; parser = Object.create(null); parser[0] = new RegExp("(coc_coc_browser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "Coc Coc"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[109] = parser; +exports.browser[134] = parser; parser = Object.create(null); parser[0] = new RegExp("(baidubrowser)[/\\s](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = "Baidu Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[110] = parser; +exports.browser[135] = parser; parser = Object.create(null); parser[0] = new RegExp("(FlyFlow)/(\\d+)\\.(\\d+)"); parser[1] = "Baidu Explorer"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[111] = parser; +exports.browser[136] = parser; parser = Object.create(null); parser[0] = new RegExp("(MxBrowser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "Maxthon"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[112] = parser; +exports.browser[137] = parser; parser = Object.create(null); parser[0] = new RegExp("(Crosswalk)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[113] = parser; +exports.browser[138] = parser; parser = Object.create(null); parser[0] = new RegExp("(Line)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "LINE"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[114] = parser; +exports.browser[139] = parser; parser = Object.create(null); parser[0] = new RegExp("(MiuiBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "MiuiBrowser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[115] = parser; +exports.browser[140] = parser; parser = Object.create(null); parser[0] = new RegExp("(Mint Browser)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Mint Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[116] = parser; +exports.browser[141] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(TopBuzz)/(\\d+).(\\d+).(\\d+)"); +parser[1] = "TopBuzz"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[142] = parser; parser = Object.create(null); -parser[0] = new RegExp("Mozilla.+Android.+(GSA)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("Mozilla.{1,200}Android.{1,200}(GSA)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Google"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[117] = parser; +exports.browser[143] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(MQQBrowser/Mini)(?:(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[1] = "QQ Browser Mini"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[144] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(MQQBrowser)(?:/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[1] = "QQ Browser Mobile"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[145] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(QQBrowser)(?:/(\\d+)(?:\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)|)"); +parser[1] = "QQ Browser"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[146] = parser; +parser = Object.create(null); +parser[0] = new RegExp("Mobile.{0,200}(DuckDuckGo)/(\\d+)"); +parser[1] = "DuckDuckGo Mobile"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[147] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Tenta/)(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = "Tenta Browser"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[148] = parser; parser = Object.create(null); -parser[0] = new RegExp("Version/.+(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("Version/.{1,300}(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Chrome Mobile WebView"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[118] = parser; +exports.browser[149] = parser; parser = Object.create(null); -parser[0] = new RegExp("; wv\\).+(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("; wv\\).{1,300}(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Chrome Mobile WebView"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[119] = parser; +exports.browser[150] = parser; parser = Object.create(null); parser[0] = new RegExp("(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Chrome Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[120] = parser; +exports.browser[151] = parser; parser = Object.create(null); parser[0] = new RegExp("(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Chrome Mobile iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[121] = parser; +exports.browser[152] = parser; parser = Object.create(null); parser[0] = new RegExp("(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile(?:[ /]|$)"); parser[1] = "Chrome Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[122] = parser; +exports.browser[153] = parser; parser = Object.create(null); -parser[0] = new RegExp(" Mobile .*(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp(" Mobile .{1,300}(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Chrome Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[123] = parser; +exports.browser[154] = parser; parser = Object.create(null); parser[0] = new RegExp("(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Chrome Frame"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[124] = parser; +exports.browser[155] = parser; parser = Object.create(null); parser[0] = new RegExp("(SLP Browser)/(\\d+)\\.(\\d+)"); parser[1] = "Tizen Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[125] = parser; +exports.browser[156] = parser; parser = Object.create(null); parser[0] = new RegExp("(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)"); parser[1] = "Sogou Explorer"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[126] = parser; -parser = Object.create(null); -parser[0] = new RegExp("(MQQBrowser/Mini)(?:(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); -parser[1] = "QQ Browser Mini"; -parser[2] = 0; -parser[3] = 0; -parser[4] = 0; -exports.browser[127] = parser; -parser = Object.create(null); -parser[0] = new RegExp("(MQQBrowser)(?:/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); -parser[1] = "QQ Browser Mobile"; -parser[2] = 0; -parser[3] = 0; -parser[4] = 0; -exports.browser[128] = parser; +exports.browser[157] = parser; parser = Object.create(null); -parser[0] = new RegExp("(QQBrowser)(?:/(\\d+)(?:\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)|)"); -parser[1] = "QQ Browser"; +parser[0] = new RegExp("(Rackspace Monitoring)/(\\d+)\\.(\\d+)"); +parser[1] = "RackspaceBot"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[129] = parser; +exports.browser[158] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Rackspace Monitoring)/(\\d+)\\.(\\d+)"); -parser[1] = "RackspaceBot"; +parser[0] = new RegExp("(PRTG Network Monitor)"); +parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[130] = parser; +exports.browser[159] = parser; parser = Object.create(null); parser[0] = new RegExp("(PyAMF)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[131] = parser; +exports.browser[160] = parser; parser = Object.create(null); parser[0] = new RegExp("(YaBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Yandex Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[132] = parser; +exports.browser[161] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+).* MRCHROME"); +parser[0] = new RegExp("(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+).{0,100} MRCHROME"); parser[1] = "Mail.ru Chromium Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[133] = parser; +exports.browser[162] = parser; parser = Object.create(null); parser[0] = new RegExp("(AOL) (\\d+)\\.(\\d+); AOLBuild (\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[134] = parser; +exports.browser[163] = parser; parser = Object.create(null); parser[0] = new RegExp("(PodCruncher|Downcast)[ /]?(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[135] = parser; +exports.browser[164] = parser; parser = Object.create(null); parser[0] = new RegExp(" (BoxNotes)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[136] = parser; +exports.browser[165] = parser; parser = Object.create(null); parser[0] = new RegExp("(Whale)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile(?:[ /]|$)"); parser[1] = "Whale"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[137] = parser; +exports.browser[166] = parser; parser = Object.create(null); parser[0] = new RegExp("(Whale)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Whale"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[138] = parser; +exports.browser[167] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(1Password)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[168] = parser; parser = Object.create(null); parser[0] = new RegExp("(Ghost)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[139] = parser; +exports.browser[169] = parser; +parser = Object.create(null); +parser[0] = new RegExp("PAN (GlobalProtect)/(\\d+)\\.(\\d+)\\.(\\d+) .{1,100} \\(X11; Linux x86_64\\)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[170] = parser; parser = Object.create(null); parser[0] = new RegExp("(Slack_SSB)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Slack Desktop Client"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[140] = parser; +exports.browser[171] = parser; parser = Object.create(null); parser[0] = new RegExp("(HipChat)/?(\\d+|)"); parser[1] = "HipChat Desktop Client"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[141] = parser; +exports.browser[172] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(MobileIron|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Spotify|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iris|UP\\.Browser|Bunjalloo|Google Earth|Raven for Mac|Openwave|MacOutlook|Electron|OktaMobile)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[142] = parser; +exports.browser[173] = parser; parser = Object.create(null); parser[0] = new RegExp("Microsoft Office Outlook 12\\.\\d+\\.\\d+|MSOffice 12"); parser[1] = "Outlook"; parser[2] = "2007"; parser[3] = 0; parser[4] = 0; -exports.browser[143] = parser; +exports.browser[174] = parser; parser = Object.create(null); parser[0] = new RegExp("Microsoft Outlook 14\\.\\d+\\.\\d+|MSOffice 14"); parser[1] = "Outlook"; parser[2] = "2010"; parser[3] = 0; parser[4] = 0; -exports.browser[144] = parser; +exports.browser[175] = parser; parser = Object.create(null); parser[0] = new RegExp("Microsoft Outlook 15\\.\\d+\\.\\d+"); parser[1] = "Outlook"; parser[2] = "2013"; parser[3] = 0; parser[4] = 0; -exports.browser[145] = parser; +exports.browser[176] = parser; parser = Object.create(null); -parser[0] = new RegExp("Microsoft Outlook (?:Mail )?16\\.\\d+\\.\\d+"); +parser[0] = new RegExp("Microsoft Outlook (?:Mail )?16\\.\\d+\\.\\d+|MSOffice 16"); parser[1] = "Outlook"; parser[2] = "2016"; parser[3] = 0; parser[4] = 0; -exports.browser[146] = parser; +exports.browser[177] = parser; parser = Object.create(null); parser[0] = new RegExp("Microsoft Office (Word) 2014"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[147] = parser; +exports.browser[178] = parser; parser = Object.create(null); -parser[0] = new RegExp("Outlook-Express\\/7\\.0.*"); +parser[0] = new RegExp("Outlook-Express\\/7\\.0"); parser[1] = "Windows Live Mail"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[148] = parser; +exports.browser[179] = parser; parser = Object.create(null); parser[0] = new RegExp("(Airmail) (\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[149] = parser; +exports.browser[180] = parser; parser = Object.create(null); parser[0] = new RegExp("(Thunderbird)/(\\d+)\\.(\\d+)(?:\\.(\\d+(?:pre|))|)"); parser[1] = "Thunderbird"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[150] = parser; +exports.browser[181] = parser; parser = Object.create(null); parser[0] = new RegExp("(Postbox)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Postbox"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[151] = parser; +exports.browser[182] = parser; parser = Object.create(null); parser[0] = new RegExp("(Barca(?:Pro)?)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "Barca"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[152] = parser; +exports.browser[183] = parser; parser = Object.create(null); parser[0] = new RegExp("(Lotus-Notes)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "Lotus Notes"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[153] = parser; +exports.browser[184] = parser; +parser = Object.create(null); +parser[0] = new RegExp("Superhuman"); +parser[1] = "Superhuman"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[185] = parser; parser = Object.create(null); parser[0] = new RegExp("(Vivaldi)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[154] = parser; +exports.browser[186] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Edge)/(\\d+)(?:\\.(\\d+)|)"); -parser[1] = 0; +parser[0] = new RegExp("(Edge?)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); +parser[1] = "Edge"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[155] = parser; +exports.browser[187] = parser; parser = Object.create(null); parser[0] = new RegExp("(brave)/(\\d+)\\.(\\d+)\\.(\\d+) Chrome"); parser[1] = "Brave"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[156] = parser; +exports.browser[188] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)[\\d.]* Iron[^/]"); +parser[0] = new RegExp("(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)[\\d.]{0,100} Iron[^/]"); parser[1] = "Iron"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[157] = parser; +exports.browser[189] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(Dolphin)(?: |HDCN/|/INT\\-)(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[158] = parser; +exports.browser[190] = parser; parser = Object.create(null); parser[0] = new RegExp("(HeadlessChrome)(?:/(\\d+)\\.(\\d+)\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[159] = parser; +exports.browser[191] = parser; parser = Object.create(null); parser[0] = new RegExp("(Evolution)/(\\d+)\\.(\\d+)\\.(\\d+\\.\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[160] = parser; +exports.browser[192] = parser; parser = Object.create(null); parser[0] = new RegExp("(RCM CardDAV plugin)/(\\d+)\\.(\\d+)\\.(\\d+(?:-dev|))"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[161] = parser; +exports.browser[193] = parser; parser = Object.create(null); parser[0] = new RegExp("(bingbot|Bolt|AdobeAIR|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|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|iTunes|MacAppStore|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser|mDolphin|qutebrowser|Otter|QupZilla|MailBar|kmail2|YahooMobileMail|ExchangeWebServices|ExchangeServicesClient|Dragon|Outlook-iOS-Android)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[162] = parser; +exports.browser[194] = parser; parser = Object.create(null); parser[0] = new RegExp("(Chromium|Chrome)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[163] = parser; +exports.browser[195] = parser; parser = Object.create(null); parser[0] = new RegExp("(IEMobile)[ /](\\d+)\\.(\\d+)"); parser[1] = "IE Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[164] = parser; +exports.browser[196] = parser; parser = Object.create(null); parser[0] = new RegExp("(BacaBerita App)\\/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[165] = parser; +exports.browser[197] = parser; parser = Object.create(null); parser[0] = new RegExp("^(bPod|Pocket Casts|Player FM)$"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[166] = parser; +exports.browser[198] = parser; parser = Object.create(null); parser[0] = new RegExp("^(AlexaMediaPlayer|VLC)/(\\d+)\\.(\\d+)\\.([^.\\s]+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[167] = parser; +exports.browser[199] = parser; parser = Object.create(null); parser[0] = new RegExp("^(AntennaPod|WMPlayer|Zune|Podkicker|Radio|ExoPlayerDemo|Overcast|PocketTunes|NSPlayer|okhttp|DoggCatcher|QuickNews|QuickTime|Peapod|Podcasts|GoldenPod|VLC|Spotify|Miro|MediaGo|Juice|iPodder|gPodder|Banshee)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[168] = parser; +exports.browser[200] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Peapod|Liferea)/([^.\\s]+)\\.([^.\\s]+|)\\.?([^.\\s]+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[169] = parser; +exports.browser[201] = parser; parser = Object.create(null); parser[0] = new RegExp("^(bPod|Player FM) BMID/(\\S+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[170] = parser; +exports.browser[202] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Podcast ?Addict)/v(\\d+) "); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[171] = parser; +exports.browser[203] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Podcast ?Addict) "); parser[1] = "PodcastAddict"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[172] = parser; +exports.browser[204] = parser; parser = Object.create(null); parser[0] = new RegExp("(Replay) AV"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[173] = parser; +exports.browser[205] = parser; parser = Object.create(null); parser[0] = new RegExp("(VOX) Music Player"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[174] = parser; +exports.browser[206] = parser; parser = Object.create(null); parser[0] = new RegExp("(CITA) RSS Aggregator/(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[175] = parser; +exports.browser[207] = parser; parser = Object.create(null); parser[0] = new RegExp("(Pocket Casts)$"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[176] = parser; +exports.browser[208] = parser; parser = Object.create(null); parser[0] = new RegExp("(Player FM)$"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[177] = parser; +exports.browser[209] = parser; parser = Object.create(null); parser[0] = new RegExp("(LG Player|Doppler|FancyMusic|MediaMonkey|Clementine) (\\d+)\\.(\\d+)\\.?([^.\\s]+|)\\.?([^.\\s]+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[178] = parser; +exports.browser[210] = parser; parser = Object.create(null); parser[0] = new RegExp("(philpodder)/(\\d+)\\.(\\d+)\\.?([^.\\s]+|)\\.?([^.\\s]+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[179] = parser; +exports.browser[211] = parser; parser = Object.create(null); parser[0] = new RegExp("(Player FM|Pocket Casts|DoggCatcher|Spotify|MediaMonkey|MediaGo|BashPodder)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[180] = parser; +exports.browser[212] = parser; parser = Object.create(null); parser[0] = new RegExp("(QuickTime)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[181] = parser; +exports.browser[213] = parser; parser = Object.create(null); parser[0] = new RegExp("(Kinoma)(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[182] = parser; +exports.browser[214] = parser; parser = Object.create(null); parser[0] = new RegExp("(Fancy) Cloud Music (\\d+)\\.(\\d+)"); parser[1] = "FancyMusic"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[183] = parser; +exports.browser[215] = parser; parser = Object.create(null); parser[0] = new RegExp("EspnDownloadManager"); parser[1] = "ESPN"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[184] = parser; +exports.browser[216] = parser; parser = Object.create(null); parser[0] = new RegExp("(ESPN) Radio (\\d+)\\.(\\d+)(?:\\.(\\d+)|) ?(?:rv:(\\d+)|) "); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[185] = parser; +exports.browser[217] = parser; parser = Object.create(null); parser[0] = new RegExp("(podracer|jPodder) v ?(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[186] = parser; +exports.browser[218] = parser; parser = Object.create(null); parser[0] = new RegExp("(ZDM)/(\\d+)\\.(\\d+)[; ]?"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[187] = parser; +exports.browser[219] = parser; parser = Object.create(null); parser[0] = new RegExp("(Zune|BeyondPod) (\\d+)(?:\\.(\\d+)|)[\\);]"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[188] = parser; +exports.browser[220] = parser; parser = Object.create(null); parser[0] = new RegExp("(WMPlayer)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[189] = parser; +exports.browser[221] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Lavf)"); parser[1] = "WMPlayer"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[190] = parser; +exports.browser[222] = parser; parser = Object.create(null); parser[0] = new RegExp("^(RSSRadio)[ /]?(\\d+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[191] = parser; +exports.browser[223] = parser; parser = Object.create(null); parser[0] = new RegExp("(RSS_Radio) (\\d+)\\.(\\d+)"); parser[1] = "RSSRadio"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[192] = parser; +exports.browser[224] = parser; parser = Object.create(null); parser[0] = new RegExp("(Podkicker) \\S+/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Podkicker"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[193] = parser; +exports.browser[225] = parser; parser = Object.create(null); parser[0] = new RegExp("^(HTC) Streaming Player \\S+ / \\S+ / \\S+ / (\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[194] = parser; +exports.browser[226] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Stitcher)/iOS"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[195] = parser; +exports.browser[227] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Stitcher)/Android"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[196] = parser; +exports.browser[228] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(VLC) .*version (\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("^(VLC) .{0,200}version (\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[197] = parser; +exports.browser[229] = parser; parser = Object.create(null); parser[0] = new RegExp(" (VLC) for"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[198] = parser; +exports.browser[230] = parser; parser = Object.create(null); parser[0] = new RegExp("(vlc)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "VLC"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[199] = parser; +exports.browser[231] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(foobar)\\S+/([^.\\s]+)\\.([^.\\s]+|)\\.?([^.\\s]+|)"); +parser[0] = new RegExp("^(foobar)\\S{1,10}/(\\d+)\\.(\\d+|)\\.?([\\da-z]+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[200] = parser; +exports.browser[232] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(Clementine)\\S+ ([^.\\s]+)\\.([^.\\s]+|)\\.?([^.\\s]+|)"); +parser[0] = new RegExp("^(Clementine)\\S{1,10} (\\d+)\\.(\\d+|)\\.?(\\d+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[201] = parser; +exports.browser[233] = parser; parser = Object.create(null); -parser[0] = new RegExp("(amarok)/([^.\\s]+)\\.([^.\\s]+|)\\.?([^.\\s]+|)"); +parser[0] = new RegExp("(amarok)/(\\d+)\\.(\\d+|)\\.?(\\d+|)"); parser[1] = "Amarok"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[202] = parser; +exports.browser[234] = parser; parser = Object.create(null); parser[0] = new RegExp("(Custom)-Feed Reader"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[203] = parser; +exports.browser[235] = parser; parser = Object.create(null); parser[0] = new RegExp("(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[204] = parser; +exports.browser[236] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iCab|Lunascape|Opera|Android|Jasmine|Polaris|Microsoft SkyDriveSync|The Bat!) (\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[0] = new RegExp("(iCab|Lunascape|Opera|Android|Jasmine|Polaris|Microsoft SkyDriveSync|The Bat!) (\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[205] = parser; +exports.browser[237] = parser; parser = Object.create(null); parser[0] = new RegExp("(Kindle)/(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[206] = parser; +exports.browser[238] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Donut"); parser[1] = 0; parser[2] = "1"; parser[3] = "2"; parser[4] = 0; -exports.browser[207] = parser; +exports.browser[239] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Eclair"); parser[1] = 0; parser[2] = "2"; parser[3] = "1"; parser[4] = 0; -exports.browser[208] = parser; +exports.browser[240] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Froyo"); parser[1] = 0; parser[2] = "2"; parser[3] = "2"; parser[4] = 0; -exports.browser[209] = parser; +exports.browser[241] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Gingerbread"); parser[1] = 0; parser[2] = "2"; parser[3] = "3"; parser[4] = 0; -exports.browser[210] = parser; +exports.browser[242] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Honeycomb"); parser[1] = 0; parser[2] = "3"; parser[3] = 0; parser[4] = 0; -exports.browser[211] = parser; +exports.browser[243] = parser; parser = Object.create(null); -parser[0] = new RegExp("(MSIE) (\\d+)\\.(\\d+).*XBLWP7"); +parser[0] = new RegExp("(MSIE) (\\d+)\\.(\\d+).{0,100}XBLWP7"); parser[1] = "IE Large Screen"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[212] = parser; +exports.browser[244] = parser; parser = Object.create(null); parser[0] = new RegExp("(Nextcloud)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[213] = parser; +exports.browser[245] = parser; parser = Object.create(null); parser[0] = new RegExp("(mirall)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[214] = parser; +exports.browser[246] = parser; parser = Object.create(null); parser[0] = new RegExp("(ownCloud-android)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Owncloud"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[215] = parser; +exports.browser[247] = parser; parser = Object.create(null); parser[0] = new RegExp("(OC)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) \\(Skype for Business\\)"); parser[1] = "Skype"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[216] = parser; +exports.browser[248] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(OpenVAS)(?:-VT)?(?:[ \\/](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[1] = "OpenVAS Scanner"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[249] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(AnyConnect)\\/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[250] = parser; +parser = Object.create(null); +parser[0] = new RegExp("compatible; monitis"); +parser[1] = "Monitis"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[251] = parser; parser = Object.create(null); parser[0] = new RegExp("(Obigo)InternetBrowser"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[217] = parser; +exports.browser[252] = parser; parser = Object.create(null); parser[0] = new RegExp("(Obigo)\\-Browser"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[218] = parser; +exports.browser[253] = parser; parser = Object.create(null); parser[0] = new RegExp("(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+)|)"); parser[1] = "Obigo"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[219] = parser; +exports.browser[254] = parser; parser = Object.create(null); parser[0] = new RegExp("(MAXTHON|Maxthon) (\\d+)\\.(\\d+)"); parser[1] = "Maxthon"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[220] = parser; +exports.browser[255] = parser; parser = Object.create(null); parser[0] = new RegExp("(Maxthon|MyIE2|Uzbl|Shiira)"); parser[1] = 0; parser[2] = "0"; parser[3] = 0; parser[4] = 0; -exports.browser[221] = parser; +exports.browser[256] = parser; parser = Object.create(null); parser[0] = new RegExp("(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[222] = parser; +exports.browser[257] = parser; parser = Object.create(null); parser[0] = new RegExp("(NCSA_Mosaic)/(\\d+)\\.(\\d+)"); parser[1] = "NCSA Mosaic"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[223] = parser; +exports.browser[258] = parser; parser = Object.create(null); parser[0] = new RegExp("(POLARIS)/(\\d+)\\.(\\d+)"); parser[1] = "Polaris"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[224] = parser; +exports.browser[259] = parser; parser = Object.create(null); parser[0] = new RegExp("(Embider)/(\\d+)\\.(\\d+)"); parser[1] = "Polaris"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[225] = parser; +exports.browser[260] = parser; parser = Object.create(null); parser[0] = new RegExp("(BonEcho)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+|)"); parser[1] = "Bon Echo"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[226] = parser; +exports.browser[261] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPod|iPhone|iPad).+GSA/(\\d+)\\.(\\d+)\\.(\\d+) Mobile"); -parser[1] = "Google"; +parser[0] = new RegExp("(TopBuzz) com.alex.NewsMaster/(\\d+).(\\d+).(\\d+)"); +parser[1] = "TopBuzz"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[227] = parser; +exports.browser[262] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPod|iPhone|iPad).+Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|).*[ +]Safari"); -parser[1] = "Mobile Safari"; +parser[0] = new RegExp("(TopBuzz) com.mobilesrepublic.newsrepublic/(\\d+).(\\d+).(\\d+)"); +parser[1] = "TopBuzz"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[228] = parser; +exports.browser[263] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\\d+)_(\\d+)(?:_(\\d+)|).* AppleNews\\/\\d+\\.\\d+\\.\\d+?"); -parser[1] = "Mobile Safari UI/WKWebView"; +parser[0] = new RegExp("(TopBuzz) com.topbuzz.videoen/(\\d+).(\\d+).(\\d+)"); +parser[1] = "TopBuzz"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[229] = parser; +exports.browser[264] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPod|iPhone|iPad).+Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); -parser[1] = "Mobile Safari UI/WKWebView"; +parser[0] = new RegExp("(iPod|iPhone|iPad).{1,200}GSA/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|) Mobile"); +parser[1] = "Google"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[230] = parser; +exports.browser[265] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\\d+)_(\\d+)(?:_(\\d+)|).*Mobile.*[ +]Safari"); +parser[0] = new RegExp("(iPod|iPhone|iPad).{1,200}Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|).{1,200}[ +]Safari"); parser[1] = "Mobile Safari"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[231] = parser; +exports.browser[266] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\\d+)_(\\d+)(?:_(\\d+)|).*Mobile"); +parser[0] = new RegExp("(iPod|iPod touch|iPhone|iPad);.{0,30}CPU.{0,30}OS[ +](\\d+)_(\\d+)(?:_(\\d+)|).{0,30} AppleNews\\/\\d+\\.\\d+(?:\\.\\d+|)"); parser[1] = "Mobile Safari UI/WKWebView"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[232] = parser; +exports.browser[267] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(iPod|iPhone|iPad).{1,200}Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "Mobile Safari UI/WKWebView"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[268] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPod|iPhone|iPad).* Safari"); +parser[0] = new RegExp("(iPod|iPod touch|iPhone|iPad).{0,200} Safari"); parser[1] = "Mobile Safari"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[233] = parser; +exports.browser[269] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPod|iPhone|iPad)"); +parser[0] = new RegExp("(iPod|iPod touch|iPhone|iPad)"); parser[1] = "Mobile Safari UI/WKWebView"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[234] = parser; +exports.browser[270] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Watch)(\\d+),(\\d+)"); +parser[1] = "Apple $1 App"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[271] = parser; parser = Object.create(null); parser[0] = new RegExp("(Outlook-iOS)/\\d+\\.\\d+\\.prod\\.iphone \\((\\d+)\\.(\\d+)\\.(\\d+)\\)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[235] = parser; +exports.browser[272] = parser; parser = Object.create(null); parser[0] = new RegExp("(AvantGo) (\\d+).(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[236] = parser; +exports.browser[273] = parser; parser = Object.create(null); parser[0] = new RegExp("(OneBrowser)/(\\d+).(\\d+)"); parser[1] = "ONE Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[237] = parser; +exports.browser[274] = parser; parser = Object.create(null); parser[0] = new RegExp("(Avant)"); parser[1] = 0; parser[2] = "1"; parser[3] = 0; parser[4] = 0; -exports.browser[238] = parser; +exports.browser[275] = parser; parser = Object.create(null); parser[0] = new RegExp("(QtCarBrowser)"); parser[1] = 0; parser[2] = "1"; parser[3] = 0; parser[4] = 0; -exports.browser[239] = parser; +exports.browser[276] = parser; parser = Object.create(null); parser[0] = new RegExp("^(iBrowser/Mini)(\\d+).(\\d+)"); parser[1] = "iBrowser Mini"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[240] = parser; +exports.browser[277] = parser; parser = Object.create(null); parser[0] = new RegExp("^(iBrowser|iRAPP)/(\\d+).(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[241] = parser; +exports.browser[278] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Nokia)"); parser[1] = "Nokia Services (WAP) Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[242] = parser; +exports.browser[279] = parser; parser = Object.create(null); parser[0] = new RegExp("(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)"); parser[1] = "Nokia Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[243] = parser; +exports.browser[280] = parser; parser = Object.create(null); parser[0] = new RegExp("(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)"); parser[1] = "Nokia Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[244] = parser; +exports.browser[281] = parser; parser = Object.create(null); parser[0] = new RegExp("(NokiaBrowser)/(\\d+)\\.(\\d+)"); parser[1] = "Nokia Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[245] = parser; +exports.browser[282] = parser; parser = Object.create(null); parser[0] = new RegExp("(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)"); parser[1] = "Nokia Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[246] = parser; +exports.browser[283] = parser; parser = Object.create(null); parser[0] = new RegExp("(Series60)/5\\.0"); parser[1] = "Nokia Browser"; parser[2] = "7"; parser[3] = "0"; parser[4] = 0; -exports.browser[247] = parser; +exports.browser[284] = parser; parser = Object.create(null); parser[0] = new RegExp("(Series60)/(\\d+)\\.(\\d+)"); parser[1] = "Nokia OSS Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[248] = parser; +exports.browser[285] = parser; parser = Object.create(null); parser[0] = new RegExp("(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Ovi Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[249] = parser; +exports.browser[286] = parser; parser = Object.create(null); parser[0] = new RegExp("(Nokia)[EN]?(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[250] = parser; +exports.browser[287] = parser; parser = Object.create(null); -parser[0] = new RegExp("(PlayBook).+RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(PlayBook).{1,200}RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "BlackBerry WebKit"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[251] = parser; +exports.browser[288] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Black[bB]erry|BB10).+Version/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(Black[bB]erry|BB10).{1,200}Version/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "BlackBerry WebKit"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[252] = parser; +exports.browser[289] = parser; parser = Object.create(null); parser[0] = new RegExp("(Black[bB]erry)\\s?(\\d+)"); parser[1] = "BlackBerry"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[253] = parser; +exports.browser[290] = parser; parser = Object.create(null); parser[0] = new RegExp("(OmniWeb)/v(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[254] = parser; +exports.browser[291] = parser; parser = Object.create(null); parser[0] = new RegExp("(Blazer)/(\\d+)\\.(\\d+)"); parser[1] = "Palm Blazer"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[255] = parser; +exports.browser[292] = parser; parser = Object.create(null); parser[0] = new RegExp("(Pre)/(\\d+)\\.(\\d+)"); parser[1] = "Palm Pre"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[256] = parser; +exports.browser[293] = parser; parser = Object.create(null); parser[0] = new RegExp("(ELinks)/(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[257] = parser; +exports.browser[294] = parser; parser = Object.create(null); parser[0] = new RegExp("(ELinks) \\((\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[258] = parser; +exports.browser[295] = parser; parser = Object.create(null); parser[0] = new RegExp("(Links) \\((\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[259] = parser; +exports.browser[296] = parser; parser = Object.create(null); parser[0] = new RegExp("(QtWeb) Internet Browser/(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[260] = parser; +exports.browser[297] = parser; parser = Object.create(null); parser[0] = new RegExp("(PhantomJS)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[261] = parser; +exports.browser[298] = parser; parser = Object.create(null); -parser[0] = new RegExp("(AppleWebKit)/(\\d+)(?:\\.(\\d+)|)\\+ .* Safari"); +parser[0] = new RegExp("(AppleWebKit)/(\\d+)(?:\\.(\\d+)|)\\+ .{0,200} Safari"); parser[1] = "WebKit Nightly"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[262] = parser; +exports.browser[299] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|).*Safari/"); +parser[0] = new RegExp("(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|).{0,100}Safari/"); parser[1] = "Safari"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[263] = parser; +exports.browser[300] = parser; parser = Object.create(null); parser[0] = new RegExp("(Safari)/\\d+"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[264] = parser; +exports.browser[301] = parser; parser = Object.create(null); parser[0] = new RegExp("(OLPC)/Update(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[265] = parser; +exports.browser[302] = parser; parser = Object.create(null); parser[0] = new RegExp("(OLPC)/Update()\\.(\\d+)"); parser[1] = 0; parser[2] = "0"; parser[3] = 0; parser[4] = 0; -exports.browser[266] = parser; +exports.browser[303] = parser; parser = Object.create(null); parser[0] = new RegExp("(SEMC\\-Browser)/(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[267] = parser; +exports.browser[304] = parser; parser = Object.create(null); parser[0] = new RegExp("(Teleca)"); parser[1] = "Teleca Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[268] = parser; +exports.browser[305] = parser; parser = Object.create(null); parser[0] = new RegExp("(Phantom)/V(\\d+)\\.(\\d+)"); parser[1] = "Phantom Browser"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[269] = parser; +exports.browser[306] = parser; parser = Object.create(null); parser[0] = new RegExp("(Trident)/(7|8)\\.(0)"); parser[1] = "IE"; parser[2] = "11"; parser[3] = 0; parser[4] = 0; -exports.browser[270] = parser; +exports.browser[307] = parser; parser = Object.create(null); parser[0] = new RegExp("(Trident)/(6)\\.(0)"); parser[1] = "IE"; parser[2] = "10"; parser[3] = 0; parser[4] = 0; -exports.browser[271] = parser; +exports.browser[308] = parser; parser = Object.create(null); parser[0] = new RegExp("(Trident)/(5)\\.(0)"); parser[1] = "IE"; parser[2] = "9"; parser[3] = 0; parser[4] = 0; -exports.browser[272] = parser; +exports.browser[309] = parser; parser = Object.create(null); parser[0] = new RegExp("(Trident)/(4)\\.(0)"); parser[1] = "IE"; parser[2] = "8"; parser[3] = 0; parser[4] = 0; -exports.browser[273] = parser; +exports.browser[310] = parser; parser = Object.create(null); parser[0] = new RegExp("(Espial)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[274] = parser; +exports.browser[311] = parser; parser = Object.create(null); parser[0] = new RegExp("(AppleWebKit)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Apple Mail"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[275] = parser; +exports.browser[312] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[276] = parser; +exports.browser[313] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[277] = parser; +exports.browser[314] = parser; parser = Object.create(null); parser[0] = new RegExp("([MS]?IE) (\\d+)\\.(\\d+)"); parser[1] = "IE"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[278] = parser; +exports.browser[315] = parser; parser = Object.create(null); parser[0] = new RegExp("(python-requests)/(\\d+)\\.(\\d+)"); parser[1] = "Python Requests"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[279] = parser; +exports.browser[316] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\b(Windows-Update-Agent|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|PycURL|Wget|aria2|Axel|OpenBSD ftp|lftp|jupdate|insomnia)(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); +parser[0] = new RegExp("\\b(Windows-Update-Agent|WindowsPowerShell|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|PycURL|Wget|wget2|aria2|Axel|OpenBSD ftp|lftp|jupdate|insomnia|fetch libfetch|akka-http|got|CloudCockpitBackend|ReactorNetty|axios|Jersey|Vert.x-WebClient|Apache-CXF|Go-CF-client|go-resty|AHC)(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[280] = parser; +exports.browser[317] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(cf)\\/(\\d+)\\.(\\d+)\\.(\\S+)"); +parser[1] = "CloudFoundry"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[318] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Java)[/ ]{0,1}\\d+\\.(\\d+)\\.(\\d+)[_-]*([a-zA-Z0-9]+|)"); +parser[0] = new RegExp("^(sap-leonardo-iot-sdk-nodejs) \\/ (\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[281] = parser; +exports.browser[319] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(SAP NetWeaver Application Server) \\(1.0;(\\d{1})(\\d{2})\\)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[320] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(\\w+-HTTPClient)\\/(\\d+)\\.(\\d+)-(\\S+)"); +parser[1] = "HTTPClient"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[321] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(go-cli)\\s(\\d+)\\.(\\d+).(\\S+)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[322] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(Java-EurekaClient|Java-EurekaClient-Replication|HTTPClient|lua-resty-http)\\/v?(\\d+)\\.(\\d+)\\.?(\\d*)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[323] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(ping-service|sap xsuaa|Node-oauth|Site24x7|SAP CPI|JAEGER_SECURITY)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[324] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Python/3\\.\\d{1,3} aiohttp)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = "Python aiohttp"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[325] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Java)[/ ]?\\d+\\.(\\d+)\\.(\\d+)[_-]*([a-zA-Z0-9]+|)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[326] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Cyberduck)/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.\\d+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[282] = parser; +exports.browser[327] = parser; parser = Object.create(null); parser[0] = new RegExp("^(S3 Browser) (\\d+)-(\\d+)-(\\d+)(?:\\s*http://s3browser\\.com|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[283] = parser; +exports.browser[328] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(S3Gof3r)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[329] = parser; +parser = Object.create(null); +parser[0] = new RegExp("\\b(ibm-cos-sdk-(?:core|java|js|python))/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[330] = parser; +parser = Object.create(null); +parser[0] = new RegExp("^(rusoto)/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[331] = parser; parser = Object.create(null); parser[0] = new RegExp("^(rclone)/v(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[284] = parser; +exports.browser[332] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Roku)/DVP-(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[285] = parser; +exports.browser[333] = parser; parser = Object.create(null); parser[0] = new RegExp("(Kurio)\\/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Kurio App"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[286] = parser; +exports.browser[334] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Box(?: Sync)?)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[287] = parser; +exports.browser[335] = parser; parser = Object.create(null); parser[0] = new RegExp("^(ViaFree|Viafree)-(?:tvOS-)?[A-Z]{2}/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "ViaFree"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[288] = parser; +exports.browser[336] = parser; parser = Object.create(null); parser[0] = new RegExp("(Wget)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[289] = parser; +exports.browser[337] = parser; parser = Object.create(null); parser[0] = new RegExp("(curl)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "cURL"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[290] = parser; +exports.browser[338] = parser; -exports.browser.length = 291; +exports.browser.length = 339; exports.device = Object.create(null); @@ -2072,21 +2408,21 @@ parser[3] = 0; parser[4] = 0; exports.device[0] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:(?:iPhone|Windows CE|Windows Phone|Android).*(?:(?:Bot|Yeti)-Mobile|YRSpider|BingPreview|bots?/\\d|(?:bot|spider)\\.html)|AdsBot-Google-Mobile.*iPhone)"); +parser[0] = new RegExp("^.{0,100}?(?:(?:iPhone|Windows CE|Windows Phone|Android).{0,300}(?:(?:Bot|Yeti)-Mobile|YRSpider|BingPreview|bots?/\\d|(?:bot|spider)\\.html)|AdsBot-Google-Mobile.{0,200}iPhone)"); parser[1] = "Spider"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[1] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:DoCoMo|\\bMOT\\b|\\bLG\\b|Nokia|Samsung|SonyEricsson).*(?:(?:Bot|Yeti)-Mobile|bots?/\\d|(?:bot|crawler)\\.html|(?:jump|google|Wukong)bot|ichiro/mobile|/spider|YahooSeeker)"); +parser[0] = new RegExp("^.{0,100}?(?:DoCoMo|\\bMOT\\b|\\bLG\\b|Nokia|Samsung|SonyEricsson).{0,200}(?:(?:Bot|Yeti)-Mobile|bots?/\\d|(?:bot|crawler)\\.html|(?:jump|google|Wukong)bot|ichiro/mobile|/spider|YahooSeeker)"); parser[1] = "Spider"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[2] = parser; parser = Object.create(null); -parser[0] = new RegExp(" PTST/\\d+(?:\\.)?\\d+$"); +parser[0] = new RegExp(" PTST/\\d+(?:\\.\\d+|)$"); parser[1] = "Spider"; parser[2] = 0; parser[3] = 0; @@ -2100,4151 +2436,4319 @@ parser[3] = 0; parser[4] = 0; exports.device[4] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\bSmartWatch *\\( *([^;]+) *; *([^;]+) *;"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("Mozilla.{1,100}Mobile.{1,100}AspiegelBot"); +parser[1] = "Spider"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[5] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android Application[^\\-]+ - (Sony) ?(Ericsson|) (.+) \\w+ - "); -parser[1] = "$1 $2"; +parser[0] = new RegExp("Mozilla.{0,200}AspiegelBot"); +parser[1] = "Spider"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[6] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android Application[^\\-]+ - (?:HTC|HUAWEI|LGE|LENOVO|MEDION|TCT) (HTC|HUAWEI|LG|LENOVO|MEDION|ALCATEL)[ _\\-](.+) \\w+ - "); +parser[0] = new RegExp("\\bSmartWatch {0,2}\\( {0,2}([^;]{1,200}) {0,2}; {0,2}([^;]{1,200}) {0,2};"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[7] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android Application[^\\-]+ - ([^ ]+) (.+) \\w+ - "); +parser[0] = new RegExp("Android Application[^\\-]{1,300} - (Sony) ?(Ericsson|) (.{1,200}) \\w{1,20} - "); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[8] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([BLRQ]C\\d{4}[A-Z]+) +Build/"); -parser[1] = "3Q $1"; +parser[0] = new RegExp("Android Application[^\\-]{1,300} - (?:HTC|HUAWEI|LGE|LENOVO|MEDION|TCT) (HTC|HUAWEI|LG|LENOVO|MEDION|ALCATEL)[ _\\-](.{1,200}) \\w{1,20} - "); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[9] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:3Q_)([^;/]+) +Build"); -parser[1] = "3Q $1"; +parser[0] = new RegExp("Android Application[^\\-]{1,300} - ([^ ]+) (.{1,200}) \\w{1,20} - "); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[10] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android [34].*; *(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700(?: Lite| 3G|)|A701|B1-A71|A1-\\d{3}|B1-\\d{3}|V360|V370|W500|W500P|W501|W501P|W510|W511|W700|Slider SL101|DA22[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}([BLRQ]C\\d{4}[A-Z]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "3Q $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[11] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Acer Iconia Tab ([^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(?:3Q_)([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "3Q $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[12] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Z1[1235]0|E320[^/]*|S500|S510|Liquid[^;/]*|Iconia A\\d+) Build"); +parser[0] = new RegExp("Android [34].{0,200}; {0,2}(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700(?: Lite| 3G|)|A701|B1-A71|A1-\\d{3}|B1-\\d{3}|V360|V370|W500|W500P|W501|W501P|W510|W511|W700|Slider SL101|DA22[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[13] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Acer |ACER )([^;/]+) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}Acer Iconia Tab ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[14] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Advent |)(Vega(?:Bean|Comb|)).* Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(Z1[1235]0|E320[^/]{0,10}|S500|S510|Liquid[^;/]{0,30}|Iconia A\\d+)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[15] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Ainol |)((?:NOVO|[Nn]ovo)[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(Acer |ACER )([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[16] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *AIRIS[ _\\-]?([^/;\\)]+) *(?:;|\\)|Build)"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Advent |)(Vega(?:Bean|Comb|)).{0,200}?(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[17] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(OnePAD[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Ainol |)((?:NOVO|[Nn]ovo)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[18] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Airpad[ \\-]([^;/]+) Build"); -parser[1] = "Airpad $1"; +parser[0] = new RegExp("; {0,2}AIRIS[ _\\-]?([^/;\\)]+) {0,2}(?:;|\\)|Build)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[19] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(one ?touch) (EVO7|T10|T20) Build"); -parser[1] = "Alcatel One Touch $2"; +parser[0] = new RegExp("; {0,2}(OnePAD[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[20] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:alcatel[ _]|)(?:(?:one[ _]?touch[ _])|ot[ \\-])([^;/]+);? Build"); -parser[1] = "Alcatel One Touch $1"; +parser[0] = new RegExp("; {0,2}Airpad[ \\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Airpad $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[21] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TCL)[ _]([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(one ?touch) (EVO7|T10|T20)(?: Build|\\) AppleWebKit)"); +parser[1] = "Alcatel One Touch $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[22] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Vodafone Smart II|Optimus_Madrid) Build"); -parser[1] = "Alcatel $1"; +parser[0] = new RegExp("; {0,2}(?:alcatel[ _]|)(?:(?:one[ _]?touch[ _])|ot[ \\-])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Alcatel One Touch $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[23] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *BASE_Lutea_3 Build"); -parser[1] = "Alcatel One Touch 998"; +parser[0] = new RegExp("; {0,2}(TCL)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[24] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *BASE_Varia Build"); -parser[1] = "Alcatel One Touch 918D"; +parser[0] = new RegExp("; {0,2}(Vodafone Smart II|Optimus_Madrid)(?: Build|\\) AppleWebKit)"); +parser[1] = "Alcatel $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[25] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:FINE|Fine)\\d[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}BASE_Lutea_3(?: Build|\\) AppleWebKit)"); +parser[1] = "Alcatel One Touch 998"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[26] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ALLVIEW[ _]?|Allview[ _]?)((?:Speed|SPEED).*) Build/"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}BASE_Varia(?: Build|\\) AppleWebKit)"); +parser[1] = "Alcatel One Touch 918D"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[27] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ALLVIEW[ _]?|Allview[ _]?|)(AX1_Shine|AX2_Frenzy) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}((?:FINE|Fine)\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[28] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ALLVIEW[ _]?|Allview[ _]?)([^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(ALLVIEW[ _]?|Allview[ _]?)((?:Speed|SPEED).{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[29] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A13-MID) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(ALLVIEW[ _]?|Allview[ _]?|)(AX1_Shine|AX2_Frenzy)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[30] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Allwinner)[ _\\-]?([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(ALLVIEW[ _]?|Allview[ _]?)([^;/]*?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[31] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A651|A701B?|A702|A703|A705|A706|A707|A711|A712|A713|A717|A722|A785|A801|A802|A803|A901|A902|A1002|A1003|A1006|A1007|A9701|A9703|Q710|Q80) Build"); +parser[0] = new RegExp("; {0,2}(A13-MID)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[32] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:AMOI|Amoi)[ _]([^;/]+) Build"); -parser[1] = "Amoi $1"; +parser[0] = new RegExp("; {0,2}(Allwinner)[ _\\-]?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[33] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(?:AMOI|Amoi)[ _]([^;/]+) Linux"); -parser[1] = "Amoi $1"; +parser[0] = new RegExp("; {0,2}(A651|A701B?|A702|A703|A705|A706|A707|A711|A712|A713|A717|A722|A785|A801|A802|A803|A901|A902|A1002|A1003|A1006|A1007|A9701|A9703|Q710|Q80)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[34] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MW(?:0[789]|10)[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(?:AMOI|Amoi)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Amoi $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[35] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(G7|M1013|M1015G|M11[CG]?|M-?12[B]?|M15|M19[G]?|M30[ACQ]?|M31[GQ]|M32|M33[GQ]|M36|M37|M38|M701T|M710|M712B|M713|M715G|M716G|M71(?:G|GS|T|)|M72[T]?|M73[T]?|M75[GT]?|M77G|M79T|M7L|M7LN|M81|M810|M81T|M82|M92|M92KS|M92S|M717G|M721|M722G|M723|M725G|M739|M785|M791|M92SK|M93D) Build"); -parser[1] = "Aoson $1"; +parser[0] = new RegExp("^(?:AMOI|Amoi)[ _]([^;/]{1,100}?) Linux"); +parser[1] = "Amoi $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[36] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Aoson ([^;/]+) Build"); -parser[1] = "Aoson $1"; +parser[0] = new RegExp("; {0,2}(MW(?:0[789]|10)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[37] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *[Aa]panda[ _\\-]([^;/]+) Build"); -parser[1] = "Apanda $1"; +parser[0] = new RegExp("; {0,2}(G7|M1013|M1015G|M11[CG]?|M-?12[B]?|M15|M19[G]?|M30[ACQ]?|M31[GQ]|M32|M33[GQ]|M36|M37|M38|M701T|M710|M712B|M713|M715G|M716G|M71(?:G|GS|T|)|M72[T]?|M73[T]?|M75[GT]?|M77G|M79T|M7L|M7LN|M81|M810|M81T|M82|M92|M92KS|M92S|M717G|M721|M722G|M723|M725G|M739|M785|M791|M92SK|M93D)(?: Build|\\) AppleWebKit)"); +parser[1] = "Aoson $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[38] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:ARCHOS|Archos) ?(GAMEPAD.*?)(?: Build|[;/\\(\\)\\-])"); -parser[1] = "Archos $1"; +parser[0] = new RegExp("; {0,2}Aoson ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Aoson $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[39] = parser; parser = Object.create(null); -parser[0] = new RegExp("ARCHOS; GOGI; ([^;]+);"); -parser[1] = "Archos $1"; +parser[0] = new RegExp("; {0,2}[Aa]panda[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Apanda $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[40] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:ARCHOS|Archos)[ _]?(.*?)(?: Build|[;/\\(\\)\\-]|$)"); +parser[0] = new RegExp("; {0,2}(?:ARCHOS|Archos) ?(GAMEPAD.{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Archos $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[41] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(AN(?:7|8|9|10|13)[A-Z0-9]{1,4}) Build"); +parser[0] = new RegExp("ARCHOS; GOGI; ([^;]{1,200});"); parser[1] = "Archos $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[42] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A28|A32|A43|A70(?:BHT|CHT|HB|S|X)|A101(?:B|C|IT)|A7EB|A7EB-WK|101G9|80G9) Build"); +parser[0] = new RegExp("(?:ARCHOS|Archos)[ _]?(.{0,200}?)(?: Build|[;/\\(\\)\\-]|$)"); parser[1] = "Archos $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[43] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(PAD-FMD[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(AN(?:7|8|9|10|13)[A-Z0-9]{1,4})(?: Build|\\) AppleWebKit)"); +parser[1] = "Archos $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[44] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(BioniQ) ?([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(A28|A32|A43|A70(?:BHT|CHT|HB|S|X)|A101(?:B|C|IT)|A7EB|A7EB-WK|101G9|80G9)(?: Build|\\) AppleWebKit)"); +parser[1] = "Archos $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[45] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(AN\\d[^;/]+|ARCHM\\d+) Build"); -parser[1] = "Arnova $1"; +parser[0] = new RegExp("; {0,2}(PAD-FMD[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[46] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:ARNOVA|Arnova) ?([^;/]+) Build"); -parser[1] = "Arnova $1"; +parser[0] = new RegExp("; {0,2}(BioniQ) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[47] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:ASSISTANT |)(AP)-?([1789]\\d{2}[A-Z]{0,2}|80104) Build"); -parser[1] = "Assistant $1-$2"; +parser[0] = new RegExp("; {0,2}(AN\\d[^;/]{1,100}|ARCHM\\d+)(?: Build|\\) AppleWebKit)"); +parser[1] = "Arnova $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[48] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ME17\\d[^;/]*|ME3\\d{2}[^;/]+|K00[A-Z]|Nexus 10|Nexus 7(?: 2013|)|PadFone[^;/]*|Transformer[^;/]*|TF\\d{3}[^;/]*|eeepc) Build"); -parser[1] = "Asus $1"; +parser[0] = new RegExp("; {0,2}(?:ARNOVA|Arnova) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Arnova $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[49] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *ASUS[ _]*([^;/]+) Build"); -parser[1] = "Asus $1"; +parser[0] = new RegExp("; {0,2}(?:ASSISTANT |)(AP)-?([1789]\\d{2}[A-Z]{0,2}|80104)(?: Build|\\) AppleWebKit)"); +parser[1] = "Assistant $1-$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[50] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Garmin-Asus ([^;/]+) Build"); -parser[1] = "Garmin-Asus $1"; +parser[0] = new RegExp("; {0,2}(ME17\\d[^;/]*|ME3\\d{2}[^;/]{1,100}|K00[A-Z]|Nexus 10|Nexus 7(?: 2013|)|PadFone[^;/]*|Transformer[^;/]*|TF\\d{3}[^;/]*|eeepc)(?: Build|\\) AppleWebKit)"); +parser[1] = "Asus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[51] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Garminfone) Build"); -parser[1] = "Garmin $1"; +parser[0] = new RegExp("; {0,2}ASUS[ _]{0,10}([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Asus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[52] = parser; parser = Object.create(null); -parser[0] = new RegExp("; (@TAB-[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}Garmin-Asus ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Garmin-Asus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[53] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T-(?:07|[^0]\\d)[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Garminfone)(?: Build|\\) AppleWebKit)"); +parser[1] = "Garmin $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[54] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Axioo[ _\\-]([^;/]+)|(picopad)[ _\\-]([^;/]+)) Build"); -parser[1] = "Axioo $1$2 $3"; +parser[0] = new RegExp("; (@TAB-[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[55] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(V(?:100|700|800)[^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(T-(?:07|[^0]\\d)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[56] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IBAK\\-[^;/]*) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(?:Axioo[ _\\-]([^;/]{1,100}?)|(picopad)[ _\\-]([^;/]{1,100}?))(?: Build|\\) AppleWebKit)"); +parser[1] = "Axioo $1$2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[57] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(HY5001|HY6501|X12|X21|I5) Build"); -parser[1] = "Bedove $1"; +parser[0] = new RegExp("; {0,2}(V(?:100|700|800)[^;/]*)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[58] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(JC-[^;/]*) Build"); -parser[1] = "Benss $1"; +parser[0] = new RegExp("; {0,2}(IBAK\\-[^;/]*)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[59] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(BB) ([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(HY5001|HY6501|X12|X21|I5)(?: Build|\\) AppleWebKit)"); +parser[1] = "Bedove $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[60] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(BlackBird)[ _](I8.*) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(JC-[^;/]*)(?: Build|\\) AppleWebKit)"); +parser[1] = "Benss $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[61] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(BlackBird)[ _](.*) Build"); +parser[0] = new RegExp("; {0,2}(BB) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[62] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([0-9]+BP[EM][^;/]*|Endeavour[^;/]+) Build"); -parser[1] = "Blaupunkt $1"; +parser[0] = new RegExp("; {0,2}(BlackBird)[ _](I8.{0,200}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[63] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:BLU|Blu)[ _\\-])([^;/]+) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(BlackBird)[ _](.{0,200}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[64] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:BMOBILE )?(Blu|BLU|DASH [^;/]+|VIVO 4\\.3|TANK 4\\.5) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}([0-9]+BP[EM][^;/]*|Endeavour[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Blaupunkt $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[65] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TOUCH\\d[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}((?:BLU|Blu)[ _\\-])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[66] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(AX5\\d+) Build"); +parser[0] = new RegExp("; {0,2}(?:BMOBILE )?(Blu|BLU|DASH [^;/]{1,100}|VIVO 4\\.3|TANK 4\\.5)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[67] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([Bb]q) ([^;/]+);? Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(TOUCH\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[68] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Maxwell [^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(AX5\\d+)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[69] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:B-Tab|B-TAB) ?\\d[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}([Bb]q) ([^;/]{1,100}?);?(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[70] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Broncho) ([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(Maxwell [^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[71] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *CAPTIVA ([^;/]+) Build"); -parser[1] = "Captiva $1"; +parser[0] = new RegExp("; {0,2}((?:B-Tab|B-TAB) ?\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[72] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(C771|CAL21|IS11CA) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Broncho) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[73] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Cat|CAT) ([^;/]+) Build"); -parser[1] = "Cat $1"; +parser[0] = new RegExp("; {0,2}CAPTIVA ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Captiva $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[74] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Cat)(Nova.*) Build"); -parser[1] = "Cat $1"; +parser[0] = new RegExp("; {0,2}(C771|CAL21|IS11CA)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[75] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(INM8002KP|ADM8000KP_[AB]) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(?:Cat|CAT) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Cat $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[76] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:[Cc]elkon[ _\\*]|CELKON[ _\\*])([^;/\\)]+) ?(?:Build|;|\\))"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(?:Cat)(Nova.{0,200}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Cat $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[77] = parser; parser = Object.create(null); -parser[0] = new RegExp("Build/(?:[Cc]elkon)+_?([^;/_\\)]+)"); +parser[0] = new RegExp("; {0,2}(INM8002KP|ADM8000KP_[AB])(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[78] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(CT)-?(\\d+) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(?:[Cc]elkon[ _\\*]|CELKON[ _\\*])([^;/\\)]+) ?(?:Build|;|\\))"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[79] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A19|A19Q|A105|A107[^;/\\)]*) ?(?:Build|;|\\))"); +parser[0] = new RegExp("Build/(?:[Cc]elkon)+_?([^;/_\\)]+)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[80] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TPC[0-9]{4,5}) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(CT)-?(\\d+)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[81] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Cloudfone)[ _](Excite)([^ ][^;/]+) Build"); -parser[1] = "$1 $2 $3"; +parser[0] = new RegExp("; {0,2}(A19|A19Q|A105|A107[^;/\\)]*) ?(?:Build|;|\\))"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[82] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Excite|ICE)[ _](\\d+[^;/]+) Build"); -parser[1] = "Cloudfone $1 $2"; +parser[0] = new RegExp("; {0,2}(TPC[0-9]{4,5})(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[83] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Cloudfone|CloudPad)[ _]([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(Cloudfone)[ _](Excite)([^ ][^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[84] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:Aquila|Clanga|Rapax)[^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Excite|ICE)[ _](\\d+[^;/]{0,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Cloudfone $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[85] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:CFW-|Kyros )?(MID[0-9]{4}(?:[ABC]|SR|TV)?)(\\(3G\\)-4G| GB 8K| 3G| 8K| GB)? *(?:Build|[;\\)])"); -parser[1] = "CobyKyros $1$2"; +parser[0] = new RegExp("; {0,2}(Cloudfone|CloudPad)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[86] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([^;/]*)Coolpad[ _]([^;/]+) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}((?:Aquila|Clanga|Rapax)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[87] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(CUBE[ _])?([KU][0-9]+ ?GT.*|A5300) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(?:CFW-|Kyros )?(MID[0-9]{4}(?:[ABC]|SR|TV)?)(\\(3G\\)-4G| GB 8K| 3G| 8K| GB)? {0,2}(?:Build|[;\\)])"); +parser[1] = "CobyKyros $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[88] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *CUBOT ([^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}([^;/]{0,50})Coolpad[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[89] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(BOBBY) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(CUBE[ _])?([KU][0-9]+ ?GT.{0,200}?|A5300)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[90] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Dslide [^;/]+) Build"); +parser[0] = new RegExp("; {0,2}CUBOT ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[91] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(XCD)[ _]?(28|35) Build"); -parser[1] = "Dell $1$2"; +parser[0] = new RegExp("; {0,2}(BOBBY)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[92] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(001DL) Build"); -parser[1] = "Dell $1"; +parser[0] = new RegExp("; {0,2}(Dslide [^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[93] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Dell|DELL) (Streak) Build"); -parser[1] = "Dell $1"; +parser[0] = new RegExp("; {0,2}(XCD)[ _]?(28|35)(?: Build|\\) AppleWebKit)"); +parser[1] = "Dell $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[94] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(101DL|GS01|Streak Pro[^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(001DL)(?: Build|\\) AppleWebKit)"); parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[95] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([Ss]treak ?7) Build"); +parser[0] = new RegExp("; {0,2}(?:Dell|DELL) (Streak)(?: Build|\\) AppleWebKit)"); parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[96] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Mini-3iX) Build"); +parser[0] = new RegExp("; {0,2}(101DL|GS01|Streak Pro[^;/]{0,100})(?: Build|\\) AppleWebKit)"); parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[97] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Dell|DELL)[ _](Aero|Venue|Thunder|Mini.*|Streak[ _]Pro) Build"); +parser[0] = new RegExp("; {0,2}([Ss]treak ?7)(?: Build|\\) AppleWebKit)"); parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[98] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Dell[ _]([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(Mini-3iX)(?: Build|\\) AppleWebKit)"); parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[99] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Dell ([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(?:Dell|DELL)[ _](Aero|Venue|Thunder|Mini.{0,200}?|Streak[ _]Pro)(?: Build|\\) AppleWebKit)"); parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[100] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TA[CD]-\\d+[^;/]*) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}Dell[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[101] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(iP[789]\\d{2}(?:-3G)?|IP10\\d{2}(?:-8GB)?) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}Dell ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[102] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(AirTab)[ _\\-]([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(TA[CD]-\\d+[^;/]{0,100})(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[103] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(F\\-\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(iP[789]\\d{2}(?:-3G)?|IP10\\d{2}(?:-8GB)?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[104] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(HT-03A) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(AirTab)[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[105] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(HT\\-\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(F\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[106] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(L\\-\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(HT-03A)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[107] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(N\\-\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(HT\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[108] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(P\\-\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(L\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[109] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SC\\-\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(N\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[110] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SH\\-\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(P\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[111] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SO\\-\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(SC\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[112] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T\\-0[12][^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(SH\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[113] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(DOOV)[ _]([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(SO\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[114] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Enot|ENOT)[ -]?([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(T\\-0[12][^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[115] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *[^;/]+ Build/(?:CROSS|Cross)+[ _\\-]([^\\)]+)"); -parser[1] = "CROSS $1"; +parser[0] = new RegExp("; {0,2}(DOOV)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[116] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(CROSS|Cross)[ _\\-]([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(Enot|ENOT)[ -]?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[117] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Explay[_ ](.+?)(?:[\\)]| Build)"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}[^;/]{1,100} Build/(?:CROSS|Cross)+[ _\\-]([^\\)]+)"); +parser[1] = "CROSS $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[118] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IQ.*) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(CROSS|Cross)[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[119] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Fly|FLY)[ _](IQ[^;]+|F[34]\\d+[^;]*);? Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}Explay[_ ](.{1,200}?)(?:[\\)]| Build)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[120] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(M532|Q572|FJL21) Build/"); +parser[0] = new RegExp("; {0,2}(IQ.{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[121] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(G1) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Fly|FLY)[ _](IQ[^;]{1,100}?|F[34]\\d+[^;]{0,100}?);?(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[122] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Geeksphone) ([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(M532|Q572|FJL21)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[123] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(G[^F]?FIVE) ([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(G1)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[124] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Gionee)[ _\\-]([^;/]+)(?:/[^;/]+|) Build"); +parser[0] = new RegExp("; {0,2}(Geeksphone) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[125] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(GN\\d+[A-Z]?|INFINITY_PASSION|Ctrl_V1) Build"); -parser[1] = "Gionee $1"; +parser[0] = new RegExp("; {0,2}(G[^F]?FIVE) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[126] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(E3) Build/JOP40D"); -parser[1] = "Gionee $1"; +parser[0] = new RegExp("; {0,2}(Gionee)[ _\\-]([^;/]{1,100}?)(?:/[^;/]{1,100}|)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[127] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\sGIONEE[-\\s_](\\w*)"); +parser[0] = new RegExp("; {0,2}(GN\\d+[A-Z]?|INFINITY_PASSION|Ctrl_V1)(?: Build|\\) AppleWebKit)"); parser[1] = "Gionee $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[128] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:FONE|QUANTUM|INSIGNIA) \\d+[^;/]*|PLAYTAB) Build"); -parser[1] = "GoClever $1"; +parser[0] = new RegExp("; {0,2}(E3) Build/JOP40D"); +parser[1] = "Gionee $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[129] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *GOCLEVER ([^;/]+) Build"); -parser[1] = "GoClever $1"; +parser[0] = new RegExp("\\sGIONEE[-\\s_](\\w*)"); +parser[1] = "Gionee $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[130] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Glass \\d+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}((?:FONE|QUANTUM|INSIGNIA) \\d+[^;/]{0,100}|PLAYTAB)(?: Build|\\) AppleWebKit)"); +parser[1] = "GoClever $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[131] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Pixel.*) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}GOCLEVER ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "GoClever $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[132] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(GSmart)[ -]([^/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(Glass \\d+)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[133] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(imx5[13]_[^/]+) Build"); -parser[1] = "Freescale $1"; +parser[0] = new RegExp("; {0,2}(Pixel.{0,200}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[134] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Haier[ _\\-]([^/]+) Build"); -parser[1] = "Haier $1"; +parser[0] = new RegExp("; {0,2}(GSmart)[ -]([^/]{1,50})(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[135] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(PAD1016) Build"); -parser[1] = "Haipad $1"; +parser[0] = new RegExp("; {0,2}(imx5[13]_[^/]{1,50})(?: Build|\\) AppleWebKit)"); +parser[1] = "Freescale $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[136] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(M701|M7|M8|M9) Build"); -parser[1] = "Haipad $1"; +parser[0] = new RegExp("; {0,2}Haier[ _\\-]([^/]{1,50})(?: Build|\\) AppleWebKit)"); +parser[1] = "Haier $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[137] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SN\\d+T[^;\\)/]*)(?: Build|[;\\)])"); -parser[1] = "Hannspree $1"; +parser[0] = new RegExp("; {0,2}(PAD1016)(?: Build|\\) AppleWebKit)"); +parser[1] = "Haipad $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[138] = parser; parser = Object.create(null); -parser[0] = new RegExp("Build/HCL ME Tablet ([^;\\)]+)[\\);]"); -parser[1] = "HCLme $1"; +parser[0] = new RegExp("; {0,2}(M701|M7|M8|M9)(?: Build|\\) AppleWebKit)"); +parser[1] = "Haipad $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[139] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([^;\\/]+) Build/HCL"); -parser[1] = "HCLme $1"; +parser[0] = new RegExp("; {0,2}(SN\\d+T[^;\\)/]*)(?: Build|[;\\)])"); +parser[1] = "Hannspree $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[140] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MID-?\\d{4}C[EM]) Build"); -parser[1] = "Hena $1"; +parser[0] = new RegExp("Build/HCL ME Tablet ([^;\\)]{1,3})[\\);]"); +parser[1] = "HCLme $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[141] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(EG\\d{2,}|HS-[^;/]+|MIRA[^;/]+) Build"); -parser[1] = "Hisense $1"; +parser[0] = new RegExp("; {0,2}([^;\\/]+) Build/HCL"); +parser[1] = "HCLme $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[142] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(andromax[^;/]+) Build"); -parser[1] = "Hisense $1"; +parser[0] = new RegExp("; {0,2}(MID-?\\d{4}C[EM])(?: Build|\\) AppleWebKit)"); +parser[1] = "Hena $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[143] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:AMAZE[ _](S\\d+)|(S\\d+)[ _]AMAZE) Build"); -parser[1] = "AMAZE $1$2"; +parser[0] = new RegExp("; {0,2}(EG\\d{2,}|HS-[^;/]{1,100}|MIRA[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Hisense $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[144] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(PlayBook) Build"); -parser[1] = "HP $1"; +parser[0] = new RegExp("; {0,2}(andromax[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Hisense $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[145] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *HP ([^/]+) Build"); -parser[1] = "HP $1"; +parser[0] = new RegExp("; {0,2}(?:AMAZE[ _](S\\d+)|(S\\d+)[ _]AMAZE)(?: Build|\\) AppleWebKit)"); +parser[1] = "AMAZE $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[146] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([^/]+_tenderloin) Build"); -parser[1] = "HP TouchPad"; +parser[0] = new RegExp("; {0,2}(PlayBook)(?: Build|\\) AppleWebKit)"); +parser[1] = "HP $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[147] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(HUAWEI |Huawei-|)([UY][^;/]+) Build/(?:Huawei|HUAWEI)([UY][^\\);]+)\\)"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}HP ([^/]{1,50})(?: Build|\\) AppleWebKit)"); +parser[1] = "HP $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[148] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\\d+[^\\);]+)[^\\);]*\\)"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}([^/]{1,30}_tenderloin)(?: Build|\\) AppleWebKit)"); +parser[1] = "HP TouchPad"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[149] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(S7|M860) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(HUAWEI |Huawei-|)([UY][^;/]{1,100}) Build/(?:Huawei|HUAWEI)([UY][^\\);]+)\\)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[150] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:HUAWEI|Huawei)[ \\-]?)(MediaPad) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}([^;/]{1,100}) Build[/ ]Huawei(MT1-U06|[A-Z]{1,50}\\d+[^\\);]{1,50})\\)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[151] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:HUAWEI[ _]?|Huawei[ _]|)Ascend[ _])([^;/]+) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(S7|M860) Build"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[152] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:HUAWEI|Huawei)[ _\\-]?)((?:G700-|MT-)[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}((?:HUAWEI|Huawei)[ \\-]?)(MediaPad) Build"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[153] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:HUAWEI|Huawei)[ _\\-]?)([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}((?:HUAWEI[ _]?|Huawei[ _]|)Ascend[ _])([^;/]{1,100}) Build"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[154] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MediaPad[^;]+|SpringBoard) Build/Huawei"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}((?:HUAWEI|Huawei)[ _\\-]?)((?:G700-|MT-)[^;/]{1,100}) Build"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[155] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([^;]+) Build/(?:Huawei|HUAWEI)"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}((?:HUAWEI|Huawei)[ _\\-]?)([^;/]{1,100}) Build"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[156] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([Uu])([89]\\d{3}) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(MediaPad[^;]{1,200}|SpringBoard) Build/Huawei"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[157] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Ideos |IDEOS )(S7) Build"); -parser[1] = "Huawei Ideos$1"; +parser[0] = new RegExp("; {0,2}([^;]{1,200}) Build/(?:Huawei|HUAWEI)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[158] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Ideos |IDEOS )([^;/]+\\s*|\\s*)Build"); -parser[1] = "Huawei Ideos$1"; +parser[0] = new RegExp("; {0,2}([Uu])([89]\\d{3}) Build"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[159] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660|Nexus 6P|ATH-.+?) Build[/ ]"); -parser[1] = "Huawei $1"; +parser[0] = new RegExp("; {0,2}(?:Ideos |IDEOS )(S7) Build"); +parser[1] = "Huawei Ideos$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[160] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *HTC[ _]([^;]+); Windows Phone"); -parser[1] = "HTC $1"; +parser[0] = new RegExp("; {0,2}(?:Ideos |IDEOS )([^;/]{1,50}\\s{0,5}|\\s{0,5})Build"); +parser[1] = "Huawei Ideos$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[161] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:HTC[ _/])+([^ _/]+)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: *Build|\\))"); -parser[1] = "HTC $1"; +parser[0] = new RegExp("; {0,2}(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660|Nexus 6P|ATH-.{1,200}?) Build[/ ]"); +parser[1] = "Huawei $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[162] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: *Build|\\))"); -parser[1] = "HTC $1 $2"; +parser[0] = new RegExp("; {0,2}((?:[A-Z]{3})\\-L[A-Za0-9]{2})[\\)]"); +parser[1] = "Huawei $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[163] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)|)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: *Build|\\))"); -parser[1] = "HTC $1 $2 $3"; +parser[0] = new RegExp("; {0,2}([^;]{1,200}) Build/(HONOR|Honor)"); +parser[1] = "Huawei Honor $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[164] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)|)|)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: *Build|\\))"); -parser[1] = "HTC $1 $2 $3 $4"; +parser[0] = new RegExp("; {0,2}HTC[ _]([^;]{1,200}); Windows Phone"); +parser[1] = "HTC $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[165] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/;]+)(?: *Build|[;\\)]| - )"); +parser[0] = new RegExp("; {0,2}(?:HTC[ _/])+([^ _/]+)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: {0,2}Build|\\))"); parser[1] = "HTC $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[166] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/;\\)]+)|)(?: *Build|[;\\)]| - )"); +parser[0] = new RegExp("; {0,2}(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: {0,2}Build|\\))"); parser[1] = "HTC $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[167] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/;\\)]+)|)|)(?: *Build|[;\\)]| - )"); +parser[0] = new RegExp("; {0,2}(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)|)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: {0,2}Build|\\))"); parser[1] = "HTC $1 $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[168] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ /;]+)|)|)|)(?: *Build|[;\\)]| - )"); +parser[0] = new RegExp("; {0,2}(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)|)|)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: {0,2}Build|\\))"); parser[1] = "HTC $1 $2 $3 $4"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[169] = parser; parser = Object.create(null); -parser[0] = new RegExp("HTC Streaming Player [^\\/]*/[^\\/]*/ htc_([^/]+) /"); +parser[0] = new RegExp("; {0,2}(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/;]+)(?: {0,2}Build|[;\\)]| - )"); parser[1] = "HTC $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[170] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:[;,] *|^)(?:htccn_chs-|)HTC[ _-]?([^;]+?)(?: *Build|clay|Android|-?Mozilla| Opera| Profile| UNTRUSTED|[;/\\(\\)]|$)"); -parser[1] = "HTC $1"; +parser[0] = new RegExp("; {0,2}(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/;\\)]+)|)(?: {0,2}Build|[;\\)]| - )"); +parser[1] = "HTC $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[171] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A6277|ADR6200|ADR6300|ADR6350|ADR6400[A-Z]*|ADR6425[A-Z]*|APX515CKT|ARIA|Desire[^_ ]*|Dream|EndeavorU|Eris|Evo|Flyer|HD2|Hero|HERO200|Hero CDMA|HTL21|Incredible|Inspire[A-Z0-9]*|Legend|Liberty|Nexus ?(?:One|HD2)|One|One S C2|One[ _]?(?:S|V|X\\+?)\\w*|PC36100|PG06100|PG86100|S31HT|Sensation|Wildfire)(?: Build|[/;\\(\\)])"); -parser[1] = "HTC $1"; +parser[0] = new RegExp("; {0,2}(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/;\\)]+)|)|)(?: {0,2}Build|[;\\)]| - )"); +parser[1] = "HTC $1 $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[172] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ADR6200|ADR6400L|ADR6425LVW|Amaze|DesireS?|EndeavorU|Eris|EVO|Evo\\d[A-Z]+|HD2|IncredibleS?|Inspire[A-Z0-9]*|Inspire[A-Z0-9]*|Sensation[A-Z0-9]*|Wildfire)[ _-](.+?)(?:[/;\\)]|Build|MIUI|1\\.0)"); -parser[1] = "HTC $1 $2"; +parser[0] = new RegExp("; {0,2}(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ /;]+)|)|)|)(?: {0,2}Build|[;\\)]| - )"); +parser[1] = "HTC $1 $2 $3 $4"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[173] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *HYUNDAI (T\\d[^/]*) Build"); -parser[1] = "Hyundai $1"; +parser[0] = new RegExp("HTC Streaming Player [^\\/]{0,30}/[^\\/]{0,10}/ htc_([^/]{1,10}) /"); +parser[1] = "HTC $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[174] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *HYUNDAI ([^;/]+) Build"); -parser[1] = "Hyundai $1"; +parser[0] = new RegExp("(?:[;,] {0,2}|^)(?:htccn_chs-|)HTC[ _-]?([^;]{1,200}?)(?: {0,2}Build|clay|Android|-?Mozilla| Opera| Profile| UNTRUSTED|[;/\\(\\)]|$)"); +parser[1] = "HTC $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[175] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(X700|Hold X|MB-6900) Build"); -parser[1] = "Hyundai $1"; +parser[0] = new RegExp("; {0,2}(A6277|ADR6200|ADR6300|ADR6350|ADR6400[A-Z]*|ADR6425[A-Z]*|APX515CKT|ARIA|Desire[^_ ]*|Dream|EndeavorU|Eris|Evo|Flyer|HD2|Hero|HERO200|Hero CDMA|HTL21|Incredible|Inspire[A-Z0-9]*|Legend|Liberty|Nexus ?(?:One|HD2)|One|One S C2|One[ _]?(?:S|V|X\\+?)\\w*|PC36100|PG06100|PG86100|S31HT|Sensation|Wildfire)(?: Build|[/;\\(\\)])"); +parser[1] = "HTC $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[176] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:iBall[ _\\-]|)(Andi)[ _]?(\\d[^;/]*) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(ADR6200|ADR6400L|ADR6425LVW|Amaze|DesireS?|EndeavorU|Eris|EVO|Evo\\d[A-Z]+|HD2|IncredibleS?|Inspire[A-Z0-9]*|Inspire[A-Z0-9]*|Sensation[A-Z0-9]*|Wildfire)[ _-](.{1,200}?)(?:[/;\\)]|Build|MIUI|1\\.0)"); +parser[1] = "HTC $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[177] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IBall)(?:[ _]([^;/]+)|) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}HYUNDAI (T\\d[^/]{0,10})(?: Build|\\) AppleWebKit)"); +parser[1] = "Hyundai $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[178] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(NT-\\d+[^ ;/]*|Net[Tt]AB [^;/]+|Mercury [A-Z]+|iconBIT)(?: S/N:[^;/]+|) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}HYUNDAI ([^;/]{1,10}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Hyundai $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[179] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IMO)[ _]([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(X700|Hold X|MB-6900)(?: Build|\\) AppleWebKit)"); +parser[1] = "Hyundai $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[180] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *i-?mobile[ _]([^/]+) Build/"); -parser[1] = "i-mobile $1"; +parser[0] = new RegExp("; {0,2}(?:iBall[ _\\-]|)(Andi)[ _]?(\\d[^;/]*)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[181] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(i-(?:style|note)[^/]*) Build/"); -parser[1] = "i-mobile $1"; +parser[0] = new RegExp("; {0,2}(IBall)(?:[ _]([^;/]{1,100}?)|)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[182] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ImPAD) ?(\\d+(?:.)*) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(NT-\\d+[^ ;/]{0,50}|Net[Tt]AB [^;/]{1,50}|Mercury [A-Z]{1,50}|iconBIT)(?: S/N:[^;/]{1,50}|)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[183] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Infinix)[ _]([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(IMO)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[184] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Informer)[ \\-]([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}i-?mobile[ _]([^/]{1,50})(?: Build|\\) AppleWebKit)"); +parser[1] = "i-mobile $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[185] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TAB) ?([78][12]4) Build"); -parser[1] = "Intenso $1"; +parser[0] = new RegExp("; {0,2}(i-(?:style|note)[^/]{0,10})(?: Build|\\) AppleWebKit)"); +parser[1] = "i-mobile $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[186] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Intex[ _]|)(AQUA|Aqua)([ _\\.\\-])([^;/]+) *(?:Build|;)"); -parser[1] = "$1$2$3"; +parser[0] = new RegExp("; {0,2}(ImPAD) ?(\\d+(?:.){0,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[187] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:INTEX|Intex)(?:[_ ]([^\\ _;/]+))(?:[_ ]([^\\ _;/]+)|) *(?:Build|;)"); +parser[0] = new RegExp("; {0,2}(Infinix)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[188] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([iI]Buddy)[ _]?(Connect)(?:_|\\?_| |)([^;/]*) *(?:Build|;)"); -parser[1] = "$1 $2 $3"; +parser[0] = new RegExp("; {0,2}(Informer)[ \\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[189] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(I-Buddy)[ _]([^;/]+) *(?:Build|;)"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(TAB) ?([78][12]4)(?: Build|\\) AppleWebKit)"); +parser[1] = "Intenso $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[190] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(iOCEAN) ([^/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(?:Intex[ _]|)(AQUA|Aqua)([ _\\.\\-])([^;/]{1,100}?) {0,2}(?:Build|;)"); +parser[1] = "$1$2$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[191] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TP\\d+(?:\\.\\d+|)\\-\\d[^;/]+) Build"); -parser[1] = "ionik $1"; +parser[0] = new RegExp("; {0,2}(?:INTEX|Intex)(?:[_ ]([^\\ _;/]+))(?:[_ ]([^\\ _;/]+)|) {0,2}(?:Build|;)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[192] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(M702pro) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}([iI]Buddy)[ _]?(Connect)(?:_|\\?_| |)([^;/]{0,50}) {0,2}(?:Build|;)"); +parser[1] = "$1 $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[193] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(DE88Plus|MD70) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(I-Buddy)[ _]([^;/]{1,100}?) {0,2}(?:Build|;)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[194] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *IVIO[_\\-]([^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(iOCEAN) ([^/]{1,50})(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[195] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TPC-\\d+|JAY-TECH) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(TP\\d+(?:\\.\\d+|)\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "ionik $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[196] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(JY-[^;/]+|G[234]S?) Build"); +parser[0] = new RegExp("; {0,2}(M702pro)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[197] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(JXD)[ _\\-]([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}itel ([^;/]*)(?: Build|\\) AppleWebKit)"); +parser[1] = "Itel $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[198] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Karbonn[ _]?([^;/]+) *(?:Build|;)"); +parser[0] = new RegExp("; {0,2}(DE88Plus|MD70)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[199] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([^;]+) Build/Karbonn"); +parser[0] = new RegExp("; {0,2}IVIO[_\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[200] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A11|A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2|Titanium S\\d) +Build"); +parser[0] = new RegExp("; {0,2}(TPC-\\d+|JAY-TECH)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[201] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS01|IS03|IS05|IS\\d{2}SH) Build"); +parser[0] = new RegExp("; {0,2}(JY-[^;/]{1,100}|G[234]S?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[202] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS04) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(JXD)[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[203] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS06|IS\\d{2}PT) Build"); +parser[0] = new RegExp("; {0,2}Karbonn[ _]?([^;/]{1,100}) {0,2}(?:Build|;)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[204] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS11S) Build"); +parser[0] = new RegExp("; {0,2}([^;]{1,200}) Build/Karbonn"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[205] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS11CA) Build"); +parser[0] = new RegExp("; {0,2}(A11|A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2|Titanium S\\d) +Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[206] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS11LG) Build"); +parser[0] = new RegExp("; {0,2}(IS01|IS03|IS05|IS\\d{2}SH)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[207] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS11N) Build"); +parser[0] = new RegExp("; {0,2}(IS04)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[208] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS11PT) Build"); +parser[0] = new RegExp("; {0,2}(IS06|IS\\d{2}PT)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[209] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS12F) Build"); +parser[0] = new RegExp("; {0,2}(IS11S)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[210] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS12M) Build"); +parser[0] = new RegExp("; {0,2}(IS11CA)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[211] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IS12S) Build"); +parser[0] = new RegExp("; {0,2}(IS11LG)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[212] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ISW11F) Build"); +parser[0] = new RegExp("; {0,2}(IS11N)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[213] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ISW11HT) Build"); +parser[0] = new RegExp("; {0,2}(IS11PT)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[214] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ISW11K) Build"); +parser[0] = new RegExp("; {0,2}(IS12F)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[215] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ISW11M) Build"); +parser[0] = new RegExp("; {0,2}(IS12M)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[216] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ISW11SC) Build"); +parser[0] = new RegExp("; {0,2}(IS12S)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[217] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ISW12HT) Build"); +parser[0] = new RegExp("; {0,2}(ISW11F)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[218] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ISW13HT) Build"); +parser[0] = new RegExp("; {0,2}(ISW11HT)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[219] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ISW?[0-9]{2}[A-Z]{0,2}) Build"); +parser[0] = new RegExp("; {0,2}(ISW11K)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[220] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(INFOBAR [^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(ISW11M)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[221] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(JOYPAD|Joypad)[ _]([^;/]+) Build/"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(ISW11SC)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[222] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Vox|VOX|Arc|K080) Build/"); +parser[0] = new RegExp("; {0,2}(ISW12HT)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[223] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\b(Kobo Touch)\\b"); +parser[0] = new RegExp("; {0,2}(ISW13HT)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[224] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(K-Touch)[ _]([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(ISW?[0-9]{2}[A-Z]{0,2})(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[225] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:EV|KM)-S\\d+[A-Z]?) Build"); +parser[0] = new RegExp("; {0,2}(INFOBAR [^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[226] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Zio|Hydro|Torque|Event|EVENT|Echo|Milano|Rise|URBANO PROGRESSO|WX04K|WX06K|WX10K|KYL21|101K|C5[12]\\d{2}) Build/"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(JOYPAD|Joypad)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[227] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:LAVA[ _]|)IRIS[ _\\-]?([^/;\\)]+) *(?:;|\\)|Build)"); -parser[1] = "Iris $1"; +parser[0] = new RegExp("; {0,2}(Vox|VOX|Arc|K080)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[228] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *LAVA[ _]([^;/]+) Build"); +parser[0] = new RegExp("\\b(Kobo Touch)\\b"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[229] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:(Aspire A1)|(?:LEMON|Lemon)[ _]([^;/]+))_? Build"); -parser[1] = "Lemon $1$2"; +parser[0] = new RegExp("; {0,2}(K-Touch)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[230] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TAB-1012) Build/"); -parser[1] = "Lenco $1"; +parser[0] = new RegExp("; {0,2}((?:EV|KM)-S\\d+[A-Z]?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[231] = parser; parser = Object.create(null); -parser[0] = new RegExp("; Lenco ([^;/]+) Build/"); -parser[1] = "Lenco $1"; +parser[0] = new RegExp("; {0,2}(Zio|Hydro|Torque|Event|EVENT|Echo|Milano|Rise|URBANO PROGRESSO|WX04K|WX06K|WX10K|KYL21|101K|C5[12]\\d{2})(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[232] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A1_07|A2107A-H|S2005A-H|S1-37AH0) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(?:LAVA[ _]|)IRIS[ _\\-]?([^/;\\)]+) {0,2}(?:;|\\)|Build)"); +parser[1] = "Iris $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[233] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Idea[Tp]ab)[ _]([^;/]+);? Build"); -parser[1] = "Lenovo $1 $2"; +parser[0] = new RegExp("; {0,2}LAVA[ _]([^;/]{1,100}) Build"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[234] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Idea(?:Tab|pad)) ?([^;/]+) Build"); -parser[1] = "Lenovo $1 $2"; +parser[0] = new RegExp("; {0,2}(?:(Aspire A1)|(?:LEMON|Lemon)[ _]([^;/]{1,100}))_?(?: Build|\\) AppleWebKit)"); +parser[1] = "Lemon $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[235] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ThinkPad) ?(Tablet) Build/"); -parser[1] = "Lenovo $1 $2"; +parser[0] = new RegExp("; {0,2}(TAB-1012)(?: Build|\\) AppleWebKit)"); +parser[1] = "Lenco $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[236] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:LNV-|)(?:=?[Ll]enovo[ _\\-]?|LENOVO[ _])(.+?)(?:Build|[;/\\)])"); -parser[1] = "Lenovo $1"; +parser[0] = new RegExp("; Lenco ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Lenco $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[237] = parser; parser = Object.create(null); -parser[0] = new RegExp("[;,] (?:Vodafone |)(SmartTab) ?(II) ?(\\d+) Build/"); -parser[1] = "Lenovo $1 $2 $3"; +parser[0] = new RegExp("; {0,2}(A1_07|A2107A-H|S2005A-H|S1-37AH0) Build"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[238] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Ideapad |)K1 Build/"); -parser[1] = "Lenovo Ideapad K1"; +parser[0] = new RegExp("; {0,2}(Idea[Tp]ab)[ _]([^;/]{1,100});? Build"); +parser[1] = "Lenovo $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[239] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(3GC101|3GW10[01]|A390) Build/"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Idea(?:Tab|pad)) ?([^;/]{1,100}) Build"); +parser[1] = "Lenovo $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[240] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\b(?:Lenovo|LENOVO)+[ _\\-]?([^,;:/ ]+)"); -parser[1] = "Lenovo $1"; +parser[0] = new RegExp("; {0,2}(ThinkPad) ?(Tablet) Build/"); +parser[1] = "Lenovo $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[241] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MFC\\d+)[A-Z]{2}([^;,/]*),? Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(?:LNV-|)(?:=?[Ll]enovo[ _\\-]?|LENOVO[ _])(.{1,200}?)(?:Build|[;/\\)])"); +parser[1] = "Lenovo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[242] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(E[34][0-9]{2}|LS[6-8][0-9]{2}|VS[6-9][0-9]+[^;/]+|Nexus 4|Nexus 5X?|GT540f?|Optimus (?:2X|G|4X HD)|OptimusX4HD) *(?:Build|;)"); -parser[1] = "$1"; +parser[0] = new RegExp("[;,] (?:Vodafone |)(SmartTab) ?(II) ?(\\d+) Build/"); +parser[1] = "Lenovo $1 $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[243] = parser; parser = Object.create(null); -parser[0] = new RegExp("[;:] *(L-\\d+[A-Z]|LGL\\d+[A-Z]?)(?:/V\\d+|) *(?:Build|[;\\)])"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(?:Ideapad |)K1 Build/"); +parser[1] = "Lenovo Ideapad K1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[244] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(LG-)([A-Z]{1,2}\\d{2,}[^,;/\\)\\(]*?)(?:Build| V\\d+|[,;/\\)\\(]|$)"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(3GC101|3GW10[01]|A390) Build/"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[245] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(LG[ \\-]|LG)([^;/]+)[;/]? Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("\\b(?:Lenovo|LENOVO)+[ _\\-]?([^,;:/ ]+)"); +parser[1] = "Lenovo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[246] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(LG)-([^;/]+)/ Mozilla/.*; Android"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(MFC\\d+)[A-Z]{2}([^;,/]*),?(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[247] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Web0S); Linux/(SmartTV)"); -parser[1] = "LG $1 $2"; +parser[0] = new RegExp("; {0,2}(E[34][0-9]{2}|LS[6-8][0-9]{2}|VS[6-9][0-9]+[^;/]{1,30}|Nexus 4|Nexus 5X?|GT540f?|Optimus (?:2X|G|4X HD)|OptimusX4HD) {0,2}(?:Build|;)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[248] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:SMB|smb)[^;/]+) Build/"); +parser[0] = new RegExp("[;:] {0,2}(L-\\d+[A-Z]|LGL\\d+[A-Z]?)(?:/V\\d+|) {0,2}(?:Build|[;\\)])"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[249] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Malata|MALATA) ([^;/]+) Build/"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(LG-)([A-Z]{1,2}\\d{2,}[^,;/\\)\\(]*?)(?:Build| V\\d+|[,;/\\)\\(]|$)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[250] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MS[45][0-9]{3}|MID0[568][NS]?|MID[1-9]|MID[78]0[1-9]|MID970[1-9]|MID100[1-9]) Build/"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(LG[ \\-]|LG)([^;/]{1,100})[;/]? Build"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[251] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(M1052|M806|M9000|M9100|M9701|MID100|MID120|MID125|MID130|MID135|MID140|MID701|MID710|MID713|MID727|MID728|MID731|MID732|MID733|MID735|MID736|MID737|MID760|MID800|MID810|MID820|MID830|MID833|MID835|MID860|MID900|MID930|MID933|MID960|MID980) Build/"); -parser[1] = "$1"; +parser[0] = new RegExp("^(LG)-([^;/]{1,100})/ Mozilla/.{0,200}; Android"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[252] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(GenxDroid7|MSD7.*|AX\\d.*|Tab 701|Tab 722) Build/"); -parser[1] = "Maxx $1"; +parser[0] = new RegExp("(Web0S); Linux/(SmartTV)"); +parser[1] = "LG $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[253] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(M-PP[^;/]+|PhonePad ?\\d{2,}[^;/]+) Build"); -parser[1] = "Mediacom $1"; +parser[0] = new RegExp("; {0,2}((?:SMB|smb)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[254] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(M-MP[^;/]+|SmartPad ?\\d{2,}[^;/]+) Build"); -parser[1] = "Mediacom $1"; +parser[0] = new RegExp("; {0,2}(?:Malata|MALATA) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[255] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:MD_|)LIFETAB[ _]([^;/]+) Build"); -parser[1] = "Medion Lifetab $1"; +parser[0] = new RegExp("; {0,2}(MS[45][0-9]{3}|MID0[568][NS]?|MID[1-9]|MID[78]0[1-9]|MID970[1-9]|MID100[1-9])(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[256] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *MEDION ([^;/]+) Build"); -parser[1] = "Medion $1"; +parser[0] = new RegExp("; {0,2}(M1052|M806|M9000|M9100|M9701|MID100|MID120|MID125|MID130|MID135|MID140|MID701|MID710|MID713|MID727|MID728|MID731|MID732|MID733|MID735|MID736|MID737|MID760|MID800|MID810|MID820|MID830|MID833|MID835|MID860|MID900|MID930|MID933|MID960|MID980)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[257] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(M030|M031|M035|M040|M065|m9) Build"); -parser[1] = "Meizu $1"; +parser[0] = new RegExp("; {0,2}(GenxDroid7|MSD7.{0,200}?|AX\\d.{0,200}?|Tab 701|Tab 722)(?: Build|\\) AppleWebKit)"); +parser[1] = "Maxx $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[258] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:meizu_|MEIZU )(.+?) *(?:Build|[;\\)])"); -parser[1] = "Meizu $1"; +parser[0] = new RegExp("; {0,2}(M-PP[^;/]{1,30}|PhonePad ?\\d{2,}[^;/]{1,30}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Mediacom $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[259] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Micromax[ _](A111|A240)|(A111|A240)) Build"); -parser[1] = "Micromax $1$2"; +parser[0] = new RegExp("; {0,2}(M-MP[^;/]{1,30}|SmartPad ?\\d{2,}[^;/]{1,30}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Mediacom $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[260] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Micromax[ _](A\\d{2,3}[^;/]*) Build"); -parser[1] = "Micromax $1"; +parser[0] = new RegExp("; {0,2}(?:MD_|)LIFETAB[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Medion Lifetab $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[261] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A\\d{2}|A[12]\\d{2}|A90S|A110Q) Build"); -parser[1] = "Micromax $1"; +parser[0] = new RegExp("; {0,2}MEDION ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Medion $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[262] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Micromax[ _](P\\d{3}[^;/]*) Build"); -parser[1] = "Micromax $1"; +parser[0] = new RegExp("; {0,2}(M030|M031|M035|M040|M065|m9)(?: Build|\\) AppleWebKit)"); +parser[1] = "Meizu $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[263] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(P\\d{3}|P\\d{3}\\(Funbook\\)) Build"); -parser[1] = "Micromax $1"; +parser[0] = new RegExp("; {0,2}(?:meizu_|MEIZU )(.{1,200}?) {0,2}(?:Build|[;\\)])"); +parser[1] = "Meizu $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[264] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MITO)[ _\\-]?([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}(?:Micromax[ _](A111|A240)|(A111|A240)) Build"); +parser[1] = "Micromax $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[265] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Cynus)[ _](F5|T\\d|.+?) *(?:Build|[;/\\)])"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}Micromax[ _](A\\d{2,3}[^;/]*) Build"); +parser[1] = "Micromax $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[266] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MODECOM |)(FreeTab) ?([^;/]+) Build"); -parser[1] = "$1$2 $3"; +parser[0] = new RegExp("; {0,2}(A\\d{2}|A[12]\\d{2}|A90S|A110Q) Build"); +parser[1] = "Micromax $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[267] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MODECOM )([^;/]+) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}Micromax[ _](P\\d{3}[^;/]*) Build"); +parser[1] = "Micromax $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[268] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MZ\\d{3}\\+?|MZ\\d{3} 4G|Xoom|XOOM[^;/]*) Build"); -parser[1] = "Motorola $1"; +parser[0] = new RegExp("; {0,2}(P\\d{3}|P\\d{3}\\(Funbook\\)) Build"); +parser[1] = "Micromax $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[269] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Milestone )(XT[^;/]*) Build"); -parser[1] = "Motorola $1$2"; +parser[0] = new RegExp("; {0,2}(MITO)[ _\\-]?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[270] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Motoroi ?x|Droid X|DROIDX) Build"); -parser[1] = "Motorola $1"; +parser[0] = new RegExp("; {0,2}(Cynus)[ _](F5|T\\d|.{1,200}?) {0,2}(?:Build|[;/\\)])"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[271] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Droid[^;/]*|DROID[^;/]*|Milestone[^;/]*|Photon|Triumph|Devour|Titanium) Build"); -parser[1] = "Motorola $1"; +parser[0] = new RegExp("; {0,2}(MODECOM |)(FreeTab) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[272] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A555|A85[34][^;/]*|A95[356]|ME[58]\\d{2}\\+?|ME600|ME632|ME722|MB\\d{3}\\+?|MT680|MT710|MT870|MT887|MT917|WX435|WX453|WX44[25]|XT\\d{3,4}[A-Z\\+]*|CL[iI]Q|CL[iI]Q XT) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(MODECOM )([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[273] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Motorola MOT-|Motorola[ _\\-]|MOT\\-?)([^;/]+) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(MZ\\d{3}\\+?|MZ\\d{3} 4G|Xoom|XOOM[^;/]*) Build"); +parser[1] = "Motorola $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[274] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Moto[_ ]?|MOT\\-)([^;/]+) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(Milestone )(XT[^;/]*) Build"); +parser[1] = "Motorola $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[275] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:MP[DQ]C|MPG\\d{1,4}|MP\\d{3,4}|MID(?:(?:10[234]|114|43|7[247]|8[24]|7)C|8[01]1))[^;/]*) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Motoroi ?x|Droid X|DROIDX) Build"); +parser[1] = "Motorola $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[276] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:MSI[ _]|)(Primo\\d+|Enjoy[ _\\-][^;/]+) Build"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(Droid[^;/]*|DROID[^;/]*|Milestone[^;/]*|Photon|Triumph|Devour|Titanium) Build"); +parser[1] = "Motorola $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[277] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Multilaser[ _]([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(A555|A85[34][^;/]*|A95[356]|ME[58]\\d{2}\\+?|ME600|ME632|ME722|MB\\d{3}\\+?|MT680|MT710|MT870|MT887|MT917|WX435|WX453|WX44[25]|XT\\d{3,4}[A-Z\\+]*|CL[iI]Q|CL[iI]Q XT) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[278] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(My)[_]?(Pad)[ _]([^;/]+) Build"); -parser[1] = "$1$2 $3"; +parser[0] = new RegExp("; {0,2}(Motorola MOT-|Motorola[ _\\-]|MOT\\-?)([^;/]{1,100}) Build"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[279] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(My)\\|?(Phone)[ _]([^;/]+) Build"); -parser[1] = "$1$2 $3"; +parser[0] = new RegExp("; {0,2}(Moto[_ ]?|MOT\\-)([^;/]{1,100}) Build"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[280] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A\\d+)[ _](Duo|) Build"); -parser[1] = "$1 $2"; +parser[0] = new RegExp("; {0,2}((?:MP[DQ]C|MPG\\d{1,4}|MP\\d{3,4}|MID(?:(?:10[234]|114|43|7[247]|8[24]|7)C|8[01]1))[^;/]*)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[281] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(myTab[^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(?:MSI[ _]|)(Primo\\d+|Enjoy[ _\\-][^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[282] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(NABI2?-)([^;/]+) Build/"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}Multilaser[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[283] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(N-\\d+[CDE]) Build/"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(My)[_]?(Pad)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[284] = parser; parser = Object.create(null); -parser[0] = new RegExp("; ?(NEC-)(.*) Build/"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(My)\\|?(Phone)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[285] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(LT-NA7) Build/"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(A\\d+)[ _](Duo|)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[286] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(NXM\\d+[A-z0-9_]*|Next\\d[A-z0-9_ \\-]*|NEXT\\d[A-z0-9_ \\-]*|Nextbook [A-z0-9_ ]*|DATAM803HC|M805)(?: Build|[\\);])"); +parser[0] = new RegExp("; {0,2}(myTab[^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[287] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Nokia)([ _\\-]*)([^;/]*) Build"); -parser[1] = "$1$2$3"; +parser[0] = new RegExp("; {0,2}(NABI2?-)([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[288] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Nook ?|Barnes & Noble Nook |BN )([^;/]+) Build"); -parser[1] = "$1$2"; +parser[0] = new RegExp("; {0,2}(N-\\d+[CDE])(?: Build|\\) AppleWebKit)"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[289] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(NOOK |)(BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2) Build"); +parser[0] = new RegExp("; ?(NEC-)(.{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[290] = parser; parser = Object.create(null); -parser[0] = new RegExp("; Build/(Nook)"); +parser[0] = new RegExp("; {0,2}(LT-NA7)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[291] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(OP110|OliPad[^;/]+) Build"); -parser[1] = "Olivetti $1"; +parser[0] = new RegExp("; {0,2}(NXM\\d+[A-Za-z0-9_]{0,50}|Next\\d[A-Za-z0-9_ \\-]{0,50}|NEXT\\d[A-Za-z0-9_ \\-]{0,50}|Nextbook [A-Za-z0-9_ ]{0,50}|DATAM803HC|M805)(?: Build|[\\);])"); +parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[292] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *OMEGA[ _\\-](MID[^;/]+) Build"); -parser[1] = "Omega $1"; +parser[0] = new RegExp("; {0,2}(Nokia)([ _\\-]{0,5})([^;/]{0,50}) Build"); +parser[1] = "$1$2$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.device[293] = parser; parser = Object.create(null); +parser[0] = new RegExp("; {0,2}(TA\\-\\d{4})(?: Build|\\) AppleWebKit)"); +parser[1] = "Nokia $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[294] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}(Nook ?|Barnes & Noble Nook |BN )([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[295] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}(NOOK |)(BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2)(?: Build|\\) AppleWebKit)"); +parser[1] = "$1$2"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[296] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; Build/(Nook)"); +parser[1] = "$1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[297] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}(OP110|OliPad[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Olivetti $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[298] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}OMEGA[ _\\-](MID[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Omega $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[299] = parser; +parser = Object.create(null); parser[0] = new RegExp("^(MID7500|MID\\d+) Mozilla/5\\.0 \\(iPad;"); parser[1] = "Omega $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[294] = parser; +exports.device[300] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:CIUS|cius)[^;/]*) Build"); +parser[0] = new RegExp("; {0,2}((?:CIUS|cius)[^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "Openpeak $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[295] = parser; +exports.device[301] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Find ?(?:5|7a)|R8[012]\\d{1,2}|T703\\d{0,1}|U70\\d{1,2}T?|X90\\d{1,2}) Build"); +parser[0] = new RegExp("; {0,2}(Find ?(?:5|7a)|R8[012]\\d{1,2}|T703\\d?|U70\\d{1,2}T?|X90\\d{1,2}|[AFR]\\d{1,2}[a-z]{1,2})(?: Build|\\) AppleWebKit)"); parser[1] = "Oppo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[296] = parser; +exports.device[302] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *OPPO ?([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}OPPO ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Oppo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[297] = parser; +exports.device[303] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}(CPH\\d{1,4}|RMX\\d{1,4}|P[A-Z]{3}\\d{2})(?: Build|\\) AppleWebKit)"); +parser[1] = "Oppo $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[304] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}(A1601)(?: Build|\\) AppleWebKit)"); +parser[1] = "Oppo F1s"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[305] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Odys\\-|ODYS\\-|ODYS )([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(?:Odys\\-|ODYS\\-|ODYS )([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Odys $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[298] = parser; +exports.device[306] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SELECT) ?(7) Build"); +parser[0] = new RegExp("; {0,2}(SELECT) ?(7)(?: Build|\\) AppleWebKit)"); parser[1] = "Odys $1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[299] = parser; +exports.device[307] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(PEDI)_(PLUS)_(W) Build"); +parser[0] = new RegExp("; {0,2}(PEDI)_(PLUS)_(W)(?: Build|\\) AppleWebKit)"); parser[1] = "Odys $1 $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[300] = parser; +exports.device[308] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(AEON|BRAVIO|FUSION|FUSION2IN1|Genio|EOS10|IEOS[^;/]*|IRON|Loox|LOOX|LOOX Plus|Motion|NOON|NOON_PRO|NEXT|OPOS|PEDI[^;/]*|PRIME[^;/]*|STUDYTAB|TABLO|Tablet-PC-4|UNO_X8|XELIO[^;/]*|Xelio ?\\d+ ?[Pp]ro|XENO10|XPRESS PRO) Build"); +parser[0] = new RegExp("; {0,2}(AEON|BRAVIO|FUSION|FUSION2IN1|Genio|EOS10|IEOS[^;/]*|IRON|Loox|LOOX|LOOX Plus|Motion|NOON|NOON_PRO|NEXT|OPOS|PEDI[^;/]*|PRIME[^;/]*|STUDYTAB|TABLO|Tablet-PC-4|UNO_X8|XELIO[^;/]*|Xelio ?\\d+ ?[Pp]ro|XENO10|XPRESS PRO)(?: Build|\\) AppleWebKit)"); parser[1] = "Odys $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[301] = parser; +exports.device[309] = parser; parser = Object.create(null); -parser[0] = new RegExp("; (ONE [a-zA-Z]\\d+) Build/"); +parser[0] = new RegExp("; (ONE [a-zA-Z]\\d+)(?: Build|\\) AppleWebKit)"); parser[1] = "OnePlus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[302] = parser; +exports.device[310] = parser; parser = Object.create(null); -parser[0] = new RegExp("; (ONEPLUS [a-zA-Z]\\d+) Build/"); +parser[0] = new RegExp("; (ONEPLUS [a-zA-Z]\\d+)(?: Build|\\) AppleWebKit)"); parser[1] = "OnePlus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[303] = parser; +exports.device[311] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TP-\\d+) Build/"); +parser[0] = new RegExp("; {0,2}(TP-\\d+)(?: Build|\\) AppleWebKit)"); parser[1] = "Orion $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[304] = parser; +exports.device[312] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(G100W?) Build/"); +parser[0] = new RegExp("; {0,2}(G100W?)(?: Build|\\) AppleWebKit)"); parser[1] = "PackardBell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[305] = parser; +exports.device[313] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Panasonic)[_ ]([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(Panasonic)[_ ]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[306] = parser; +exports.device[314] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(FZ-A1B|JT-B1) Build"); +parser[0] = new RegExp("; {0,2}(FZ-A1B|JT-B1)(?: Build|\\) AppleWebKit)"); parser[1] = "Panasonic $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[307] = parser; +exports.device[315] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(dL1|DL1) Build"); +parser[0] = new RegExp("; {0,2}(dL1|DL1)(?: Build|\\) AppleWebKit)"); parser[1] = "Panasonic $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[308] = parser; +exports.device[316] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SKY[ _]|)(IM\\-[AT]\\d{3}[^;/]+).* Build/"); +parser[0] = new RegExp("; {0,2}(SKY[ _]|)(IM\\-[AT]\\d{3}[^;/]{1,100}).{0,30} Build/"); parser[1] = "Pantech $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[309] = parser; +exports.device[317] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:ADR8995|ADR910L|ADR930L|ADR930VW|PTL21|P8000)(?: 4G|)) Build/"); +parser[0] = new RegExp("; {0,2}((?:ADR8995|ADR910L|ADR930L|ADR930VW|PTL21|P8000)(?: 4G|)) Build/"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[310] = parser; +exports.device[318] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Pantech([^;/]+).* Build/"); +parser[0] = new RegExp("; {0,2}Pantech([^;/]{1,30}).{0,200}? Build/"); parser[1] = "Pantech $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[311] = parser; +exports.device[319] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(papyre)[ _\\-]([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(papyre)[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[312] = parser; +exports.device[320] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Touchlet )?(X10\\.[^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(?:Touchlet )?(X10\\.[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Pearl $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[313] = parser; +exports.device[321] = parser; parser = Object.create(null); -parser[0] = new RegExp("; PHICOMM (i800) Build/"); +parser[0] = new RegExp("; PHICOMM (i800)(?: Build|\\) AppleWebKit)"); parser[1] = "Phicomm $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[314] = parser; +exports.device[322] = parser; parser = Object.create(null); -parser[0] = new RegExp("; PHICOMM ([^;/]+) Build/"); +parser[0] = new RegExp("; PHICOMM ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Phicomm $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[315] = parser; +exports.device[323] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(FWS\\d{3}[^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(FWS\\d{3}[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Phicomm $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[316] = parser; +exports.device[324] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(D633|D822|D833|T539|T939|V726|W335|W336|W337|W3568|W536|W5510|W626|W632|W6350|W6360|W6500|W732|W736|W737|W7376|W820|W832|W8355|W8500|W8510|W930) Build"); +parser[0] = new RegExp("; {0,2}(D633|D822|D833|T539|T939|V726|W335|W336|W337|W3568|W536|W5510|W626|W632|W6350|W6360|W6500|W732|W736|W737|W7376|W820|W832|W8355|W8500|W8510|W930)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[317] = parser; +exports.device[325] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Philips|PHILIPS)[ _]([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(?:Philips|PHILIPS)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Philips $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[318] = parser; +exports.device[326] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android 4\\..*; *(M[12356789]|U[12368]|S[123])\\ ?(pro)? Build"); +parser[0] = new RegExp("Android 4\\..{0,200}; {0,2}(M[12356789]|U[12368]|S[123])\\ ?(pro)?(?: Build|\\) AppleWebKit)"); parser[1] = "Pipo $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[319] = parser; +exports.device[327] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MOMO[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(MOMO[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[320] = parser; +exports.device[328] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Polaroid[ _]|)((?:MIDC\\d{3,}|PMID\\d{2,}|PTAB\\d{3,})[^;/]*)(\\/[^;/]*|) Build/"); +parser[0] = new RegExp("; {0,2}(?:Polaroid[ _]|)((?:MIDC\\d{3,}|PMID\\d{2,}|PTAB\\d{3,})[^;/]{0,30}?)(\\/[^;/]{0,30}|)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[321] = parser; +exports.device[329] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Polaroid )(Tablet) Build/"); +parser[0] = new RegExp("; {0,2}(?:Polaroid )(Tablet)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[322] = parser; +exports.device[330] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(POMP)[ _\\-](.+?) *(?:Build|[;/\\)])"); +parser[0] = new RegExp("; {0,2}(POMP)[ _\\-](.{1,200}?) {0,2}(?:Build|[;/\\)])"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[323] = parser; +exports.device[331] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TB07STA|TB10STA|TB07FTA|TB10FTA) Build/"); +parser[0] = new RegExp("; {0,2}(TB07STA|TB10STA|TB07FTA|TB10FTA)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[324] = parser; +exports.device[332] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Positivo |)((?:YPY|Ypy)[^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(?:Positivo |)((?:YPY|Ypy)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[325] = parser; +exports.device[333] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(MOB-[^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(MOB-[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[326] = parser; +exports.device[334] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *POV[ _\\-]([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}POV[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "POV $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[327] = parser; +exports.device[335] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:TAB-PLAYTAB|TAB-PROTAB|PROTAB|PlayTabPro|Mobii[ _\\-]|TAB-P)[^;/]*) Build/"); +parser[0] = new RegExp("; {0,2}((?:TAB-PLAYTAB|TAB-PROTAB|PROTAB|PlayTabPro|Mobii[ _\\-]|TAB-P)[^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "POV $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[328] = parser; +exports.device[336] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Prestigio |)((?:PAP|PMP)\\d[^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(?:Prestigio |)((?:PAP|PMP)\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Prestigio $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[329] = parser; +exports.device[337] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(PLT[0-9]{4}.*) Build/"); +parser[0] = new RegExp("; {0,2}(PLT[0-9]{4}.{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[330] = parser; +exports.device[338] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A2|A5|A8|A900)_?(Classic|) Build"); +parser[0] = new RegExp("; {0,2}(A2|A5|A8|A900)_?(Classic|)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[331] = parser; +exports.device[339] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Q[Mm]obile)_([^_]+)_([^_]+) Build"); +parser[0] = new RegExp("; {0,2}(Q[Mm]obile)_([^_]+)_([^_]+?)(?: Build|\\) AppleWebKit)"); parser[1] = "Qmobile $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[332] = parser; +exports.device[340] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Q\\-?[Mm]obile)[_ ](A[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(Q\\-?[Mm]obile)[_ ](A[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Qmobile $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[333] = parser; +exports.device[341] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Q\\-Smart)[ _]([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(Q\\-Smart)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[334] = parser; +exports.device[342] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Q\\-?[Mm]obile)[ _\\-](S[^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(Q\\-?[Mm]obile)[ _\\-](S[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[335] = parser; +exports.device[343] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TA1013) Build"); +parser[0] = new RegExp("; {0,2}(TA1013)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[336] = parser; +exports.device[344] = parser; parser = Object.create(null); -parser[0] = new RegExp("; (RCT\\w+) Build/"); +parser[0] = new RegExp("; (RCT\\w+)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[337] = parser; +exports.device[345] = parser; parser = Object.create(null); -parser[0] = new RegExp("; RCA (\\w+) Build/"); +parser[0] = new RegExp("; RCA (\\w+)(?: Build|\\) AppleWebKit)"); parser[1] = "RCA $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[338] = parser; +exports.device[346] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(RK\\d+),? Build/"); +parser[0] = new RegExp("; {0,2}(RK\\d+),?(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[339] = parser; +exports.device[347] = parser; parser = Object.create(null); parser[0] = new RegExp(" Build/(RK\\d+)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[340] = parser; +exports.device[348] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SAMSUNG |Samsung |)((?:Galaxy (?:Note II|S\\d)|GT-I9082|GT-I9205|GT-N7\\d{3}|SM-N9005)[^;/]*)\\/?[^;/]* Build/"); +parser[0] = new RegExp("; {0,2}(SAMSUNG |Samsung |)((?:Galaxy (?:Note II|S\\d)|GT-I9082|GT-I9205|GT-N7\\d{3}|SM-N9005)[^;/]{0,100})\\/?[^;/]{0,50} Build/"); parser[1] = "Samsung $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[341] = parser; +exports.device[349] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Google |)(Nexus [Ss](?: 4G|)) Build/"); +parser[0] = new RegExp("; {0,2}(Google |)(Nexus [Ss](?: 4G|)) Build/"); parser[1] = "Samsung $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[342] = parser; +exports.device[350] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SAMSUNG |Samsung )([^\\/]*)\\/[^ ]* Build/"); +parser[0] = new RegExp("; {0,2}(SAMSUNG |Samsung )([^\\/]{0,50})\\/[^ ]{0,50} Build/"); parser[1] = "Samsung $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[343] = parser; +exports.device[351] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Galaxy(?: Ace| Nexus| S ?II+|Nexus S| with MCR 1.2| Mini Plus 4G|)) Build/"); +parser[0] = new RegExp("; {0,2}(Galaxy(?: Ace| Nexus| S ?II+|Nexus S| with MCR 1.2| Mini Plus 4G|)) Build/"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[344] = parser; +exports.device[352] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SAMSUNG[ _\\-]|)(?:SAMSUNG[ _\\-])([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(SAMSUNG[ _\\-]|)(?:SAMSUNG[ _\\-])([^;/]{1,100}) Build"); parser[1] = "Samsung $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[345] = parser; +exports.device[353] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SAMSUNG-|)(GT\\-[BINPS]\\d{4}[^\\/]*)(\\/[^ ]*) Build"); +parser[0] = new RegExp("; {0,2}(SAMSUNG-|)(GT\\-[BINPS]\\d{4}[^\\/]{0,50})(\\/[^ ]{0,50}) Build"); parser[1] = "Samsung $1$2$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[346] = parser; +exports.device[354] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:; *|^)((?:GT\\-[BIiNPS]\\d{4}|I9\\d{2}0[A-Za-z\\+]?\\b)[^;/\\)]*?)(?:Build|Linux|MIUI|[;/\\)])"); +parser[0] = new RegExp("(?:; {0,2}|^)((?:GT\\-[BIiNPS]\\d{4}|I9\\d{2}0[A-Za-z\\+]?\\b)[^;/\\)]*?)(?:Build|Linux|MIUI|[;/\\)])"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[347] = parser; +exports.device[355] = parser; parser = Object.create(null); -parser[0] = new RegExp("; (SAMSUNG-)([A-Za-z0-9\\-]+).* Build/"); +parser[0] = new RegExp("; (SAMSUNG-)([A-Za-z0-9\\-]{0,50}).{0,200} Build/"); parser[1] = "Samsung $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[348] = parser; +exports.device[356] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\\-[A-Za-z0-9 ]+)(/?[^ ]*|) Build"); +parser[0] = new RegExp("; {0,2}((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\\-[A-Za-z0-9 ]{1,50})(/?[^ ]*|) Build"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[349] = parser; +exports.device[357] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:SC)\\-[A-Za-z0-9 ]+)(/?[^ ]*|)\\)"); +parser[0] = new RegExp("; {0,2}((?:SC)\\-[A-Za-z0-9 ]{1,50})(/?[^ ]*|)\\)"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[350] = parser; +exports.device[358] = parser; parser = Object.create(null); -parser[0] = new RegExp(" ((?:SCH)\\-[A-Za-z0-9 ]+)(/?[^ ]*|) Build"); +parser[0] = new RegExp(" ((?:SCH)\\-[A-Za-z0-9 ]{1,50})(/?[^ ]*|) Build"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[351] = parser; +exports.device[359] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Behold ?(?:2|II)|YP\\-G[^;/]+|EK-GC100|SCL21|I9300) Build"); +parser[0] = new RegExp("; {0,2}(Behold ?(?:2|II)|YP\\-G[^;/]{1,100}|EK-GC100|SCL21|I9300) Build"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[352] = parser; +exports.device[360] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\\-[A-Za-z0-9]{5,6})[\\)]"); +parser[1] = "Samsung $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[361] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SH\\-?\\d\\d[^;/]+|SBM\\d[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(SH\\-?\\d\\d[^;/]{1,100}|SBM\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[353] = parser; +exports.device[362] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SHARP[ -])([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(SHARP[ -])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[354] = parser; +exports.device[363] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SPX[_\\-]\\d[^;/]*) Build/"); +parser[0] = new RegExp("; {0,2}(SPX[_\\-]\\d[^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[355] = parser; +exports.device[364] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SX7\\-PEARL\\.GmbH) Build/"); +parser[0] = new RegExp("; {0,2}(SX7\\-PEARL\\.GmbH)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[356] = parser; +exports.device[365] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SP[T]?\\-\\d{2}[^;/]*) Build/"); +parser[0] = new RegExp("; {0,2}(SP[T]?\\-\\d{2}[^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[357] = parser; +exports.device[366] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SK\\-.*) Build/"); +parser[0] = new RegExp("; {0,2}(SK\\-.{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[358] = parser; +exports.device[367] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:SKYTEX|SX)-([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(?:SKYTEX|SX)-([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[359] = parser; +exports.device[368] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(IMAGINE [^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(IMAGINE [^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[360] = parser; +exports.device[369] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SmartQ) ?([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(SmartQ) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[361] = parser; +exports.device[370] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(WF7C|WF10C|SBT[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(WF7C|WF10C|SBT[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[362] = parser; +exports.device[371] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SBM(?:003SH|005SH|006SH|007SH|102SH)) Build"); +parser[0] = new RegExp("; {0,2}(SBM(?:003SH|005SH|006SH|007SH|102SH)) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[363] = parser; +exports.device[372] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(003P|101P|101P11C|102P) Build"); +parser[0] = new RegExp("; {0,2}(003P|101P|101P11C|102P) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[364] = parser; +exports.device[373] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(00\\dZ) Build/"); +parser[0] = new RegExp("; {0,2}(00\\dZ) Build/"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[365] = parser; +exports.device[374] = parser; parser = Object.create(null); parser[0] = new RegExp("; HTC(X06HT) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[366] = parser; +exports.device[375] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(001HT|X06HT) Build"); +parser[0] = new RegExp("; {0,2}(001HT|X06HT) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[367] = parser; +exports.device[376] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(201M) Build"); +parser[0] = new RegExp("; {0,2}(201M) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[368] = parser; +exports.device[377] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ST\\d{4}.*)Build/ST"); +parser[0] = new RegExp("; {0,2}(ST\\d{4}.{0,200})Build/ST"); parser[1] = "Trekstor $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[369] = parser; +exports.device[378] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ST\\d{4}.*) Build/"); +parser[0] = new RegExp("; {0,2}(ST\\d{4}.{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Trekstor $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[370] = parser; +exports.device[379] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Sony ?Ericsson ?)([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(Sony ?Ericsson ?)([^;/]{1,100}) Build"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[371] = parser; +exports.device[380] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:SK|ST|E|X|LT|MK|MT|WT)\\d{2}[a-z0-9]*(?:-o|)|R800i|U20i) Build"); +parser[0] = new RegExp("; {0,2}((?:SK|ST|E|X|LT|MK|MT|WT)\\d{2}[a-z0-9]*(?:-o|)|R800i|U20i) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[372] = parser; +exports.device[381] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Xperia (?:A8|Arc|Acro|Active|Live with Walkman|Mini|Neo|Play|Pro|Ray|X\\d+)[^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(Xperia (?:A8|Arc|Acro|Active|Live with Walkman|Mini|Neo|Play|Pro|Ray|X\\d+)[^;/]{0,50}) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[373] = parser; +exports.device[382] = parser; parser = Object.create(null); -parser[0] = new RegExp("; Sony (Tablet[^;/]+) Build"); +parser[0] = new RegExp("; Sony (Tablet[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Sony $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[374] = parser; +exports.device[383] = parser; parser = Object.create(null); -parser[0] = new RegExp("; Sony ([^;/]+) Build"); +parser[0] = new RegExp("; Sony ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Sony $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[375] = parser; +exports.device[384] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Sony)([A-Za-z0-9\\-]+) Build"); +parser[0] = new RegExp("; {0,2}(Sony)([A-Za-z0-9\\-]+)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[376] = parser; +exports.device[385] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Xperia [^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(Xperia [^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[377] = parser; +exports.device[386] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(C(?:1[0-9]|2[0-9]|53|55|6[0-9])[0-9]{2}|D[25]\\d{3}|D6[56]\\d{2}) Build"); +parser[0] = new RegExp("; {0,2}(C(?:1[0-9]|2[0-9]|53|55|6[0-9])[0-9]{2}|D[25]\\d{3}|D6[56]\\d{2})(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[378] = parser; +exports.device[387] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SGP\\d{3}|SGPT\\d{2}) Build"); +parser[0] = new RegExp("; {0,2}(SGP\\d{3}|SGPT\\d{2})(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[379] = parser; +exports.device[388] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(NW-Z1000Series) Build"); +parser[0] = new RegExp("; {0,2}(NW-Z1000Series)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[380] = parser; +exports.device[389] = parser; parser = Object.create(null); parser[0] = new RegExp("PLAYSTATION 3"); parser[1] = "PlayStation 3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[381] = parser; +exports.device[390] = parser; parser = Object.create(null); parser[0] = new RegExp("(PlayStation (?:Portable|Vita|\\d+))"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[382] = parser; +exports.device[391] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:CSL_Spice|Spice|SPICE|CSL)[ _\\-]?|)([Mm][Ii])([ _\\-]|)(\\d{3}[^;/]*) Build/"); +parser[0] = new RegExp("; {0,2}((?:CSL_Spice|Spice|SPICE|CSL)[ _\\-]?|)([Mm][Ii])([ _\\-]|)(\\d{3}[^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2$3$4"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[383] = parser; +exports.device[392] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Sprint )(.+?) *(?:Build|[;/])"); +parser[0] = new RegExp("; {0,2}(Sprint )(.{1,200}?) {0,2}(?:Build|[;/])"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[384] = parser; +exports.device[393] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(Sprint)[: ]([^;,/ ]+)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[385] = parser; +exports.device[394] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TAGI[ ]?)(MID) ?([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(TAGI[ ]?)(MID) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[386] = parser; +exports.device[395] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Oyster500|Opal 800) Build"); +parser[0] = new RegExp("; {0,2}(Oyster500|Opal 800)(?: Build|\\) AppleWebKit)"); parser[1] = "Tecmobile $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[387] = parser; +exports.device[396] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TECNO[ _])([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(TECNO[ _])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[388] = parser; +exports.device[397] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Android for (Telechips|Techvision) ([^ ]+) "); +parser[0] = new RegExp("; {0,2}Android for (Telechips|Techvision) ([^ ]+) "); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[389] = parser; +exports.device[398] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T-Hub2) Build/"); +parser[0] = new RegExp("; {0,2}(T-Hub2)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[390] = parser; +exports.device[399] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(PAD) ?(100[12]) Build/"); +parser[0] = new RegExp("; {0,2}(PAD) ?(100[12])(?: Build|\\) AppleWebKit)"); parser[1] = "Terra $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[391] = parser; +exports.device[400] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T[BM]-\\d{3}[^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(T[BM]-\\d{3}[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[392] = parser; +exports.device[401] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(tolino [^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(tolino [^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[393] = parser; +exports.device[402] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *Build/.* (TOLINO_BROWSER)"); +parser[0] = new RegExp("; {0,2}Build/.{0,200} (TOLINO_BROWSER)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[394] = parser; +exports.device[403] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:CJ[ -])?(ThL|THL)[ -]([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(?:CJ[ -])?(ThL|THL)[ -]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[395] = parser; +exports.device[404] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T100|T200|T5|W100|W200|W8s) Build/"); +parser[0] = new RegExp("; {0,2}(T100|T200|T5|W100|W200|W8s)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[396] = parser; +exports.device[405] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T-Mobile[ _]G2[ _]Touch) Build"); +parser[0] = new RegExp("; {0,2}(T-Mobile[ _]G2[ _]Touch) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[397] = parser; +exports.device[406] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T-Mobile[ _]G2) Build"); +parser[0] = new RegExp("; {0,2}(T-Mobile[ _]G2) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[398] = parser; +exports.device[407] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T-Mobile myTouch Q) Build"); +parser[0] = new RegExp("; {0,2}(T-Mobile myTouch Q) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[399] = parser; +exports.device[408] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T-Mobile myTouch) Build"); +parser[0] = new RegExp("; {0,2}(T-Mobile myTouch) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[400] = parser; +exports.device[409] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T-Mobile_Espresso) Build"); +parser[0] = new RegExp("; {0,2}(T-Mobile_Espresso) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[401] = parser; +exports.device[410] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(T-Mobile G1) Build"); +parser[0] = new RegExp("; {0,2}(T-Mobile G1) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[402] = parser; +exports.device[411] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(T-Mobile ?|)(myTouch)[ _]?([34]G)[ _]?([^\\/]*) (?:Mozilla|Build)"); parser[1] = "$1$2 $3 $4"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[403] = parser; +exports.device[412] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\b(T-Mobile)_([^_]+)_(.*) Build"); +parser[0] = new RegExp("\\b(T-Mobile)_([^_]+)_(.{0,200}) Build"); parser[1] = "$1 $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[404] = parser; +exports.device[413] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\b(T-Mobile)[_ ]?(.*?)Build"); +parser[0] = new RegExp("\\b(T-Mobile)[_ ]?(.{0,200}?)Build"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[405] = parser; +exports.device[414] = parser; parser = Object.create(null); -parser[0] = new RegExp(" (ATP[0-9]{4}) Build"); +parser[0] = new RegExp(" (ATP[0-9]{4})(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[406] = parser; +exports.device[415] = parser; parser = Object.create(null); -parser[0] = new RegExp(" *(TOOKY)[ _\\-]([^;/]+) ?(?:Build|;)"); +parser[0] = new RegExp(" ?(TOOKY)[ _\\-]([^;/]{1,100}) ?(?:Build|;)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[407] = parser; +exports.device[416] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(TOSHIBA_AC_AND_AZ|TOSHIBA_FOLIO_AND_A|FOLIO_AND_A)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[408] = parser; +exports.device[417] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([Ff]olio ?100) Build/"); +parser[0] = new RegExp("; {0,2}([Ff]olio ?100)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[409] = parser; +exports.device[418] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(AT[0-9]{2,3}(?:\\-A|LE\\-A|PE\\-A|SE|a|)|AT7-A|AT1S0|Hikari-iFrame/WDPF-[^;/]+|THRiVE|Thrive) Build/"); +parser[0] = new RegExp("; {0,2}(AT[0-9]{2,3}(?:\\-A|LE\\-A|PE\\-A|SE|a|)|AT7-A|AT1S0|Hikari-iFrame/WDPF-[^;/]{1,100}|THRiVE|Thrive)(?: Build|\\) AppleWebKit)"); parser[1] = "Toshiba $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[410] = parser; +exports.device[419] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TM-MID\\d+[^;/]+|TOUCHMATE|MID-750) Build"); +parser[0] = new RegExp("; {0,2}(TM-MID\\d+[^;/]{1,50}|TOUCHMATE|MID-750)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[411] = parser; +exports.device[420] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TM-SM\\d+[^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(TM-SM\\d+[^;/]{1,50}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[412] = parser; +exports.device[421] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A10 [Bb]asic2?) Build/"); +parser[0] = new RegExp("; {0,2}(A10 [Bb]asic2?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[413] = parser; +exports.device[422] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(TREQ[ _\\-])([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(TREQ[ _\\-])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[414] = parser; +exports.device[423] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(X-?5|X-?3) Build/"); +parser[0] = new RegExp("; {0,2}(X-?5|X-?3)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[415] = parser; +exports.device[424] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(A502\\+?|A936|A603|X1|X2) Build/"); +parser[0] = new RegExp("; {0,2}(A502\\+?|A936|A603|X1|X2)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[416] = parser; +exports.device[425] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; thor Build/"); +parser[1] = "Thor"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[426] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; Thor (E)? Build/"); +parser[1] = "Thor $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[427] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; Apollo Lite Build/"); +parser[1] = "Apollo Lite"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[428] = parser; parser = Object.create(null); -parser[0] = new RegExp("(TOUCH(?:TAB|PAD).+?) Build/"); +parser[0] = new RegExp("(TOUCH(?:TAB|PAD).{1,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Versus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[417] = parser; +exports.device[429] = parser; parser = Object.create(null); -parser[0] = new RegExp("(VERTU) ([^;/]+) Build/"); +parser[0] = new RegExp("(VERTU) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[418] = parser; +exports.device[430] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Videocon)[ _\\-]([^;/]+) *(?:Build|;)"); +parser[0] = new RegExp("; {0,2}(Videocon)[ _\\-]([^;/]{1,100}?) {0,2}(?:Build|;)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[419] = parser; +exports.device[431] = parser; parser = Object.create(null); -parser[0] = new RegExp(" (VT\\d{2}[A-Za-z]*) Build"); +parser[0] = new RegExp(" (VT\\d{2}[A-Za-z]*)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[420] = parser; +exports.device[432] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((?:ViewPad|ViewPhone|VSD)[^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}((?:ViewPad|ViewPhone|VSD)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[421] = parser; +exports.device[433] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ViewSonic-)([^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(ViewSonic-)([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[422] = parser; +exports.device[434] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(GTablet.*) Build/"); +parser[0] = new RegExp("; {0,2}(GTablet.{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[423] = parser; +exports.device[435] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([Vv]ivo)[ _]([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}([Vv]ivo)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[424] = parser; +exports.device[436] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Vodafone) (.*) Build/"); +parser[0] = new RegExp("(Vodafone) (.{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[425] = parser; +exports.device[437] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Walton[ _\\-]|)(Primo[ _\\-][^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(?:Walton[ _\\-]|)(Primo[ _\\-][^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Walton $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[426] = parser; +exports.device[438] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:WIKO[ \\-]|)(CINK\\+?|BARRY|BLOOM|DARKFULL|DARKMOON|DARKNIGHT|DARKSIDE|FIZZ|HIGHWAY|IGGY|OZZY|RAINBOW|STAIRWAY|SUBLIM|WAX|CINK [^;/]+) Build/"); +parser[0] = new RegExp("; {0,2}(?:WIKO[ \\-]|)(CINK\\+?|BARRY|BLOOM|DARKFULL|DARKMOON|DARKNIGHT|DARKSIDE|FIZZ|HIGHWAY|IGGY|OZZY|RAINBOW|STAIRWAY|SUBLIM|WAX|CINK [^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Wiko $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[427] = parser; +exports.device[439] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *WellcoM-([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}WellcoM-([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Wellcom $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[428] = parser; +exports.device[440] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(?:(WeTab)-Browser|; (wetab) Build)"); +parser[1] = "$1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[441] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}(AT-AS[^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Wolfgang $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[442] = parser; +parser = Object.create(null); +parser[0] = new RegExp("; {0,2}(?:Woxter|Wxt) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); +parser[1] = "Woxter $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[443] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:(WeTab)-Browser|; (wetab) Build)"); -parser[1] = "$1"; +parser[0] = new RegExp("; {0,2}(?:Xenta |Luna |)(TAB[234][0-9]{2}|TAB0[78]-\\d{3}|TAB0?9-\\d{3}|TAB1[03]-\\d{3}|SMP\\d{2}-\\d{3})(?: Build|\\) AppleWebKit)"); +parser[1] = "Yarvik $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[429] = parser; +exports.device[444] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(AT-AS[^;/]+) Build"); -parser[1] = "Wolfgang $1"; +parser[0] = new RegExp("; {0,2}([A-Z]{2,4})(M\\d{3,}[A-Z]{2})([^;\\)\\/]*)(?: Build|[;\\)])"); +parser[1] = "Yifang $1$2$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[430] = parser; +exports.device[445] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Woxter|Wxt) ([^;/]+) Build"); -parser[1] = "Woxter $1"; +parser[0] = new RegExp("; {0,2}((Mi|MI|HM|MI-ONE|Redmi)[ -](NOTE |Note |)[^;/]*) (Build|MIUI)/"); +parser[1] = "XiaoMi $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[431] = parser; +exports.device[446] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Xenta |Luna |)(TAB[234][0-9]{2}|TAB0[78]-\\d{3}|TAB0?9-\\d{3}|TAB1[03]-\\d{3}|SMP\\d{2}-\\d{3}) Build/"); -parser[1] = "Yarvik $1"; +parser[0] = new RegExp("; {0,2}((Mi|MI|HM|MI-ONE|Redmi)[ -](NOTE |Note |)[^;/\\)]*)"); +parser[1] = "XiaoMi $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[432] = parser; +exports.device[447] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([A-Z]{2,4})(M\\d{3,}[A-Z]{2})([^;\\)\\/]*)(?: Build|[;\\)])"); -parser[1] = "Yifang $1$2$3"; +parser[0] = new RegExp("; {0,2}(MIX) (Build|MIUI)/"); +parser[1] = "XiaoMi $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[433] = parser; +exports.device[448] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *((Mi|MI|HM|MI-ONE|Redmi)[ -](NOTE |Note |)[^;/]*) (Build|MIUI)/"); +parser[0] = new RegExp("; {0,2}((MIX) ([^;/]*)) (Build|MIUI)/"); parser[1] = "XiaoMi $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[434] = parser; +exports.device[449] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *XOLO[ _]([^;/]*tab.*) Build"); +parser[0] = new RegExp("; {0,2}XOLO[ _]([^;/]{0,30}tab.{0,30})(?: Build|\\) AppleWebKit)"); parser[1] = "Xolo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[435] = parser; +exports.device[450] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *XOLO[ _]([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}XOLO[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "Xolo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[436] = parser; +exports.device[451] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(q\\d0{2,3}[a-z]?) Build"); +parser[0] = new RegExp("; {0,2}(q\\d0{2,3}[a-z]?)(?: Build|\\) AppleWebKit)"); parser[1] = "Xolo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[437] = parser; +exports.device[452] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(PAD ?[79]\\d+[^;/]*|TelePAD\\d+[^;/]) Build"); +parser[0] = new RegExp("; {0,2}(PAD ?[79]\\d+[^;/]{0,50}|TelePAD\\d+[^;/])(?: Build|\\) AppleWebKit)"); parser[1] = "Xoro $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[438] = parser; +exports.device[453] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:(?:ZOPO|Zopo)[ _]([^;/]+)|(ZP ?(?:\\d{2}[^;/]+|C2))|(C[2379])) Build"); +parser[0] = new RegExp("; {0,2}(?:(?:ZOPO|Zopo)[ _]([^;/]{1,100}?)|(ZP ?(?:\\d{2}[^;/]{1,100}|C2))|(C[2379]))(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[439] = parser; +exports.device[454] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ZiiLABS) (Zii[^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(ZiiLABS) (Zii[^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[440] = parser; +exports.device[455] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Zii)_([^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(Zii)_([^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[441] = parser; +exports.device[456] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(ARIZONA|(?:ATLAS|Atlas) W|D930|Grand (?:[SX][^;]*|Era|Memo[^;]*)|JOE|(?:Kis|KIS)\\b[^;]*|Libra|Light [^;]*|N8[056][01]|N850L|N8000|N9[15]\\d{2}|N9810|NX501|Optik|(?:Vip )Racer[^;]*|RacerII|RACERII|San Francisco[^;]*|V9[AC]|V55|V881|Z[679][0-9]{2}[A-z]?) Build"); +parser[0] = new RegExp("; {0,2}(ARIZONA|(?:ATLAS|Atlas) W|D930|Grand (?:[SX][^;]{0,200}?|Era|Memo[^;]{0,200}?)|JOE|(?:Kis|KIS)\\b[^;]{0,200}?|Libra|Light [^;]{0,200}?|N8[056][01]|N850L|N8000|N9[15]\\d{2}|N9810|NX501|Optik|(?:Vip )Racer[^;]{0,200}?|RacerII|RACERII|San Francisco[^;]{0,200}?|V9[AC]|V55|V881|Z[679][0-9]{2}[A-z]?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[442] = parser; +exports.device[457] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *([A-Z]\\d+)_USA_[^;]* Build"); +parser[0] = new RegExp("; {0,2}([A-Z]\\d+)_USA_[^;]{0,200}(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[443] = parser; +exports.device[458] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(SmartTab\\d+)[^;]* Build"); +parser[0] = new RegExp("; {0,2}(SmartTab\\d+)[^;]{0,50}(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[444] = parser; +exports.device[459] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Blade|BLADE|ZTE-BLADE)([^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(?:Blade|BLADE|ZTE-BLADE)([^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "ZTE Blade$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[445] = parser; +exports.device[460] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:Skate|SKATE|ZTE-SKATE)([^;/]*) Build"); +parser[0] = new RegExp("; {0,2}(?:Skate|SKATE|ZTE-SKATE)([^;/]*)(?: Build|\\) AppleWebKit)"); parser[1] = "ZTE Skate$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[446] = parser; +exports.device[461] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(Orange |Optimus )(Monte Carlo|San Francisco) Build"); +parser[0] = new RegExp("; {0,2}(Orange |Optimus )(Monte Carlo|San Francisco)(?: Build|\\) AppleWebKit)"); parser[1] = "$1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[447] = parser; +exports.device[462] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(?:ZXY-ZTE_|ZTE\\-U |ZTE[\\- _]|ZTE-C[_ ])([^;/]+) Build"); +parser[0] = new RegExp("; {0,2}(?:ZXY-ZTE_|ZTE\\-U |ZTE[\\- _]|ZTE-C[_ ])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)"); parser[1] = "ZTE $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[448] = parser; +exports.device[463] = parser; parser = Object.create(null); -parser[0] = new RegExp("; (BASE) (lutea|Lutea 2|Tab[^;]*) Build"); +parser[0] = new RegExp("; (BASE) (lutea|Lutea 2|Tab[^;]{0,200}?)(?: Build|\\) AppleWebKit)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[449] = parser; +exports.device[464] = parser; parser = Object.create(null); -parser[0] = new RegExp("; (Avea inTouch 2|soft stone|tmn smart a7|Movistar[ _]Link) Build"); +parser[0] = new RegExp("; (Avea inTouch 2|soft stone|tmn smart a7|Movistar[ _]Link)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[450] = parser; +exports.device[465] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(vp9plus)\\)"); +parser[0] = new RegExp("; {0,2}(vp9plus)\\)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[451] = parser; +exports.device[466] = parser; parser = Object.create(null); -parser[0] = new RegExp("; ?(Cloud[ _]Z5|z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900) Build/"); +parser[0] = new RegExp("; ?(Cloud[ _]Z5|z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900)(?: Build|\\) AppleWebKit)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[452] = parser; +exports.device[467] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFOT|Kindle Fire) Build\\b"); parser[1] = "Kindle Fire"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[453] = parser; +exports.device[468] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFOTE|Amazon Kindle Fire2) Build\\b"); parser[1] = "Kindle Fire 2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[454] = parser; +exports.device[469] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFTT) Build\\b"); parser[1] = "Kindle Fire HD"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[455] = parser; +exports.device[470] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFJWI) Build\\b"); parser[1] = "Kindle Fire HD 8.9\" WiFi"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[456] = parser; +exports.device[471] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFJWA) Build\\b"); parser[1] = "Kindle Fire HD 8.9\" 4G"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[457] = parser; +exports.device[472] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFSOWI) Build\\b"); parser[1] = "Kindle Fire HD 7\" WiFi"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[458] = parser; +exports.device[473] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFTHWI) Build\\b"); parser[1] = "Kindle Fire HDX 7\" WiFi"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[459] = parser; +exports.device[474] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFTHWA) Build\\b"); parser[1] = "Kindle Fire HDX 7\" 4G"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[460] = parser; +exports.device[475] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFAPWI) Build\\b"); parser[1] = "Kindle Fire HDX 8.9\" WiFi"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[461] = parser; +exports.device[476] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(KFAPWA) Build\\b"); parser[1] = "Kindle Fire HDX 8.9\" 4G"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[462] = parser; +exports.device[477] = parser; parser = Object.create(null); -parser[0] = new RegExp("; ?Amazon ([^;/]+) Build\\b"); +parser[0] = new RegExp("; ?Amazon ([^;/]{1,100}) Build\\b"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[463] = parser; +exports.device[478] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(Kindle) Build\\b"); parser[1] = "Kindle"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[464] = parser; +exports.device[479] = parser; parser = Object.create(null); parser[0] = new RegExp("; ?(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+)|) Build\\b"); parser[1] = "Kindle Fire"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[465] = parser; +exports.device[480] = parser; parser = Object.create(null); parser[0] = new RegExp(" (Kindle)/(\\d+\\.\\d+)"); parser[1] = "Kindle"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[466] = parser; +exports.device[481] = parser; parser = Object.create(null); parser[0] = new RegExp(" (Silk|Kindle)/(\\d+)\\."); parser[1] = "Kindle"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[467] = parser; +exports.device[482] = parser; parser = Object.create(null); -parser[0] = new RegExp("(sprd)\\-([^/]+)/"); +parser[0] = new RegExp("(sprd)\\-([^/]{1,50})/"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[468] = parser; +exports.device[483] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(H\\d{2}00\\+?) Build"); +parser[0] = new RegExp("; {0,2}(H\\d{2}00\\+?) Build"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[469] = parser; +exports.device[484] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(iphone|iPhone5) Build/"); +parser[0] = new RegExp("; {0,2}(iphone|iPhone5) Build/"); parser[1] = "Xianghe $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[470] = parser; +exports.device[485] = parser; parser = Object.create(null); -parser[0] = new RegExp("; *(e\\d{4}[a-z]?_?v\\d+|v89_[^;/]+)[^;/]+ Build/"); +parser[0] = new RegExp("; {0,2}(e\\d{4}[a-z]?_?v\\d+|v89_[^;/]{1,100})[^;/]{1,30} Build/"); parser[1] = "Xianghe $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[471] = parser; +exports.device[486] = parser; parser = Object.create(null); parser[0] = new RegExp("\\bUSCC[_\\-]?([^ ;/\\)]+)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[472] = parser; +exports.device[487] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:ALCATEL)[^;]*; *([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:ALCATEL)[^;]{0,200}; {0,2}([^;,\\)]+)"); parser[1] = "Alcatel $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[473] = parser; +exports.device[488] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:ASUS|Asus)[^;]*; *([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:ASUS|Asus)[^;]{0,200}; {0,2}([^;,\\)]+)"); parser[1] = "Asus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[474] = parser; +exports.device[489] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:DELL|Dell)[^;]*; *([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:DELL|Dell)[^;]{0,200}; {0,2}([^;,\\)]+)"); parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[475] = parser; +exports.device[490] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:HTC|Htc|HTC_blocked[^;]*)[^;]*; *(?:HTC|)([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:HTC|Htc|HTC_blocked[^;]{0,200})[^;]{0,200}; {0,2}(?:HTC|)([^;,\\)]+)"); parser[1] = "HTC $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[476] = parser; +exports.device[491] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:HUAWEI)[^;]*; *(?:HUAWEI |)([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:HUAWEI)[^;]{0,200}; {0,2}(?:HUAWEI |)([^;,\\)]+)"); parser[1] = "Huawei $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[477] = parser; +exports.device[492] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:LG|Lg)[^;]*; *(?:LG[ \\-]|)([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:LG|Lg)[^;]{0,200}; {0,2}(?:LG[ \\-]|)([^;,\\)]+)"); parser[1] = "LG $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[478] = parser; +exports.device[493] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:rv:11; |)(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?|)(\\d{3,10}[^;\\)]*)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:rv:11; |)(?:NOKIA|Nokia)[^;]{0,200}; {0,2}(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?|)(\\d{3,10}[^;\\)]*)"); parser[1] = "Lumia $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[479] = parser; +exports.device[494] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:NOKIA|Nokia)[^;]*; *(RM-\\d{3,})"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:NOKIA|Nokia)[^;]{0,200}; {0,2}(RM-\\d{3,})"); parser[1] = "Nokia $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[480] = parser; +exports.device[495] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)]|WPDesktop;) ?(?:ARM; ?Touch; ?|Touch; ?|)(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?|)([^;\\)]+)"); +parser[0] = new RegExp("(?:Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)]|WPDesktop;) ?(?:ARM; ?Touch; ?|Touch; ?|)(?:NOKIA|Nokia)[^;]{0,200}; {0,2}(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?|)([^;\\)]+)"); parser[1] = "Nokia $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[481] = parser; +exports.device[496] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:Microsoft(?: Corporation|))[^;]*; *([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:Microsoft(?: Corporation|))[^;]{0,200}; {0,2}([^;,\\)]+)"); parser[1] = "Microsoft $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[482] = parser; +exports.device[497] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:SAMSUNG)[^;]*; *(?:SAMSUNG |)([^;,\\.\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:SAMSUNG)[^;]{0,200}; {0,2}(?:SAMSUNG |)([^;,\\.\\)]+)"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[483] = parser; +exports.device[498] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:TOSHIBA|FujitsuToshibaMobileCommun)[^;]*; *([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:TOSHIBA|FujitsuToshibaMobileCommun)[^;]{0,200}; {0,2}([^;,\\)]+)"); parser[1] = "Toshiba $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[484] = parser; +exports.device[499] = parser; parser = Object.create(null); -parser[0] = new RegExp("Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)([^;]+); *([^;,\\)]+)"); +parser[0] = new RegExp("Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)([^;]{1,200}); {0,2}([^;,\\)]+)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[485] = parser; +exports.device[500] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:^|; )SAMSUNG\\-([A-Za-z0-9\\-]+).* Bada/"); +parser[0] = new RegExp("(?:^|; )SAMSUNG\\-([A-Za-z0-9\\-]{1,50}).{0,200} Bada/"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[486] = parser; +exports.device[501] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\(Mobile; ALCATEL ?(One|ONE) ?(Touch|TOUCH) ?([^;/]+)(?:/[^;]+|); rv:[^\\)]+\\) Gecko/[^\\/]+ Firefox/"); +parser[0] = new RegExp("\\(Mobile; ALCATEL ?(One|ONE) ?(Touch|TOUCH) ?([^;/]{1,100}?)(?:/[^;]{1,200}|); rv:[^\\)]{1,200}\\) Gecko/[^\\/]{1,200} Firefox/"); parser[1] = "Alcatel $1 $2 $3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[487] = parser; +exports.device[502] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\(Mobile; (?:ZTE([^;]+)|(OpenC)); rv:[^\\)]+\\) Gecko/[^\\/]+ Firefox/"); +parser[0] = new RegExp("\\(Mobile; (?:ZTE([^;]{1,200})|(OpenC)); rv:[^\\)]{1,200}\\) Gecko/[^\\/]{1,200} Firefox/"); parser[1] = "ZTE $1$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[488] = parser; +exports.device[503] = parser; +parser = Object.create(null); +parser[0] = new RegExp("\\(Mobile; ALCATEL([A-Za-z0-9\\-]+); rv:[^\\)]{1,200}\\) Gecko/[^\\/]{1,200} Firefox/[^\\/]{1,200} KaiOS/"); +parser[1] = "Alcatel $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[504] = parser; +parser = Object.create(null); +parser[0] = new RegExp("\\(Mobile; LYF\\/([A-Za-z0-9\\-]{1,100})\\/.{0,100};.{0,100}rv:[^\\)]{1,100}\\) Gecko/[^\\/]{1,100} Firefox/[^\\/]{1,100} KAIOS/"); +parser[1] = "LYF $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[505] = parser; parser = Object.create(null); -parser[0] = new RegExp("Nokia(N[0-9]+)([A-z_\\-][A-z0-9_\\-]*)"); +parser[0] = new RegExp("\\(Mobile; Nokia_([A-Za-z0-9\\-]{1,100})_.{1,100}; rv:[^\\)]{1,100}\\) Gecko/[^\\/]{1,100} Firefox/[^\\/]{1,100} KAIOS/"); parser[1] = "Nokia $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[489] = parser; +exports.device[506] = parser; +parser = Object.create(null); +parser[0] = new RegExp("Nokia(N[0-9]+)([A-Za-z_\\-][A-Za-z0-9_\\-]*)"); +parser[1] = "Nokia $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[507] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:NOKIA|Nokia)(?:\\-| *)(?:([A-Za-z0-9]+)\\-[0-9a-f]{32}|([A-Za-z0-9\\-]+)(?:UCBrowser)|([A-Za-z0-9\\-]+))"); +parser[0] = new RegExp("(?:NOKIA|Nokia)(?:\\-| {0,2})(?:([A-Za-z0-9]+)\\-[0-9a-f]{32}|([A-Za-z0-9\\-]+)(?:UCBrowser)|([A-Za-z0-9\\-]+))"); parser[1] = "Nokia $1$2$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[490] = parser; +exports.device[508] = parser; parser = Object.create(null); parser[0] = new RegExp("Lumia ([A-Za-z0-9\\-]+)"); parser[1] = "Lumia $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[491] = parser; +exports.device[509] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\(Symbian; U; S60 V5; [A-z]{2}\\-[A-z]{2}; (SonyEricsson|Samsung|Nokia|LG)([^;/]+)\\)"); +parser[0] = new RegExp("\\(Symbian; U; S60 V5; [A-z]{2}\\-[A-z]{2}; (SonyEricsson|Samsung|Nokia|LG)([^;/]{1,100}?)\\)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[492] = parser; +exports.device[510] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\(Symbian(?:/3|); U; ([^;]+);"); +parser[0] = new RegExp("\\(Symbian(?:/3|); U; ([^;]{1,200});"); parser[1] = "Nokia $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[493] = parser; +exports.device[511] = parser; parser = Object.create(null); parser[0] = new RegExp("BB10; ([A-Za-z0-9\\- ]+)\\)"); parser[1] = "BlackBerry $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[494] = parser; +exports.device[512] = parser; parser = Object.create(null); -parser[0] = new RegExp("Play[Bb]ook.+RIM Tablet OS"); +parser[0] = new RegExp("Play[Bb]ook.{1,200}RIM Tablet OS"); parser[1] = "BlackBerry Playbook"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[495] = parser; +exports.device[513] = parser; parser = Object.create(null); parser[0] = new RegExp("Black[Bb]erry ([0-9]+);"); parser[1] = "BlackBerry $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[496] = parser; +exports.device[514] = parser; parser = Object.create(null); parser[0] = new RegExp("Black[Bb]erry([0-9]+)"); parser[1] = "BlackBerry $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[497] = parser; +exports.device[515] = parser; parser = Object.create(null); parser[0] = new RegExp("Black[Bb]erry;"); parser[1] = "BlackBerry"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[498] = parser; +exports.device[516] = parser; parser = Object.create(null); parser[0] = new RegExp("(Pre|Pixi)/\\d+\\.\\d+"); parser[1] = "Palm $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[499] = parser; +exports.device[517] = parser; parser = Object.create(null); parser[0] = new RegExp("Palm([0-9]+)"); parser[1] = "Palm $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[500] = parser; +exports.device[518] = parser; parser = Object.create(null); parser[0] = new RegExp("Treo([A-Za-z0-9]+)"); parser[1] = "Palm Treo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[501] = parser; +exports.device[519] = parser; parser = Object.create(null); -parser[0] = new RegExp("webOS.*(P160U(?:NA|))/(\\d+).(\\d+)"); +parser[0] = new RegExp("webOS.{0,200}(P160U(?:NA|))/(\\d+).(\\d+)"); parser[1] = "HP Veer"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[502] = parser; +exports.device[520] = parser; parser = Object.create(null); parser[0] = new RegExp("(Touch[Pp]ad)/\\d+\\.\\d+"); parser[1] = "HP TouchPad"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[503] = parser; +exports.device[521] = parser; parser = Object.create(null); -parser[0] = new RegExp("HPiPAQ([A-Za-z0-9]+)/\\d+.\\d+"); +parser[0] = new RegExp("HPiPAQ([A-Za-z0-9]{1,20})/\\d+\\.\\d+"); parser[1] = "HP iPAQ $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[504] = parser; +exports.device[522] = parser; parser = Object.create(null); parser[0] = new RegExp("PDA; (PalmOS)/sony/model ([a-z]+)/Revision"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[505] = parser; +exports.device[523] = parser; parser = Object.create(null); parser[0] = new RegExp("(Apple\\s?TV)"); parser[1] = "AppleTV"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[506] = parser; +exports.device[524] = parser; parser = Object.create(null); parser[0] = new RegExp("(QtCarBrowser)"); parser[1] = "Tesla Model S"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[507] = parser; +exports.device[525] = parser; parser = Object.create(null); parser[0] = new RegExp("(iPhone|iPad|iPod)(\\d+,\\d+)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[508] = parser; +exports.device[526] = parser; parser = Object.create(null); parser[0] = new RegExp("(iPad)(?:;| Simulator;)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[509] = parser; +exports.device[527] = parser; parser = Object.create(null); parser[0] = new RegExp("(iPod)(?:;| touch;| Simulator;)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[510] = parser; +exports.device[528] = parser; parser = Object.create(null); parser[0] = new RegExp("(iPhone)(?:;| Simulator;)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[511] = parser; +exports.device[529] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Watch)(\\d+,\\d+)"); +parser[1] = "Apple $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[530] = parser; parser = Object.create(null); parser[0] = new RegExp("(Apple Watch)(?:;| Simulator;)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[512] = parser; +exports.device[531] = parser; parser = Object.create(null); parser[0] = new RegExp("(HomePod)(?:;| Simulator;)"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[513] = parser; +exports.device[532] = parser; parser = Object.create(null); parser[0] = new RegExp("iPhone"); parser[1] = "iPhone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[514] = parser; +exports.device[533] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/\\d.*\\(((?:Mac|iMac|PowerMac|PowerBook)[^\\d]*)(\\d+)(?:,|%2C)(\\d+)"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/\\d.{0,100}\\(((?:Mac|iMac|PowerMac|PowerBook)[^\\d]*)(\\d+)(?:,|%2C)(\\d+)"); parser[1] = "$1$2,$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[515] = parser; +exports.device[534] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/\\d+\\.\\d+\\.\\d+ \\(x86_64\\)"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/\\d+\\.\\d+\\.\\d+ \\(x86_64\\)"); parser[1] = "Mac"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[516] = parser; +exports.device[535] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/\\d"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/\\d"); parser[1] = "iOS-Device"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[517] = parser; +exports.device[536] = parser; parser = Object.create(null); parser[0] = new RegExp("Outlook-(iOS)/\\d+\\.\\d+\\.prod\\.iphone"); parser[1] = "iPhone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[518] = parser; +exports.device[537] = parser; parser = Object.create(null); parser[0] = new RegExp("acer_([A-Za-z0-9]+)_"); parser[1] = "Acer $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[519] = parser; +exports.device[538] = parser; parser = Object.create(null); parser[0] = new RegExp("(?:ALCATEL|Alcatel)-([A-Za-z0-9\\-]+)"); parser[1] = "Alcatel $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[520] = parser; +exports.device[539] = parser; parser = Object.create(null); parser[0] = new RegExp("(?:Amoi|AMOI)\\-([A-Za-z0-9]+)"); parser[1] = "Amoi $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[521] = parser; +exports.device[540] = parser; parser = Object.create(null); parser[0] = new RegExp("(?:; |\\/|^)((?:Transformer (?:Pad|Prime) |Transformer |PadFone[ _]?)[A-Za-z0-9]*)"); parser[1] = "Asus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[522] = parser; +exports.device[541] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:asus.*?ASUS|Asus|ASUS|asus)[\\- ;]*((?:Transformer (?:Pad|Prime) |Transformer |Padfone |Nexus[ _]|)[A-Za-z0-9]+)"); +parser[0] = new RegExp("(?:asus.{0,200}?ASUS|Asus|ASUS|asus)[\\- ;]*((?:Transformer (?:Pad|Prime) |Transformer |Padfone |Nexus[ _]|)[A-Za-z0-9]+)"); parser[1] = "Asus $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[523] = parser; +exports.device[542] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(?:ASUS)_([A-Za-z0-9\\-]+)"); +parser[1] = "Asus $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[543] = parser; parser = Object.create(null); parser[0] = new RegExp("\\bBIRD[ \\-\\.]([A-Za-z0-9]+)"); parser[1] = "Bird $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[524] = parser; +exports.device[544] = parser; parser = Object.create(null); parser[0] = new RegExp("\\bDell ([A-Za-z0-9]+)"); parser[1] = "Dell $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[525] = parser; +exports.device[545] = parser; parser = Object.create(null); parser[0] = new RegExp("DoCoMo/2\\.0 ([A-Za-z0-9]+)"); parser[1] = "DoCoMo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[526] = parser; +exports.device[546] = parser; parser = Object.create(null); -parser[0] = new RegExp("([A-Za-z0-9]+)_W;FOMA"); +parser[0] = new RegExp("^.{0,50}?([A-Za-z0-9]{1,30})_W;FOMA"); parser[1] = "DoCoMo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[527] = parser; +exports.device[547] = parser; parser = Object.create(null); -parser[0] = new RegExp("([A-Za-z0-9]+);FOMA"); +parser[0] = new RegExp("^.{0,50}?([A-Za-z0-9]{1,30});FOMA"); parser[1] = "DoCoMo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[528] = parser; +exports.device[548] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\b(?:HTC/|HTC/[a-z0-9]+/|)HTC[ _\\-;]? *(.*?)(?:-?Mozilla|fingerPrint|[;/\\(\\)]|$)"); +parser[0] = new RegExp("\\b(?:HTC/|HTC/[a-z0-9]{1,20}/|)HTC[ _\\-;]? {0,2}(.{0,200}?)(?:-?Mozilla|fingerPrint|[;/\\(\\)]|$)"); parser[1] = "HTC $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[529] = parser; +exports.device[549] = parser; parser = Object.create(null); parser[0] = new RegExp("Huawei([A-Za-z0-9]+)"); parser[1] = "Huawei $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[530] = parser; +exports.device[550] = parser; parser = Object.create(null); parser[0] = new RegExp("HUAWEI-([A-Za-z0-9]+)"); parser[1] = "Huawei $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[531] = parser; +exports.device[551] = parser; +parser = Object.create(null); +parser[0] = new RegExp("HUAWEI ([A-Za-z0-9\\-]+)"); +parser[1] = "Huawei $1"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[552] = parser; parser = Object.create(null); parser[0] = new RegExp("vodafone([A-Za-z0-9]+)"); parser[1] = "Huawei Vodafone $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[532] = parser; +exports.device[553] = parser; parser = Object.create(null); parser[0] = new RegExp("i\\-mate ([A-Za-z0-9]+)"); parser[1] = "i-mate $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[533] = parser; +exports.device[554] = parser; parser = Object.create(null); parser[0] = new RegExp("Kyocera\\-([A-Za-z0-9]+)"); parser[1] = "Kyocera $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[534] = parser; +exports.device[555] = parser; parser = Object.create(null); parser[0] = new RegExp("KWC\\-([A-Za-z0-9]+)"); parser[1] = "Kyocera $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[535] = parser; +exports.device[556] = parser; parser = Object.create(null); parser[0] = new RegExp("Lenovo[_\\-]([A-Za-z0-9]+)"); parser[1] = "Lenovo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[536] = parser; +exports.device[557] = parser; parser = Object.create(null); -parser[0] = new RegExp("(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+ \\([^;]*; *(LG)E *; *([^;]*) *;[^;]*;[^;]*;\\)"); +parser[0] = new RegExp("(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+ \\( ?;(LG)E ?;([^;]{0,30})"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[537] = parser; +exports.device[558] = parser; parser = Object.create(null); -parser[0] = new RegExp("(HbbTV)/1\\.1\\.1.*CE-HTML/1\\.\\d;(Vendor/|)(THOM[^;]*?)[;\\s].{0,30}(LF[^;]+);?"); +parser[0] = new RegExp("(HbbTV)/1\\.1\\.1.{0,200}CE-HTML/1\\.\\d;(Vendor/|)(THOM[^;]{0,200}?)[;\\s].{0,30}(LF[^;]{1,200});?"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[538] = parser; +exports.device[559] = parser; parser = Object.create(null); -parser[0] = new RegExp("(HbbTV)(?:/1\\.1\\.1|) ?(?: \\(;;;;;\\)|); *CE-HTML(?:/1\\.\\d|); *([^ ]+) ([^;]+);"); +parser[0] = new RegExp("(HbbTV)(?:/1\\.1\\.1|) ?(?: \\(;;;;;\\)|); {0,2}CE-HTML(?:/1\\.\\d|); {0,2}([^ ]{1,30}) ([^;]{1,200});"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[539] = parser; +exports.device[560] = parser; parser = Object.create(null); parser[0] = new RegExp("(HbbTV)/1\\.1\\.1 \\(;;;;;\\) Maple_2011"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[540] = parser; +exports.device[561] = parser; parser = Object.create(null); -parser[0] = new RegExp("(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+ \\([^;]*; *(?:CUS:([^;]*)|([^;]+)) *; *([^;]*) *;.*;"); +parser[0] = new RegExp("(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+ \\([^;]{0,30}; ?(?:CUS:([^;]{0,200})|([^;]{1,200})) ?; ?([^;]{0,30})"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[541] = parser; +exports.device[562] = parser; parser = Object.create(null); parser[0] = new RegExp("(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[542] = parser; +exports.device[563] = parser; parser = Object.create(null); -parser[0] = new RegExp("LGE; (?:Media\\/|)([^;]*);[^;]*;[^;]*;?\\); \"?LG NetCast(\\.TV|\\.Media|)-\\d+"); +parser[0] = new RegExp("LGE; (?:Media\\/|)([^;]{0,200});[^;]{0,200};[^;]{0,200};?\\); \"?LG NetCast(\\.TV|\\.Media|)-\\d+"); parser[1] = "NetCast$2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[543] = parser; +exports.device[564] = parser; parser = Object.create(null); -parser[0] = new RegExp("InettvBrowser/[0-9]+\\.[0-9A-Z]+ \\([^;]*;(Sony)([^;]*);[^;]*;[^\\)]*\\)"); +parser[0] = new RegExp("InettvBrowser/[0-9]{1,30}\\.[0-9A-Z]{1,30} \\([^;]{0,200};(Sony)([^;]{0,200});[^;]{0,200};[^\\)]{0,10}\\)"); parser[1] = "Inettv"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[544] = parser; +exports.device[565] = parser; parser = Object.create(null); -parser[0] = new RegExp("InettvBrowser/[0-9]+\\.[0-9A-Z]+ \\([^;]*;([^;]*);[^;]*;[^\\)]*\\)"); +parser[0] = new RegExp("InettvBrowser/[0-9]{1,30}\\.[0-9A-Z]{1,30} \\([^;]{0,200};([^;]{0,200});[^;]{0,200};[^\\)]{0,10}\\)"); parser[1] = "Inettv"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[545] = parser; +exports.device[566] = parser; parser = Object.create(null); parser[0] = new RegExp("(?:InettvBrowser|TSBNetTV|NETTV|HBBTV)"); parser[1] = "Inettv"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[546] = parser; +exports.device[567] = parser; parser = Object.create(null); parser[0] = new RegExp("Series60/\\d\\.\\d (LG)[\\-]?([A-Za-z0-9 \\-]+)"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[547] = parser; +exports.device[568] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(?:LGE[ \\-]LG\\-(?:AX|)|LGE |LGE?-LG|LGE?[ \\-]|LG[ /\\-]|lg[\\-])([A-Za-z0-9]+)\\b"); parser[1] = "LG $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[548] = parser; +exports.device[569] = parser; parser = Object.create(null); parser[0] = new RegExp("(?:^LG[\\-]?|^LGE[\\-/]?)([A-Za-z]+[0-9]+[A-Za-z]*)"); parser[1] = "LG $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[549] = parser; +exports.device[570] = parser; parser = Object.create(null); parser[0] = new RegExp("^LG([0-9]+[A-Za-z]*)"); parser[1] = "LG $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[550] = parser; +exports.device[571] = parser; parser = Object.create(null); parser[0] = new RegExp("(KIN\\.[^ ]+) (\\d+)\\.(\\d+)"); parser[1] = "Microsoft $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[551] = parser; +exports.device[572] = parser; parser = Object.create(null); -parser[0] = new RegExp("(?:MSIE|XBMC).*\\b(Xbox)\\b"); +parser[0] = new RegExp("(?:MSIE|XBMC).{0,200}\\b(Xbox)\\b"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[552] = parser; +exports.device[573] = parser; parser = Object.create(null); parser[0] = new RegExp("; ARM; Trident/6\\.0; Touch[\\);]"); parser[1] = "Microsoft Surface RT"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[553] = parser; +exports.device[574] = parser; parser = Object.create(null); parser[0] = new RegExp("Motorola\\-([A-Za-z0-9]+)"); parser[1] = "Motorola $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[554] = parser; +exports.device[575] = parser; parser = Object.create(null); parser[0] = new RegExp("MOTO\\-([A-Za-z0-9]+)"); parser[1] = "Motorola $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[555] = parser; +exports.device[576] = parser; parser = Object.create(null); parser[0] = new RegExp("MOT\\-([A-z0-9][A-z0-9\\-]*)"); parser[1] = "Motorola $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[556] = parser; +exports.device[577] = parser; parser = Object.create(null); parser[0] = new RegExp("Nintendo WiiU"); parser[1] = "Nintendo Wii U"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[557] = parser; +exports.device[578] = parser; parser = Object.create(null); parser[0] = new RegExp("Nintendo (DS|3DS|DSi|Wii);"); parser[1] = "Nintendo $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[558] = parser; +exports.device[579] = parser; parser = Object.create(null); parser[0] = new RegExp("(?:Pantech|PANTECH)[ _-]?([A-Za-z0-9\\-]+)"); parser[1] = "Pantech $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[559] = parser; +exports.device[580] = parser; parser = Object.create(null); parser[0] = new RegExp("Philips([A-Za-z0-9]+)"); parser[1] = "Philips $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[560] = parser; +exports.device[581] = parser; parser = Object.create(null); parser[0] = new RegExp("Philips ([A-Za-z0-9]+)"); parser[1] = "Philips $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[561] = parser; +exports.device[582] = parser; parser = Object.create(null); -parser[0] = new RegExp("(SMART-TV); .* Tizen "); +parser[0] = new RegExp("(SMART-TV); .{0,200} Tizen "); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[562] = parser; +exports.device[583] = parser; parser = Object.create(null); -parser[0] = new RegExp("SymbianOS/9\\.\\d.* Samsung[/\\-]([A-Za-z0-9 \\-]+)"); +parser[0] = new RegExp("SymbianOS/9\\.\\d.{0,200} Samsung[/\\-]([A-Za-z0-9 \\-]+)"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[563] = parser; +exports.device[584] = parser; parser = Object.create(null); parser[0] = new RegExp("(Samsung)(SGH)(i[0-9]+)"); parser[1] = "$1 $2$3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[564] = parser; +exports.device[585] = parser; parser = Object.create(null); -parser[0] = new RegExp("SAMSUNG-ANDROID-MMS/([^;/]+)"); +parser[0] = new RegExp("SAMSUNG-ANDROID-MMS/([^;/]{1,100})"); parser[1] = "$1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[565] = parser; +exports.device[586] = parser; parser = Object.create(null); parser[0] = new RegExp("SAMSUNG(?:; |[ -/])([A-Za-z0-9\\-]+)"); parser[1] = "Samsung $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[566] = parser; +exports.device[587] = parser; parser = Object.create(null); parser[0] = new RegExp("(Dreamcast)"); parser[1] = "Sega $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[567] = parser; +exports.device[588] = parser; parser = Object.create(null); parser[0] = new RegExp("^SIE-([A-Za-z0-9]+)"); parser[1] = "Siemens $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[568] = parser; +exports.device[589] = parser; parser = Object.create(null); parser[0] = new RegExp("Softbank/[12]\\.0/([A-Za-z0-9]+)"); parser[1] = "Softbank $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[569] = parser; +exports.device[590] = parser; parser = Object.create(null); parser[0] = new RegExp("SonyEricsson ?([A-Za-z0-9\\-]+)"); parser[1] = "Ericsson $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[570] = parser; +exports.device[591] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android [^;]+; ([^ ]+) (Sony)/"); +parser[0] = new RegExp("Android [^;]{1,200}; ([^ ]+) (Sony)/"); parser[1] = "$2 $1"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[571] = parser; +exports.device[592] = parser; parser = Object.create(null); parser[0] = new RegExp("(Sony)(?:BDP\\/|\\/|)([^ /;\\)]+)[ /;\\)]"); parser[1] = "$1 $2"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[572] = parser; +exports.device[593] = parser; parser = Object.create(null); parser[0] = new RegExp("Puffin/[\\d\\.]+IT"); parser[1] = "iPad"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[573] = parser; +exports.device[594] = parser; parser = Object.create(null); parser[0] = new RegExp("Puffin/[\\d\\.]+IP"); parser[1] = "iPhone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[574] = parser; +exports.device[595] = parser; parser = Object.create(null); parser[0] = new RegExp("Puffin/[\\d\\.]+AT"); parser[1] = "Generic Tablet"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[575] = parser; +exports.device[596] = parser; parser = Object.create(null); parser[0] = new RegExp("Puffin/[\\d\\.]+AP"); parser[1] = "Generic Smartphone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[576] = parser; +exports.device[597] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android[\\- ][\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{0,2}; WOWMobile (.+) Build[/ ]"); +parser[0] = new RegExp("Android[\\- ][\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{0,2}; WOWMobile (.{1,200})( Build[/ ]|\\))"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[577] = parser; +exports.device[598] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android[\\- ][\\d]+\\.[\\d]+\\-update1; [A-Za-z]{2}\\-[A-Za-z]{0,2} *; *(.+?) Build[/ ]"); +parser[0] = new RegExp("Android[\\- ][\\d]+\\.[\\d]+\\-update1; [A-Za-z]{2}\\-[A-Za-z]{0,2} {0,2}; {0,2}(.{1,200}?)( Build[/ ]|\\))"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[578] = parser; +exports.device[599] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); *[A-Za-z]{2}[_\\-][A-Za-z]{0,2}\\-? *; *(.+?) Build[/ ]"); +parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); {0,2}[A-Za-z]{2}[_\\-][A-Za-z]{0,2}\\-? {0,2}; {0,2}(.{1,200}?)( Build[/ ]|\\))"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[579] = parser; +exports.device[600] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); *[A-Za-z]{0,2}\\- *; *(.+?) Build[/ ]"); +parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); {0,2}[A-Za-z]{0,2}\\- {0,2}; {0,2}(.{1,200}?)( Build[/ ]|\\))"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[580] = parser; +exports.device[601] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); *[a-z]{0,2}[_\\-]?[A-Za-z]{0,2};? Build[/ ]"); +parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); {0,2}[a-z]{0,2}[_\\-]?[A-Za-z]{0,2};?( Build[/ ]|\\))"); parser[1] = "Generic Smartphone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[581] = parser; +exports.device[602] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); *\\-?[A-Za-z]{2}; *(.+?) Build[/ ]"); +parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); {0,3}\\-?[A-Za-z]{2}; {0,2}(.{1,50}?)( Build[/ ]|\\))"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[582] = parser; +exports.device[603] = parser; parser = Object.create(null); -parser[0] = new RegExp("Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|)(?:;.*|); *(.+?) Build[/ ]"); +parser[0] = new RegExp("Android \\d+?(?:\\.\\d+|)(?:\\.\\d+|); ([^;]{1,100}?)(?: Build|\\) AppleWebKit).{1,200}? Mobile Safari"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[583] = parser; +exports.device[604] = parser; +parser = Object.create(null); +parser[0] = new RegExp("Android \\d+?(?:\\.\\d+|)(?:\\.\\d+|); ([^;]{1,100}?)(?: Build|\\) AppleWebKit).{1,200}? Safari"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[605] = parser; +parser = Object.create(null); +parser[0] = new RegExp("Android \\d+?(?:\\.\\d+|)(?:\\.\\d+|); ([^;]{1,100}?)(?: Build|\\))"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[606] = parser; parser = Object.create(null); parser[0] = new RegExp("(GoogleTV)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[584] = parser; +exports.device[607] = parser; parser = Object.create(null); parser[0] = new RegExp("(WebTV)/\\d+.\\d+"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[585] = parser; +exports.device[608] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Roku)/DVP-\\d+\\.\\d+"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[586] = parser; +exports.device[609] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Android 3\\.\\d|Opera Tablet|Tablet; .+Firefox/|Android.*(?:Tab|Pad))"); +parser[0] = new RegExp("(Android 3\\.\\d|Opera Tablet|Tablet; .{1,100}Firefox/|Android.{0,100}(?:Tab|Pad))"); parser[1] = "Generic Tablet"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[587] = parser; +exports.device[610] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Symbian|\\bS60(Version|V\\d)|\\bS60\\b|\\((Series 60|Windows Mobile|Palm OS|Bada); Opera Mini|Windows CE|Opera Mobi|BREW|Brew|Mobile; .+Firefox/|iPhone OS|Android|MobileSafari|Windows *Phone|\\(webOS/|PalmOS)"); +parser[0] = new RegExp("(Symbian|\\bS60(Version|V\\d)|\\bS60\\b|\\((Series 60|Windows Mobile|Palm OS|Bada); Opera Mini|Windows CE|Opera Mobi|BREW|Brew|Mobile; .{1,200}Firefox/|iPhone OS|Android|MobileSafari|Windows {0,2}Phone|\\(webOS/|PalmOS)"); parser[1] = "Generic Smartphone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[588] = parser; +exports.device[611] = parser; parser = Object.create(null); parser[0] = new RegExp("(hiptop|avantgo|plucker|xiino|blazer|elaine)"); parser[1] = "Generic Smartphone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[589] = parser; +exports.device[612] = parser; parser = Object.create(null); -parser[0] = new RegExp("(bot|BUbiNG|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|Daum|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|spider|msnbot|msrbot|vortex|^vortex|crawler|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|bingbot|BingPreview|openbot|gigabot|furlbot|polybot|seekbot|^voyager|archiver|Icarus6j|mogimogi|Netvibes|blitzbot|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|SeznamBot|ProoXiBot|wsr\\-agent|Squrl Java|EtaoSpider|PaperLiBot|SputnikBot|A6\\-Indexer|netresearch|searchsight|baiduspider|YisouSpider|ICC\\-Crawler|http%20client|Python-urllib|dataparksearch|converacrawler|Screaming Frog|AppEngine-Google|YahooCacheSystem|fast\\-webcrawler|Sogou Pic Spider|semanticdiscovery|Innovazion Crawler|facebookexternalhit|Google.*/\\+/web/snippet|Google-HTTP-Java-Client|BlogBridge|IlTrovatore-Setaccio|InternetArchive|GomezAgent|WebThumbnail|heritrix|NewsGator|PagePeeker|Reaper|ZooShot|holmes|NL-Crawler|Pingdom|StatusCake|WhatsApp|masscan|Google Web Preview|Qwantify|Yeti)"); +parser[0] = new RegExp("^.{0,100}(bot|BUbiNG|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|Daum|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|spider|msnbot|msrbot|vortex|^vortex|crawler|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|bingbot|BingPreview|openbot|gigabot|furlbot|polybot|seekbot|^voyager|archiver|Icarus6j|mogimogi|Netvibes|blitzbot|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|SeznamBot|ProoXiBot|wsr\\-agent|Squrl Java|EtaoSpider|PaperLiBot|SputnikBot|A6\\-Indexer|netresearch|searchsight|baiduspider|YisouSpider|ICC\\-Crawler|http%20client|Python-urllib|dataparksearch|converacrawler|Screaming Frog|AppEngine-Google|YahooCacheSystem|fast\\-webcrawler|Sogou Pic Spider|semanticdiscovery|Innovazion Crawler|facebookexternalhit|Google.{0,200}/\\+/web/snippet|Google-HTTP-Java-Client|BlogBridge|IlTrovatore-Setaccio|InternetArchive|GomezAgent|WebThumbnail|heritrix|NewsGator|PagePeeker|Reaper|ZooShot|holmes|NL-Crawler|Pingdom|StatusCake|WhatsApp|masscan|Google Web Preview|Qwantify|Yeti|OgScrper)"); parser[1] = "Spider"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[590] = parser; +exports.device[613] = parser; parser = Object.create(null); parser[0] = new RegExp("^(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|bmobile|bell|bird|bw\\-n|bw\\-u|beck|benq|bilb|blac|c55/|cdm\\-|chtm|capi|comp|cond|dall|dbte|dc\\-s|dica|ds\\-d|ds12|dait|devi|dmob|doco|dopo|dorado|el(?:38|39|48|49|50|55|58|68)|el[3456]\\d{2}dual|erk0|esl8|ex300|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)"); parser[1] = "Generic Feature Phone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[591] = parser; +exports.device[614] = parser; parser = Object.create(null); parser[0] = new RegExp("^(htcp|htcs|htct|htc_|haie|hita|huaw|hutc|i\\-20|i\\-go|i\\-ma|i\\-mobile|i230|iac|iac\\-|iac/|ig01|im1k|inno|iris|jata|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/|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)"); parser[1] = "Generic Feature Phone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[592] = parser; +exports.device[615] = parser; parser = Object.create(null); parser[0] = new RegExp("^(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)"); parser[1] = "Generic Feature Phone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[593] = parser; +exports.device[616] = parser; parser = Object.create(null); parser[0] = new RegExp("^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vertu|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_)"); parser[1] = "Generic Feature Phone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[594] = parser; +exports.device[617] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Ice)$"); parser[1] = "Generic Feature Phone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[595] = parser; +exports.device[618] = parser; parser = Object.create(null); parser[0] = new RegExp("(wap[\\-\\ ]browser|maui|netfront|obigo|teleca|up\\.browser|midp|Opera Mini)"); parser[1] = "Generic Feature Phone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.device[596] = parser; +exports.device[619] = parser; +parser = Object.create(null); +parser[0] = new RegExp("Mac OS"); +parser[1] = "Mac"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.device[620] = parser; -exports.device.length = 597; +exports.device.length = 621; exports.os = Object.create(null); @@ -6270,1089 +6774,1243 @@ parser[3] = 0; parser[4] = 0; exports.os[2] = parser; parser = Object.create(null); -parser[0] = new RegExp("HbbTV/\\d+\\.\\d+\\.\\d+ \\(;(Samsung);SmartTV([0-9]{4});.*FXPDEUC"); +parser[0] = new RegExp("HbbTV/\\d+\\.\\d+\\.\\d+ \\(;(Samsung);SmartTV([0-9]{4});.{0,200}FXPDEUC"); parser[1] = 0; parser[2] = 0; parser[3] = "UE40F7000"; parser[4] = 0; exports.os[3] = parser; parser = Object.create(null); -parser[0] = new RegExp("HbbTV/\\d+\\.\\d+\\.\\d+ \\(;(Samsung);SmartTV([0-9]{4});.*MST12DEUC"); +parser[0] = new RegExp("HbbTV/\\d+\\.\\d+\\.\\d+ \\(;(Samsung);SmartTV([0-9]{4});.{0,200}MST12DEUC"); parser[1] = 0; parser[2] = 0; parser[3] = "UE32F4500"; parser[4] = 0; exports.os[4] = parser; parser = Object.create(null); -parser[0] = new RegExp("HbbTV/1\\.1\\.1 \\(; (Philips);.*NETTV/4"); +parser[0] = new RegExp("HbbTV/1\\.1\\.1 \\(; (Philips);.{0,200}NETTV/4"); parser[1] = 0; parser[2] = "2013"; parser[3] = 0; parser[4] = 0; exports.os[5] = parser; parser = Object.create(null); -parser[0] = new RegExp("HbbTV/1\\.1\\.1 \\(; (Philips);.*NETTV/3"); +parser[0] = new RegExp("HbbTV/1\\.1\\.1 \\(; (Philips);.{0,200}NETTV/3"); parser[1] = 0; parser[2] = "2012"; parser[3] = 0; parser[4] = 0; exports.os[6] = parser; parser = Object.create(null); -parser[0] = new RegExp("HbbTV/1\\.1\\.1 \\(; (Philips);.*NETTV/2"); +parser[0] = new RegExp("HbbTV/1\\.1\\.1 \\(; (Philips);.{0,200}NETTV/2"); parser[1] = 0; parser[2] = "2011"; parser[3] = 0; parser[4] = 0; exports.os[7] = parser; parser = Object.create(null); -parser[0] = new RegExp("HbbTV/\\d+\\.\\d+\\.\\d+.*(firetv)-firefox-plugin (\\d+).(\\d+).(\\d+)"); +parser[0] = new RegExp("HbbTV/\\d+\\.\\d+\\.\\d+.{0,100}(firetv)-firefox-plugin (\\d+).(\\d+).(\\d+)"); parser[1] = "FireHbbTV"; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.os[8] = parser; parser = Object.create(null); -parser[0] = new RegExp("HbbTV/\\d+\\.\\d+\\.\\d+ \\(.*; ?([a-zA-Z]+) ?;.*(201[1-9]).*\\)"); +parser[0] = new RegExp("HbbTV/\\d+\\.\\d+\\.\\d+ \\(.{0,30}; ?([a-zA-Z]+) ?;.{0,30}(201[1-9]).{0,30}\\)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; exports.os[9] = parser; parser = Object.create(null); +parser[0] = new RegExp("AspiegelBot"); +parser[1] = "Other"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.os[10] = parser; +parser = Object.create(null); parser[0] = new RegExp("(Windows Phone) (?:OS[ /])?(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[10] = parser; +exports.os[11] = parser; parser = Object.create(null); -parser[0] = new RegExp("(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone)[ +]+(\\d+)[_\\.](\\d+)(?:[_\\.](\\d+)|).*Outlook-iOS-Android"); +parser[0] = new RegExp("(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone)[ +]+(\\d+)[_\\.](\\d+)(?:[_\\.](\\d+)|).{0,100}Outlook-iOS-Android"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[11] = parser; +exports.os[12] = parser; +parser = Object.create(null); +parser[0] = new RegExp("ArcGIS\\.?(iOS|Android)-\\d+\\.\\d+(?:\\.\\d+|)(?:[^\\/]{1,50}|)\\/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.os[13] = parser; +parser = Object.create(null); +parser[0] = new RegExp("ArcGISRuntime-(?:Android|iOS)\\/\\d+\\.\\d+(?:\\.\\d+|) \\((Android|iOS) (\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|);"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.os[14] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android)[ \\-/](\\d+)(?:\\.(\\d+)|)(?:[.\\-]([a-z0-9]+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[12] = parser; +exports.os[15] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Donut"); parser[1] = 0; parser[2] = "1"; parser[3] = "2"; parser[4] = 0; -exports.os[13] = parser; +exports.os[16] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Eclair"); parser[1] = 0; parser[2] = "2"; parser[3] = "1"; parser[4] = 0; -exports.os[14] = parser; +exports.os[17] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Froyo"); parser[1] = 0; parser[2] = "2"; parser[3] = "2"; parser[4] = 0; -exports.os[15] = parser; +exports.os[18] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Gingerbread"); parser[1] = 0; parser[2] = "2"; parser[3] = "3"; parser[4] = 0; -exports.os[16] = parser; +exports.os[19] = parser; parser = Object.create(null); parser[0] = new RegExp("(Android) Honeycomb"); parser[1] = 0; parser[2] = "3"; parser[3] = 0; parser[4] = 0; -exports.os[17] = parser; +exports.os[20] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(Android) (\\d+);"); +parser[1] = 0; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.os[21] = parser; parser = Object.create(null); -parser[0] = new RegExp("^UCWEB.*; (Adr) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+)|);"); +parser[0] = new RegExp("^UCWEB.{0,200}; (Adr) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]{1,100})|);"); parser[1] = "Android"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[18] = parser; +exports.os[22] = parser; parser = Object.create(null); -parser[0] = new RegExp("^UCWEB.*; (iPad|iPh|iPd) OS (\\d+)_(\\d+)(?:_(\\d+)|);"); +parser[0] = new RegExp("^UCWEB.{0,200}; (iPad|iPh|iPd) OS (\\d+)_(\\d+)(?:_(\\d+)|);"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[19] = parser; +exports.os[23] = parser; parser = Object.create(null); -parser[0] = new RegExp("^UCWEB.*; (wds) (\\d+)\\.(\\d+)(?:\\.(\\d+)|);"); +parser[0] = new RegExp("^UCWEB.{0,200}; (wds) (\\d+)\\.(\\d+)(?:\\.(\\d+)|);"); parser[1] = "Windows Phone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[20] = parser; +exports.os[24] = parser; parser = Object.create(null); -parser[0] = new RegExp("^(JUC).*; ?U; ?(?:Android|)(\\d+)\\.(\\d+)(?:[\\.\\-]([a-z0-9]+)|)"); +parser[0] = new RegExp("^(JUC).{0,200}; ?U; ?(?:Android|)(\\d+)\\.(\\d+)(?:[\\.\\-]([a-z0-9]{1,100})|)"); parser[1] = "Android"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[21] = parser; +exports.os[25] = parser; parser = Object.create(null); parser[0] = new RegExp("(android)\\s(?:mobile\\/)(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)"); parser[1] = "Android"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[22] = parser; +exports.os[26] = parser; parser = Object.create(null); parser[0] = new RegExp("(Silk-Accelerated=[a-z]{4,5})"); parser[1] = "Android"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[23] = parser; +exports.os[27] = parser; parser = Object.create(null); -parser[0] = new RegExp("(x86_64|aarch64)\\ (\\d+)\\.(\\d+)\\.(\\d+).*Chrome.*(?:CitrixChromeApp)$"); +parser[0] = new RegExp("(x86_64|aarch64)\\ (\\d+)\\.(\\d+)\\.(\\d+).{0,100}Chrome.{0,100}(?:CitrixChromeApp)$"); parser[1] = "Chrome OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[24] = parser; +exports.os[28] = parser; parser = Object.create(null); parser[0] = new RegExp("(XBLWP7)"); parser[1] = "Windows Phone"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[25] = parser; +exports.os[29] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows ?Mobile)"); parser[1] = "Windows Mobile"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[26] = parser; +exports.os[30] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows 10)"); parser[1] = "Windows"; parser[2] = "10"; parser[3] = 0; parser[4] = 0; -exports.os[27] = parser; +exports.os[31] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows (?:NT 5\\.2|NT 5\\.1))"); parser[1] = "Windows"; parser[2] = "XP"; parser[3] = 0; parser[4] = 0; -exports.os[28] = parser; +exports.os[32] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Windows NT 6\\.1)"); +parser[0] = new RegExp("(Win(?:dows NT |32NT\\/)6\\.1)"); parser[1] = "Windows"; parser[2] = "7"; parser[3] = 0; parser[4] = 0; -exports.os[29] = parser; +exports.os[33] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Windows NT 6\\.0)"); +parser[0] = new RegExp("(Win(?:dows NT |32NT\\/)6\\.0)"); parser[1] = "Windows"; parser[2] = "Vista"; parser[3] = 0; parser[4] = 0; -exports.os[30] = parser; +exports.os[34] = parser; parser = Object.create(null); parser[0] = new RegExp("(Win 9x 4\\.90)"); parser[1] = "Windows"; parser[2] = "ME"; parser[3] = 0; parser[4] = 0; -exports.os[31] = parser; +exports.os[35] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows NT 6\\.2; ARM;)"); parser[1] = "Windows"; parser[2] = "RT"; parser[3] = 0; parser[4] = 0; -exports.os[32] = parser; +exports.os[36] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Windows NT 6\\.2)"); +parser[0] = new RegExp("(Win(?:dows NT |32NT\\/)6\\.2)"); parser[1] = "Windows"; parser[2] = "8"; parser[3] = 0; parser[4] = 0; -exports.os[33] = parser; +exports.os[37] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows NT 6\\.3; ARM;)"); parser[1] = "Windows"; parser[2] = "RT 8"; parser[3] = "1"; parser[4] = 0; -exports.os[34] = parser; +exports.os[38] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Windows NT 6\\.3)"); +parser[0] = new RegExp("(Win(?:dows NT |32NT\\/)6\\.3)"); parser[1] = "Windows"; parser[2] = "8"; parser[3] = "1"; parser[4] = 0; -exports.os[35] = parser; +exports.os[39] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Windows NT 6\\.4)"); +parser[0] = new RegExp("(Win(?:dows NT |32NT\\/)6\\.4)"); parser[1] = "Windows"; parser[2] = "10"; parser[3] = 0; parser[4] = 0; -exports.os[36] = parser; +exports.os[40] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows NT 10\\.0)"); parser[1] = "Windows"; parser[2] = "10"; parser[3] = 0; parser[4] = 0; -exports.os[37] = parser; +exports.os[41] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows NT 5\\.0)"); parser[1] = "Windows"; parser[2] = "2000"; parser[3] = 0; parser[4] = 0; -exports.os[38] = parser; +exports.os[42] = parser; parser = Object.create(null); parser[0] = new RegExp("(WinNT4.0)"); parser[1] = "Windows"; parser[2] = "NT 4.0"; parser[3] = 0; parser[4] = 0; -exports.os[39] = parser; +exports.os[43] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows ?CE)"); parser[1] = "Windows"; parser[2] = "CE"; parser[3] = 0; parser[4] = 0; -exports.os[40] = parser; +exports.os[44] = parser; parser = Object.create(null); parser[0] = new RegExp("Win(?:dows)? ?(95|98|3.1|NT|ME|2000|XP|Vista|7|CE)"); parser[1] = "Windows"; parser[2] = "$1"; parser[3] = 0; parser[4] = 0; -exports.os[41] = parser; +exports.os[45] = parser; parser = Object.create(null); parser[0] = new RegExp("Win16"); parser[1] = "Windows"; parser[2] = "3.1"; parser[3] = 0; parser[4] = 0; -exports.os[42] = parser; +exports.os[46] = parser; parser = Object.create(null); parser[0] = new RegExp("Win32"); parser[1] = "Windows"; parser[2] = "95"; parser[3] = 0; parser[4] = 0; -exports.os[43] = parser; +exports.os[47] = parser; parser = Object.create(null); -parser[0] = new RegExp("^Box.*Windows/([\\d.]+);"); +parser[0] = new RegExp("^Box.{0,200}Windows/([\\d.]+);"); parser[1] = "Windows"; parser[2] = "$1"; parser[3] = 0; parser[4] = 0; -exports.os[44] = parser; +exports.os[48] = parser; parser = Object.create(null); parser[0] = new RegExp("(Tizen)[/ ](\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[45] = parser; +exports.os[49] = parser; parser = Object.create(null); parser[0] = new RegExp("((?:Mac[ +]?|; )OS[ +]X)[\\s+/](?:(\\d+)[_.](\\d+)(?:[_.](\\d+)|)|Mach-O)"); parser[1] = "Mac OS X"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[46] = parser; +exports.os[50] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\w+\\s+Mac OS X\\s+\\w+\\s+(\\d+).(\\d+).(\\d+).*"); +parser[0] = new RegExp("Mac OS X\\s.{1,50}\\s(\\d+).(\\d+).(\\d+)"); parser[1] = "Mac OS X"; parser[2] = "$1"; parser[3] = "$2"; parser[4] = "$3"; -exports.os[47] = parser; +exports.os[51] = parser; parser = Object.create(null); -parser[0] = new RegExp(" (Dar)(win)/(9).(\\d+).*\\((?:i386|x86_64|Power Macintosh)\\)"); +parser[0] = new RegExp(" (Dar)(win)/(9).(\\d+).{0,100}\\((?:i386|x86_64|Power Macintosh)\\)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "5"; parser[4] = 0; -exports.os[48] = parser; +exports.os[52] = parser; parser = Object.create(null); -parser[0] = new RegExp(" (Dar)(win)/(10).(\\d+).*\\((?:i386|x86_64)\\)"); +parser[0] = new RegExp(" (Dar)(win)/(10).(\\d+).{0,100}\\((?:i386|x86_64)\\)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "6"; parser[4] = 0; -exports.os[49] = parser; +exports.os[53] = parser; parser = Object.create(null); -parser[0] = new RegExp(" (Dar)(win)/(11).(\\d+).*\\((?:i386|x86_64)\\)"); +parser[0] = new RegExp(" (Dar)(win)/(11).(\\d+).{0,100}\\((?:i386|x86_64)\\)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "7"; parser[4] = 0; -exports.os[50] = parser; +exports.os[54] = parser; parser = Object.create(null); -parser[0] = new RegExp(" (Dar)(win)/(12).(\\d+).*\\((?:i386|x86_64)\\)"); +parser[0] = new RegExp(" (Dar)(win)/(12).(\\d+).{0,100}\\((?:i386|x86_64)\\)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "8"; parser[4] = 0; -exports.os[51] = parser; +exports.os[55] = parser; parser = Object.create(null); -parser[0] = new RegExp(" (Dar)(win)/(13).(\\d+).*\\((?:i386|x86_64)\\)"); +parser[0] = new RegExp(" (Dar)(win)/(13).(\\d+).{0,100}\\((?:i386|x86_64)\\)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "9"; parser[4] = 0; -exports.os[52] = parser; +exports.os[56] = parser; parser = Object.create(null); parser[0] = new RegExp("Mac_PowerPC"); parser[1] = "Mac OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[53] = parser; +exports.os[57] = parser; parser = Object.create(null); parser[0] = new RegExp("(?:PPC|Intel) (Mac OS X)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[54] = parser; +exports.os[58] = parser; parser = Object.create(null); -parser[0] = new RegExp("^Box.*;(Darwin)/(10)\\.(1\\d)(?:\\.(\\d+)|)"); +parser[0] = new RegExp("^Box.{0,200};(Darwin)/(10)\\.(1\\d)(?:\\.(\\d+)|)"); parser[1] = "Mac OS X"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[55] = parser; +exports.os[59] = parser; parser = Object.create(null); parser[0] = new RegExp("(Apple\\s?TV)(?:/(\\d+)\\.(\\d+)|)"); parser[1] = "ATV OS X"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[56] = parser; +exports.os[60] = parser; parser = Object.create(null); -parser[0] = new RegExp("(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS)[ +]+(\\d+)[_\\.](\\d+)(?:[_\\.](\\d+)|)"); +parser[0] = new RegExp("(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS|CPU iPad OS)[ +]+(\\d+)[_\\.](\\d+)(?:[_\\.](\\d+)|)"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[57] = parser; +exports.os[61] = parser; parser = Object.create(null); parser[0] = new RegExp("(iPhone|iPad|iPod); Opera"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[58] = parser; +exports.os[62] = parser; parser = Object.create(null); -parser[0] = new RegExp("(iPhone|iPad|iPod).*Mac OS X.*Version/(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(iPhone|iPad|iPod).{0,100}Mac OS X.{0,100}Version/(\\d+)\\.(\\d+)"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[59] = parser; +exports.os[63] = parser; parser = Object.create(null); -parser[0] = new RegExp("(CFNetwork)/(5)48\\.0\\.3.* Darwin/11\\.0\\.0"); +parser[0] = new RegExp("(CFNetwork)/(5)48\\.0\\.3.{0,100} Darwin/11\\.0\\.0"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[60] = parser; +exports.os[64] = parser; parser = Object.create(null); -parser[0] = new RegExp("(CFNetwork)/(5)48\\.(0)\\.4.* Darwin/(1)1\\.0\\.0"); +parser[0] = new RegExp("(CFNetwork)/(5)48\\.(0)\\.4.{0,100} Darwin/(1)1\\.0\\.0"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[61] = parser; +exports.os[65] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)/(5)48\\.(1)\\.4"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[62] = parser; +exports.os[66] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)/(4)85\\.1(3)\\.9"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[63] = parser; +exports.os[67] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)/(6)09\\.(1)\\.4"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[64] = parser; +exports.os[68] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)/(6)(0)9"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[65] = parser; +exports.os[69] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)/6(7)2\\.(1)\\.13"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[66] = parser; +exports.os[70] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)/6(7)2\\.(1)\\.(1)4"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[67] = parser; +exports.os[71] = parser; parser = Object.create(null); parser[0] = new RegExp("(CF)(Network)/6(7)(2)\\.1\\.15"); parser[1] = "iOS"; parser[2] = "7"; parser[3] = "1"; parser[4] = 0; -exports.os[68] = parser; +exports.os[72] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)/6(7)2\\.(0)\\.(?:2|8)"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[69] = parser; +exports.os[73] = parser; parser = Object.create(null); parser[0] = new RegExp("(CFNetwork)/709\\.1"); parser[1] = "iOS"; parser[2] = "8"; parser[3] = "0.b5"; parser[4] = 0; -exports.os[70] = parser; +exports.os[74] = parser; parser = Object.create(null); parser[0] = new RegExp("(CF)(Network)/711\\.(\\d)"); parser[1] = "iOS"; parser[2] = "8"; parser[3] = 0; parser[4] = 0; -exports.os[71] = parser; +exports.os[75] = parser; parser = Object.create(null); parser[0] = new RegExp("(CF)(Network)/(720)\\.(\\d)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "10"; parser[4] = 0; -exports.os[72] = parser; +exports.os[76] = parser; parser = Object.create(null); parser[0] = new RegExp("(CF)(Network)/(760)\\.(\\d)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "11"; parser[4] = 0; -exports.os[73] = parser; +exports.os[77] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/7.* Darwin/15\\.4\\.\\d+"); +parser[0] = new RegExp("CFNetwork/7.{0,100} Darwin/15\\.4\\.\\d+"); parser[1] = "iOS"; parser[2] = "9"; parser[3] = "3"; parser[4] = "1"; -exports.os[74] = parser; +exports.os[78] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/7.* Darwin/15\\.5\\.\\d+"); +parser[0] = new RegExp("CFNetwork/7.{0,100} Darwin/15\\.5\\.\\d+"); parser[1] = "iOS"; parser[2] = "9"; parser[3] = "3"; parser[4] = "2"; -exports.os[75] = parser; +exports.os[79] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/7.* Darwin/15\\.6\\.\\d+"); +parser[0] = new RegExp("CFNetwork/7.{0,100} Darwin/15\\.6\\.\\d+"); parser[1] = "iOS"; parser[2] = "9"; parser[3] = "3"; parser[4] = "5"; -exports.os[76] = parser; +exports.os[80] = parser; parser = Object.create(null); parser[0] = new RegExp("(CF)(Network)/758\\.(\\d)"); parser[1] = "iOS"; parser[2] = "9"; parser[3] = 0; parser[4] = 0; -exports.os[77] = parser; +exports.os[81] = parser; parser = Object.create(null); parser[0] = new RegExp("CFNetwork/808\\.3 Darwin/16\\.3\\.\\d+"); parser[1] = "iOS"; parser[2] = "10"; parser[3] = "2"; parser[4] = "1"; -exports.os[78] = parser; +exports.os[82] = parser; parser = Object.create(null); parser[0] = new RegExp("(CF)(Network)/808\\.(\\d)"); parser[1] = "iOS"; parser[2] = "10"; parser[3] = 0; parser[4] = 0; -exports.os[79] = parser; +exports.os[83] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/17\\.\\d+.*\\(x86_64\\)"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/17\\.\\d+.{0,100}\\(x86_64\\)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "13"; parser[4] = 0; -exports.os[80] = parser; +exports.os[84] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/16\\.\\d+.*\\(x86_64\\)"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/16\\.\\d+.{0,100}\\(x86_64\\)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "12"; parser[4] = 0; -exports.os[81] = parser; +exports.os[85] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/15\\.\\d+.*\\(x86_64\\)"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/15\\.\\d+.{0,100}\\(x86_64\\)"); parser[1] = "Mac OS X"; parser[2] = "10"; parser[3] = "11"; parser[4] = 0; -exports.os[82] = parser; +exports.os[86] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/(9)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/(9)\\.\\d+"); parser[1] = "iOS"; parser[2] = "1"; parser[3] = 0; parser[4] = 0; -exports.os[83] = parser; +exports.os[87] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/(10)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/(10)\\.\\d+"); parser[1] = "iOS"; parser[2] = "4"; parser[3] = 0; parser[4] = 0; -exports.os[84] = parser; +exports.os[88] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/(11)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/(11)\\.\\d+"); parser[1] = "iOS"; parser[2] = "5"; parser[3] = 0; parser[4] = 0; -exports.os[85] = parser; +exports.os[89] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/(13)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/(13)\\.\\d+"); parser[1] = "iOS"; parser[2] = "6"; parser[3] = 0; parser[4] = 0; -exports.os[86] = parser; +exports.os[90] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/6.* Darwin/(14)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/6.{0,100} Darwin/(14)\\.\\d+"); parser[1] = "iOS"; parser[2] = "7"; parser[3] = 0; parser[4] = 0; -exports.os[87] = parser; +exports.os[91] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/7.* Darwin/(14)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/7.{0,100} Darwin/(14)\\.\\d+"); parser[1] = "iOS"; parser[2] = "8"; parser[3] = "0"; parser[4] = 0; -exports.os[88] = parser; +exports.os[92] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/7.* Darwin/(15)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/7.{0,100} Darwin/(15)\\.\\d+"); parser[1] = "iOS"; parser[2] = "9"; parser[3] = "0"; parser[4] = 0; -exports.os[89] = parser; +exports.os[93] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/16\\.5\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/16\\.5\\.\\d+"); parser[1] = "iOS"; parser[2] = "10"; parser[3] = "3"; parser[4] = 0; -exports.os[90] = parser; +exports.os[94] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/16\\.6\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/16\\.6\\.\\d+"); parser[1] = "iOS"; parser[2] = "10"; parser[3] = "3"; parser[4] = "2"; -exports.os[91] = parser; +exports.os[95] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/16\\.7\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/16\\.7\\.\\d+"); parser[1] = "iOS"; parser[2] = "10"; parser[3] = "3"; parser[4] = "3"; -exports.os[92] = parser; +exports.os[96] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/(16)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/(16)\\.\\d+"); parser[1] = "iOS"; parser[2] = "10"; parser[3] = 0; parser[4] = 0; -exports.os[93] = parser; +exports.os[97] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/17\\.0\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/17\\.0\\.\\d+"); parser[1] = "iOS"; parser[2] = "11"; parser[3] = "0"; parser[4] = 0; -exports.os[94] = parser; +exports.os[98] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/17\\.2\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/17\\.2\\.\\d+"); parser[1] = "iOS"; parser[2] = "11"; parser[3] = "1"; parser[4] = 0; -exports.os[95] = parser; +exports.os[99] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/17\\.3\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/17\\.3\\.\\d+"); parser[1] = "iOS"; parser[2] = "11"; parser[3] = "2"; parser[4] = 0; -exports.os[96] = parser; +exports.os[100] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/17\\.4\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/17\\.4\\.\\d+"); parser[1] = "iOS"; parser[2] = "11"; parser[3] = "2"; parser[4] = "6"; -exports.os[97] = parser; +exports.os[101] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/17\\.5\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/17\\.5\\.\\d+"); parser[1] = "iOS"; parser[2] = "11"; parser[3] = "3"; parser[4] = 0; -exports.os[98] = parser; +exports.os[102] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/9.* Darwin/17\\.6\\.\\d+"); +parser[0] = new RegExp("CFNetwork/9.{0,100} Darwin/17\\.6\\.\\d+"); parser[1] = "iOS"; parser[2] = "11"; parser[3] = "4"; parser[4] = 0; -exports.os[99] = parser; +exports.os[103] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/9.* Darwin/17\\.7\\.\\d+"); +parser[0] = new RegExp("CFNetwork/9.{0,100} Darwin/17\\.7\\.\\d+"); parser[1] = "iOS"; parser[2] = "11"; parser[3] = "4"; parser[4] = "1"; -exports.os[100] = parser; +exports.os[104] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/8.* Darwin/(17)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/8.{0,100} Darwin/(17)\\.\\d+"); parser[1] = "iOS"; parser[2] = "11"; parser[3] = 0; parser[4] = 0; -exports.os[101] = parser; +exports.os[105] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/9.* Darwin/18\\.0\\.\\d+"); +parser[0] = new RegExp("CFNetwork/9.{0,100} Darwin/18\\.0\\.\\d+"); parser[1] = "iOS"; parser[2] = "12"; parser[3] = "0"; parser[4] = 0; -exports.os[102] = parser; +exports.os[106] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/9.{0,100} Darwin/18\\.2\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "12"; +parser[3] = "1"; +parser[4] = 0; +exports.os[107] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/9.{0,100} Darwin/18\\.5\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "12"; +parser[3] = "2"; +parser[4] = 0; +exports.os[108] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/9.{0,100} Darwin/18\\.6\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "12"; +parser[3] = "3"; +parser[4] = 0; +exports.os[109] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/9.{0,100} Darwin/18\\.7\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "12"; +parser[3] = "4"; +parser[4] = 0; +exports.os[110] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/9.* Darwin/(18)\\.\\d+"); +parser[0] = new RegExp("CFNetwork/9.{0,100} Darwin/(18)\\.\\d+"); parser[1] = "iOS"; parser[2] = "12"; parser[3] = 0; parser[4] = 0; -exports.os[103] = parser; +exports.os[111] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/11.{0,100} Darwin/19\\.2\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "13"; +parser[3] = "3"; +parser[4] = 0; +exports.os[112] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/11.{0,100} Darwin/19\\.3\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "13"; +parser[3] = "3"; +parser[4] = "1"; +exports.os[113] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/11.{0,100} Darwin/19\\.4\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "13"; +parser[3] = "4"; +parser[4] = 0; +exports.os[114] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/11.{0,100} Darwin/19\\.5\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "13"; +parser[3] = "5"; +parser[4] = 0; +exports.os[115] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/11.{0,100} Darwin/19\\.6\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "13"; +parser[3] = "6"; +parser[4] = 0; +exports.os[116] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/1[01].{0,100} Darwin/19\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "13"; +parser[3] = 0; +parser[4] = 0; +exports.os[117] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/12.{0,100} Darwin/20\\.1\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "14"; +parser[3] = "2"; +parser[4] = 0; +exports.os[118] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/12.{0,100} Darwin/20\\.2\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "14"; +parser[3] = "3"; +parser[4] = 0; +exports.os[119] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/12.{0,100} Darwin/20\\.3\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "14"; +parser[3] = "4"; +parser[4] = 0; +exports.os[120] = parser; parser = Object.create(null); -parser[0] = new RegExp("CFNetwork/.* Darwin/"); +parser[0] = new RegExp("CFNetwork/12.{0,100} Darwin/20\\.4\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "14"; +parser[3] = "5"; +parser[4] = 0; +exports.os[121] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/(20)\\.\\d+"); +parser[1] = "iOS"; +parser[2] = "14"; +parser[3] = 0; +parser[4] = 0; +exports.os[122] = parser; +parser = Object.create(null); +parser[0] = new RegExp("CFNetwork/.{0,100} Darwin/"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[104] = parser; +exports.os[123] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(iOS[ /]|iOS; |iPhone(?:/| v|[ _]OS[/,]|; | OS : |\\d,\\d/|\\d,\\d; )|iPad/)(\\d{1,2})[_\\.](\\d{1,2})(?:[_\\.](\\d+)|)"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[105] = parser; +exports.os[124] = parser; parser = Object.create(null); parser[0] = new RegExp("\\((iOS);"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[106] = parser; +exports.os[125] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(watchOS)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "WatchOS"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.os[126] = parser; parser = Object.create(null); parser[0] = new RegExp("Outlook-(iOS)/\\d+\\.\\d+\\.prod\\.iphone"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[107] = parser; +exports.os[127] = parser; parser = Object.create(null); parser[0] = new RegExp("(iPod|iPhone|iPad)"); parser[1] = "iOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[108] = parser; +exports.os[128] = parser; parser = Object.create(null); parser[0] = new RegExp("(tvOS)[/ ](\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "tvOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[109] = parser; +exports.os[129] = parser; parser = Object.create(null); parser[0] = new RegExp("(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "Chrome OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[110] = parser; +exports.os[130] = parser; parser = Object.create(null); parser[0] = new RegExp("([Dd]ebian)"); parser[1] = "Debian"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[111] = parser; +exports.os[131] = parser; parser = Object.create(null); parser[0] = new RegExp("(Linux Mint)(?:/(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[112] = parser; +exports.os[132] = parser; parser = Object.create(null); parser[0] = new RegExp("(Mandriva)(?: Linux|)/(?:[\\d.-]+m[a-z]{2}(\\d+).(\\d)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[113] = parser; +exports.os[133] = parser; parser = Object.create(null); parser[0] = new RegExp("(Symbian[Oo][Ss])[/ ](\\d+)\\.(\\d+)"); parser[1] = "Symbian OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[114] = parser; +exports.os[134] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Symbian/3).+NokiaBrowser/7\\.3"); +parser[0] = new RegExp("(Symbian/3).{1,200}NokiaBrowser/7\\.3"); parser[1] = "Symbian^3 Anna"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[115] = parser; +exports.os[135] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Symbian/3).+NokiaBrowser/7\\.4"); +parser[0] = new RegExp("(Symbian/3).{1,200}NokiaBrowser/7\\.4"); parser[1] = "Symbian^3 Belle"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[116] = parser; +exports.os[136] = parser; parser = Object.create(null); parser[0] = new RegExp("(Symbian/3)"); parser[1] = "Symbian^3"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[117] = parser; +exports.os[137] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(Series 60|SymbOS|S60Version|S60V\\d|S60\\b)"); parser[1] = "Symbian OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[118] = parser; +exports.os[138] = parser; parser = Object.create(null); parser[0] = new RegExp("(MeeGo)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[119] = parser; +exports.os[139] = parser; parser = Object.create(null); parser[0] = new RegExp("Symbian [Oo][Ss]"); parser[1] = "Symbian OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[120] = parser; +exports.os[140] = parser; parser = Object.create(null); parser[0] = new RegExp("Series40;"); parser[1] = "Nokia Series 40"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[121] = parser; +exports.os[141] = parser; parser = Object.create(null); parser[0] = new RegExp("Series30Plus;"); parser[1] = "Nokia Series 30 Plus"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[122] = parser; +exports.os[142] = parser; parser = Object.create(null); -parser[0] = new RegExp("(BB10);.+Version/(\\d+)\\.(\\d+)\\.(\\d+)"); +parser[0] = new RegExp("(BB10);.{1,200}Version/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "BlackBerry OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[123] = parser; +exports.os[143] = parser; parser = Object.create(null); parser[0] = new RegExp("(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "BlackBerry OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[124] = parser; +exports.os[144] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Black[Bb]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[0] = new RegExp("(Black[Bb]erry).{1,200}Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "BlackBerry OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[125] = parser; +exports.os[145] = parser; parser = Object.create(null); parser[0] = new RegExp("(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "BlackBerry Tablet OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[126] = parser; +exports.os[146] = parser; parser = Object.create(null); parser[0] = new RegExp("(Play[Bb]ook)"); parser[1] = "BlackBerry Tablet OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[127] = parser; +exports.os[147] = parser; parser = Object.create(null); parser[0] = new RegExp("(Black[Bb]erry)"); parser[1] = "BlackBerry OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[128] = parser; +exports.os[148] = parser; +parser = Object.create(null); +parser[0] = new RegExp("(K[Aa][Ii]OS)\\/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); +parser[1] = "KaiOS"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.os[149] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\((?:Mobile|Tablet);.+Gecko/18.0 Firefox/\\d+\\.\\d+"); +parser[0] = new RegExp("\\((?:Mobile|Tablet);.{1,200}Gecko/18.0 Firefox/\\d+\\.\\d+"); parser[1] = "Firefox OS"; parser[2] = "1"; parser[3] = "0"; parser[4] = "1"; -exports.os[129] = parser; +exports.os[150] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\((?:Mobile|Tablet);.+Gecko/18.1 Firefox/\\d+\\.\\d+"); +parser[0] = new RegExp("\\((?:Mobile|Tablet);.{1,200}Gecko/18.1 Firefox/\\d+\\.\\d+"); parser[1] = "Firefox OS"; parser[2] = "1"; parser[3] = "1"; parser[4] = 0; -exports.os[130] = parser; +exports.os[151] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\((?:Mobile|Tablet);.+Gecko/26.0 Firefox/\\d+\\.\\d+"); +parser[0] = new RegExp("\\((?:Mobile|Tablet);.{1,200}Gecko/26.0 Firefox/\\d+\\.\\d+"); parser[1] = "Firefox OS"; parser[2] = "1"; parser[3] = "2"; parser[4] = 0; -exports.os[131] = parser; +exports.os[152] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\((?:Mobile|Tablet);.+Gecko/28.0 Firefox/\\d+\\.\\d+"); +parser[0] = new RegExp("\\((?:Mobile|Tablet);.{1,200}Gecko/28.0 Firefox/\\d+\\.\\d+"); parser[1] = "Firefox OS"; parser[2] = "1"; parser[3] = "3"; parser[4] = 0; -exports.os[132] = parser; +exports.os[153] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\((?:Mobile|Tablet);.+Gecko/30.0 Firefox/\\d+\\.\\d+"); +parser[0] = new RegExp("\\((?:Mobile|Tablet);.{1,200}Gecko/30.0 Firefox/\\d+\\.\\d+"); parser[1] = "Firefox OS"; parser[2] = "1"; parser[3] = "4"; parser[4] = 0; -exports.os[133] = parser; +exports.os[154] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\((?:Mobile|Tablet);.+Gecko/32.0 Firefox/\\d+\\.\\d+"); +parser[0] = new RegExp("\\((?:Mobile|Tablet);.{1,200}Gecko/32.0 Firefox/\\d+\\.\\d+"); parser[1] = "Firefox OS"; parser[2] = "2"; parser[3] = "0"; parser[4] = 0; -exports.os[134] = parser; +exports.os[155] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\((?:Mobile|Tablet);.+Gecko/34.0 Firefox/\\d+\\.\\d+"); +parser[0] = new RegExp("\\((?:Mobile|Tablet);.{1,200}Gecko/34.0 Firefox/\\d+\\.\\d+"); parser[1] = "Firefox OS"; parser[2] = "2"; parser[3] = "1"; parser[4] = 0; -exports.os[135] = parser; +exports.os[156] = parser; parser = Object.create(null); -parser[0] = new RegExp("\\((?:Mobile|Tablet);.+Firefox/\\d+\\.\\d+"); +parser[0] = new RegExp("\\((?:Mobile|Tablet);.{1,200}Firefox/\\d+\\.\\d+"); parser[1] = "Firefox OS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[136] = parser; +exports.os[157] = parser; parser = Object.create(null); parser[0] = new RegExp("(BREW)[ /](\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[137] = parser; +exports.os[158] = parser; parser = Object.create(null); parser[0] = new RegExp("(BREW);"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[138] = parser; +exports.os[159] = parser; parser = Object.create(null); parser[0] = new RegExp("(Brew MP|BMP)[ /](\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Brew MP"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[139] = parser; +exports.os[160] = parser; parser = Object.create(null); parser[0] = new RegExp("BMP;"); parser[1] = "Brew MP"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[140] = parser; +exports.os[161] = parser; parser = Object.create(null); parser[0] = new RegExp("(GoogleTV)(?: (\\d+)\\.(\\d+)(?:\\.(\\d+)|)|/[\\da-z]+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[141] = parser; +exports.os[162] = parser; parser = Object.create(null); parser[0] = new RegExp("(WebTV)/(\\d+).(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[142] = parser; +exports.os[163] = parser; parser = Object.create(null); parser[0] = new RegExp("(CrKey)(?:[/](\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)"); parser[1] = "Chromecast"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[143] = parser; +exports.os[164] = parser; parser = Object.create(null); parser[0] = new RegExp("(hpw|web)OS/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = "webOS"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[144] = parser; +exports.os[165] = parser; parser = Object.create(null); parser[0] = new RegExp("(VRE);"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[145] = parser; +exports.os[166] = parser; parser = Object.create(null); parser[0] = new RegExp("(Fedora|Red Hat|PCLinuxOS|Puppy|Ubuntu|Kindle|Bada|Sailfish|Lubuntu|BackTrack|Slackware|(?:Free|Open|Net|\\b)BSD)[/ ](\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[146] = parser; +exports.os[167] = parser; parser = Object.create(null); -parser[0] = new RegExp("(Linux)[ /](\\d+)\\.(\\d+)(?:\\.(\\d+)|).*gentoo"); +parser[0] = new RegExp("(Linux)[ /](\\d+)\\.(\\d+)(?:\\.(\\d+)|).{0,100}gentoo"); parser[1] = "Gentoo"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[147] = parser; +exports.os[168] = parser; parser = Object.create(null); parser[0] = new RegExp("\\((Bada);"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[148] = parser; +exports.os[169] = parser; parser = Object.create(null); parser[0] = new RegExp("(Windows|Android|WeTab|Maemo|Web0S)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[149] = parser; +exports.os[170] = parser; parser = Object.create(null); parser[0] = new RegExp("(Ubuntu|Kubuntu|Arch Linux|CentOS|Slackware|Gentoo|openSUSE|SUSE|Red Hat|Fedora|PCLinuxOS|Mageia|(?:Free|Open|Net|\\b)BSD)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[150] = parser; +exports.os[171] = parser; parser = Object.create(null); parser[0] = new RegExp("(Linux)(?:[ /](\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[151] = parser; +exports.os[172] = parser; parser = Object.create(null); parser[0] = new RegExp("SunOS"); parser[1] = "Solaris"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[152] = parser; +exports.os[173] = parser; parser = Object.create(null); parser[0] = new RegExp("\\(linux-gnu\\)"); parser[1] = "Linux"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[153] = parser; +exports.os[174] = parser; parser = Object.create(null); parser[0] = new RegExp("\\(x86_64-redhat-linux-gnu\\)"); parser[1] = "Red Hat"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[154] = parser; +exports.os[175] = parser; parser = Object.create(null); parser[0] = new RegExp("\\((freebsd)(\\d+)\\.(\\d+)\\)"); parser[1] = "FreeBSD"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[155] = parser; +exports.os[176] = parser; +parser = Object.create(null); +parser[0] = new RegExp("linux"); +parser[1] = "Linux"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.os[177] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Roku)/DVP-(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[156] = parser; +exports.os[178] = parser; parser = Object.create(null); parser[0] = new RegExp("(iOS) (\\d+)\\.(\\d+)(?:\\.(\\d+))?"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.os[157] = parser; +exports.os[179] = parser; -exports.os.length = 158; \ No newline at end of file +exports.os.length = 180; \ No newline at end of file diff --git a/lib/update.js b/lib/update.js index 1447f97..d949f62 100644 --- a/lib/update.js +++ b/lib/update.js @@ -15,37 +15,14 @@ var request = require('request') , yaml = require('yamlparser'); /** - * Local modules. - */ -var old = require('./regexps'); - -function getKnown(old) { - var known = new Set(); - for (var type in old) { - if (!old.hasOwnProperty(type)) continue; - var group = old[type]; - for (var i = 0; i < group.length; i++) { - var regex = group[i][0].source; - known.add(regex); - } - } - return known; -} - -var known = getKnown(old); - -function isSafe(source) { - if (!/[+*{].*[+*{]/.test(source)) return true; // -35% - return false; -} - -/** - * Update the regexps.js file + * Update the regexp.js file * + * @param {String} remote optional remote URL for regex source * @param {Function} callback Completion callback. * @api public */ -exports.update = function update(callback) { +exports.update = function update(remote, callback) { + if (remote !== undefined) exports.remote = remote; // Prepend local additions that are missing from the source fs.readFile(exports.before, 'utf8', function reading(err, before) { if (err) return callback(err); @@ -70,8 +47,10 @@ exports.update = function update(callback) { // tmp.file(function (err, tempFilePath) { if (err) return; + fs.writeFile(tempFilePath, source, function idk(err) { if (err) return + fs.rename(tempFilePath, exports.output, function(err) { }); @@ -91,7 +70,6 @@ exports.update = function update(callback) { * @api public */ exports.parse = function parse(sources, callback) { - var unsafe = []; var results = {}; var data = sources.reduce(function parser(memo, data) { @@ -146,29 +124,16 @@ exports.parse = function parse(sources, callback) { var resources = data[details.resource] , name = details.resource.replace('_parsers', '') , resource - , regex - , source , parser; for (var i = 0, l = resources.length; i < l; i++) { resource = resources[i]; - regex = resource.regex; - - source = new RegExp(regex).source; - if (!known.has(source)) { - // A quick check, regexes not matching those are clearly safe - // This check excludes about 35% of all regexps we have - if (!isSafe(source)) { - unsafe.push(source); - } - known.add(source); - } // We need to JSON stringify the data to properly add slashes escape other // kinds of crap in the RegularExpression. If we don't do thing we get // some illegal token warnings. parser = 'parser = Object.create(null);\n'; - parser += 'parser[0] = new RegExp('+ JSON.stringify(regex) + ');\n'; + parser += 'parser[0] = new RegExp('+ JSON.stringify(resource.regex) + ');\n'; // Check if we have replacement for the parsed family name if (resource[details.replacement]) { @@ -207,16 +172,6 @@ exports.parse = function parse(sources, callback) { } }); - if (unsafe.length > 0) { - console.log('There are new regexps! Here they are, one per line:'); - for (var i = 0; i < unsafe.length; i++) { - console.log(' ' + unsafe[i]); - } - console.log('Those might be potentially unsafe and cause ReDoS.'); - console.log('Make sure to take them through Weideman\'s tool and to inspect them!'); - console.log('See https://github.com/NicolaasWeideman/RegexStaticAnalysis'); - } - // Generate a correct format exports.generate(results, callback); }; @@ -267,7 +222,7 @@ exports.generate = function generate(results, callback) { * @type {String} * @api private */ -exports.remote = process.env.USERAGENT_REMOTE ? process.env.USERAGENT_REMOTE : 'https://raw.githubusercontent.com/ua-parser/uap-core/master/regexes.yaml'; +exports.remote = 'https://raw.githubusercontent.com/ua-parser/uap-core/master/regexes.yaml'; /** * The locations of our local regexes yaml files. diff --git a/test/parser.test.js b/test/parser.test.js index 48d05d8..ac0ed01 100644 --- a/test/parser.test.js +++ b/test/parser.test.js @@ -42,7 +42,7 @@ describe('useragent', function () { assume(agent.device).is.instanceOf(useragent.Device) }); - it('correctly parsers the operating system', function () { + it('correctly parses the operating system', function () { var os = useragent.parse(ua).os; assume(os.toString()).equals('Mac OS X 10.7.1'); @@ -96,7 +96,7 @@ describe('useragent', function () { assume(agent.toVersion()).equals('15.0.874'); assume(agent.toString()).equals('Chrome 15.0.874 / Mac OS X 10.7.1'); assume(agent.toAgent()).equals('Chrome 15.0.874'); - assume(JSON.stringify(agent)).equals('{"family":"Chrome","major":"15","minor":"0","patch":"874","device":{"family":"Other","major":"0","minor":"0","patch":"0"},"os":{"family":"Mac OS X","major":"10","minor":"7","patch":"1"}}'); + assume(agent.device.family).equals("Mac"); }); it('correctly parses iOS8', function () { From 0afe8aa7434af571f788c966c3c894152c0dfe79 Mon Sep 17 00:00:00 2001 From: Sam Brown Date: Thu, 9 Sep 2021 16:33:02 -0700 Subject: [PATCH 2/4] Update interface is backwards compatible. --- bin/update.js | 2 +- index.js | 25 +- lib/update.js | 66 +++- package-lock.json | 811 ++++++++++++++++++++++++++++++++++++++++++++ test/parser.test.js | 18 +- 5 files changed, 905 insertions(+), 17 deletions(-) create mode 100644 package-lock.json diff --git a/bin/update.js b/bin/update.js index e5ae941..28c2501 100755 --- a/bin/update.js +++ b/bin/update.js @@ -5,7 +5,7 @@ /** * Update our definition file. */ -require('../lib/update').update(undefined, function updating(err, data) { +require('../lib/update').update(function updating(err, data) { if (err) { console.error('Update unsuccessfull due to reasons'); console.log(err.message); diff --git a/index.js b/index.js index bfe8919..a5559c7 100644 --- a/index.js +++ b/index.js @@ -357,13 +357,14 @@ Device.prototype.toJSON = function toJSON() { /** * Small nifty thick that allows us to download a fresh set regexs from a remote - * source. Package uses the compiled version by default, but allow for updating from - * the default source (no args) or a custom source, via the `remote` parameter. + * source. Package uses the compiled version by default, but allows for updating + * from the default source (no args) or a custom source, via the "remote" + * parameter. * - * @param {String} remote optionally specify a custom URL for regex sourcing + * @param {String} [remote] optionally specify a custom URL for regex sourcing * @api public */ -module.exports = function updater(remote) { + module.exports = function updater(remote) { try { require('./lib/update').update(remote, function updating(err, results) { if (err) { @@ -415,10 +416,15 @@ function isSafe(userAgent) { var consecutive = 0 , code = 0; + if (userAgent.length > 1000) return false; + for (var i = 0; i < userAgent.length; i++) { code = userAgent.charCodeAt(i); - // numbers between 0 and 9, letters between a and z - if ((code >= 48 && code <= 57) || (code >= 97 && code <= 122)) { + if ((code >= 48 && code <= 57) || // numbers + (code >= 65 && code <= 90) || // letters A-Z + (code >= 97 && code <= 122) || // letters a-z + code <= 32 // spaces and control + ) { consecutive++; } else { consecutive = 0; @@ -443,6 +449,10 @@ function isSafe(userAgent) { * @api public */ exports.parse = function parse(userAgent, jsAgent) { + if (userAgent && userAgent.length > 1000) { + userAgent = userAgent.substring(0, 1000); + } + if (!userAgent || !isSafe(userAgent)) return new Agent(); var length = agentparserslength @@ -506,7 +516,8 @@ exports.parse = function parse(userAgent, jsAgent) { * @param {String} jsAgent Optional UA from js to detect chrome frame * @api public */ -var LRU = require('lru-cache')(5000); +var lruCache = require('lru-cache'); +var LRU = new lruCache(5000); exports.lookup = function lookup(userAgent, jsAgent) { var key = (userAgent || '')+(jsAgent || '') , cached = LRU.get(key); diff --git a/lib/update.js b/lib/update.js index d949f62..288c05c 100644 --- a/lib/update.js +++ b/lib/update.js @@ -15,14 +15,44 @@ var request = require('request') , yaml = require('yamlparser'); /** - * Update the regexp.js file + * Local modules. + */ +var old = require('./regexps'); + +function getKnown(old) { + var known = new Set(); + for (var type in old) { + if (!old.hasOwnProperty(type)) continue; + var group = old[type]; + for (var i = 0; i < group.length; i++) { + var regex = group[i][0].source; + known.add(regex); + } + } + return known; +} + +var known = getKnown(old); + +function isSafe(source) { + if (!/[+*{].*[+*{]/.test(source)) return true; // -35% + return false; +} + +/** + * Update the regexps.js file * - * @param {String} remote optional remote URL for regex source + * @param {String} [remote] optional remote URL for regex source * @param {Function} callback Completion callback. * @api public */ -exports.update = function update(remote, callback) { + exports.update = function update() { + let remote, callback; + + if (arguments.length === 2) [remote, callback] = arguments; + else if (arguments.length === 1) [callback] = arguments; if (remote !== undefined) exports.remote = remote; + // Prepend local additions that are missing from the source fs.readFile(exports.before, 'utf8', function reading(err, before) { if (err) return callback(err); @@ -47,10 +77,8 @@ exports.update = function update(remote, callback) { // tmp.file(function (err, tempFilePath) { if (err) return; - fs.writeFile(tempFilePath, source, function idk(err) { if (err) return - fs.rename(tempFilePath, exports.output, function(err) { }); @@ -70,6 +98,7 @@ exports.update = function update(remote, callback) { * @api public */ exports.parse = function parse(sources, callback) { + var unsafe = []; var results = {}; var data = sources.reduce(function parser(memo, data) { @@ -124,16 +153,29 @@ exports.parse = function parse(sources, callback) { var resources = data[details.resource] , name = details.resource.replace('_parsers', '') , resource + , regex + , source , parser; for (var i = 0, l = resources.length; i < l; i++) { resource = resources[i]; + regex = resource.regex; + + source = new RegExp(regex).source; + if (!known.has(source)) { + // A quick check, regexes not matching those are clearly safe + // This check excludes about 35% of all regexps we have + if (!isSafe(source)) { + unsafe.push(source); + } + known.add(source); + } // We need to JSON stringify the data to properly add slashes escape other // kinds of crap in the RegularExpression. If we don't do thing we get // some illegal token warnings. parser = 'parser = Object.create(null);\n'; - parser += 'parser[0] = new RegExp('+ JSON.stringify(resource.regex) + ');\n'; + parser += 'parser[0] = new RegExp('+ JSON.stringify(regex) + ');\n'; // Check if we have replacement for the parsed family name if (resource[details.replacement]) { @@ -172,6 +214,16 @@ exports.parse = function parse(sources, callback) { } }); + if (unsafe.length > 0) { + console.log('There are new regexps! Here they are, one per line:'); + for (var i = 0; i < unsafe.length; i++) { + console.log(' ' + unsafe[i]); + } + console.log('Those might be potentially unsafe and cause ReDoS.'); + console.log('Make sure to take them through Weideman\'s tool and to inspect them!'); + console.log('See https://github.com/NicolaasWeideman/RegexStaticAnalysis'); + } + // Generate a correct format exports.generate(results, callback); }; @@ -222,7 +274,7 @@ exports.generate = function generate(results, callback) { * @type {String} * @api private */ -exports.remote = 'https://raw.githubusercontent.com/ua-parser/uap-core/master/regexes.yaml'; +exports.remote = process.env.USERAGENT_REMOTE ? process.env.USERAGENT_REMOTE : 'https://raw.githubusercontent.com/ua-parser/uap-core/master/regexes.yaml'; /** * The locations of our local regexes yaml files. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..118f046 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,811 @@ +{ + "name": "useragent", + "version": "2.3.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assume": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/assume/-/assume-1.5.2.tgz", + "integrity": "sha512-/IDWcpPTGjUsf4lcMi837n3xFxkEBVEfVxOvYUgdU3y6FjWSWzXiUzFAYlulr94kr79mNbiOFC5isJmaQn2C2w==", + "dev": true, + "requires": { + "deep-eql": "0.1.x", + "fn.name": "1.0.x", + "object-inspect": "1.0.x", + "pathval": "0.1.x", + "pruddy-error": "1.0.x" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fn.name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.0.1.tgz", + "integrity": "sha1-gBWtFJwQEaEWzbieukzBHZA5rdg=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "dev": true + }, + "mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "dev": true, + "requires": { + "mime-db": "1.49.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.5.tgz", + "integrity": "sha512-3MM3UjZ5p8EJrYpG7s+29HAI9G7sTzKEe4+w37Dg0QP7qL4XGsV+Q2xet2cE37AqdgN1OtYQB6Vl98YiPV3PgA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-inspect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.0.2.tgz", + "integrity": "sha1-qXiFtVPldetACevAm92psc0hl5o=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-0.1.1.tgz", + "integrity": "sha1-CPkRzcqczllCiA2ngXvAtyO2bYI=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pre-commit": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", + "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "spawn-sync": "^1.0.15", + "which": "1.2.x" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "pruddy-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pruddy-error/-/pruddy-error-1.0.2.tgz", + "integrity": "sha1-s37Bo4v5EHwM3FvGY9PU6ANUroA=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "spawn-sync": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", + "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", + "dev": true, + "requires": { + "concat-stream": "^1.4.7", + "os-shim": "^0.1.2" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + } + } + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yamlparser": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/yamlparser/-/yamlparser-0.0.2.tgz", + "integrity": "sha1-Mjk+avxwyMoGa2ZQrGc4tIFnjrw=", + "dev": true + } + } +} diff --git a/test/parser.test.js b/test/parser.test.js index ac0ed01..7954b73 100644 --- a/test/parser.test.js +++ b/test/parser.test.js @@ -84,7 +84,7 @@ describe('useragent', function () { assume(JSON.stringify(agent)).equals('{"family":"Other","major":"0","minor":"0","patch":"0","device":{"family":"Other","major":"0","minor":"0","patch":"0"},"os":{"family":"Other","major":"0","minor":"0","patch":"0"}}'); }); - it('should correctly parse chromes user agent', function () { + it('should correctly parse the Chrome user agent', function () { var agent = useragent.parse(ua); assume(agent.family).equals('Chrome'); @@ -96,7 +96,21 @@ describe('useragent', function () { assume(agent.toVersion()).equals('15.0.874'); assume(agent.toString()).equals('Chrome 15.0.874 / Mac OS X 10.7.1'); assume(agent.toAgent()).equals('Chrome 15.0.874'); - assume(agent.device.family).equals("Mac"); + assume(JSON.stringify(agent)).equals('{"family":"Chrome","major":"15","minor":"0","patch":"874","device":{"family":"Mac","major":"0","minor":"0","patch":"0"},"os":{"family":"Mac OS X","major":"10","minor":"7","patch":"1"}}'); + }); + + it('should correctly parse the Apple Mail user agent', function () { + var agent = useragent.parse('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko)'); + + assume(agent.family).equals('Apple Mail'); + assume(agent.major).equals('605'); + assume(agent.minor).equals('1'); + assume(agent.patch).equals('15'); + + assume(agent.os.toString()).equals('Mac OS X 10.15.3'); + assume(agent.toVersion()).equals('605.1.15'); + assume(agent.toString()).equals('Apple Mail 605.1.15 / Mac OS X 10.15.3'); + assume(agent.toAgent()).equals('Apple Mail 605.1.15'); }); it('correctly parses iOS8', function () { From e87d6b685b52a287650cfa2f4bfb838d6cd9941f Mon Sep 17 00:00:00 2001 From: Sam Brown Date: Thu, 9 Sep 2021 17:08:08 -0700 Subject: [PATCH 3/4] Increment package version. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0a4bcd5..b356273 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "useragent", - "version": "2.3.0", + "version": "2.3.1", "description": "Fastest, most accurate & effecient user agent string parser, uses Browserscope's research for parsing", "author": "Arnout Kazemier", "main": "./index.js", From 5d16abcb79a2dce08ec32c9de8cbea8a5ad2de53 Mon Sep 17 00:00:00 2001 From: Sam Brown Date: Wed, 13 Oct 2021 14:38:46 -0700 Subject: [PATCH 4/4] Catch new apple mail user agent. --- lib/regexps.js | 61 ++++++++++++++++++++++++++++---------------------- lib/update.js | 2 +- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/lib/regexps.js b/lib/regexps.js index 8c5a576..bbca2fd 100644 --- a/lib/regexps.js +++ b/lib/regexps.js @@ -2214,189 +2214,196 @@ parser[3] = 0; parser[4] = 0; exports.browser[312] = parser; parser = Object.create(null); +parser[0] = new RegExp("^(Mozilla/5\\.0)$"); +parser[1] = "Apple Mail"; +parser[2] = 0; +parser[3] = 0; +parser[4] = 0; +exports.browser[313] = parser; +parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[313] = parser; +exports.browser[314] = parser; parser = Object.create(null); parser[0] = new RegExp("(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[314] = parser; +exports.browser[315] = parser; parser = Object.create(null); parser[0] = new RegExp("([MS]?IE) (\\d+)\\.(\\d+)"); parser[1] = "IE"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[315] = parser; +exports.browser[316] = parser; parser = Object.create(null); parser[0] = new RegExp("(python-requests)/(\\d+)\\.(\\d+)"); parser[1] = "Python Requests"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[316] = parser; +exports.browser[317] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(Windows-Update-Agent|WindowsPowerShell|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|PycURL|Wget|wget2|aria2|Axel|OpenBSD ftp|lftp|jupdate|insomnia|fetch libfetch|akka-http|got|CloudCockpitBackend|ReactorNetty|axios|Jersey|Vert.x-WebClient|Apache-CXF|Go-CF-client|go-resty|AHC)(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[317] = parser; +exports.browser[318] = parser; parser = Object.create(null); parser[0] = new RegExp("^(cf)\\/(\\d+)\\.(\\d+)\\.(\\S+)"); parser[1] = "CloudFoundry"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[318] = parser; +exports.browser[319] = parser; parser = Object.create(null); parser[0] = new RegExp("^(sap-leonardo-iot-sdk-nodejs) \\/ (\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[319] = parser; +exports.browser[320] = parser; parser = Object.create(null); parser[0] = new RegExp("^(SAP NetWeaver Application Server) \\(1.0;(\\d{1})(\\d{2})\\)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[320] = parser; +exports.browser[321] = parser; parser = Object.create(null); parser[0] = new RegExp("^(\\w+-HTTPClient)\\/(\\d+)\\.(\\d+)-(\\S+)"); parser[1] = "HTTPClient"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[321] = parser; +exports.browser[322] = parser; parser = Object.create(null); parser[0] = new RegExp("^(go-cli)\\s(\\d+)\\.(\\d+).(\\S+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[322] = parser; +exports.browser[323] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Java-EurekaClient|Java-EurekaClient-Replication|HTTPClient|lua-resty-http)\\/v?(\\d+)\\.(\\d+)\\.?(\\d*)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[323] = parser; +exports.browser[324] = parser; parser = Object.create(null); parser[0] = new RegExp("^(ping-service|sap xsuaa|Node-oauth|Site24x7|SAP CPI|JAEGER_SECURITY)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[324] = parser; +exports.browser[325] = parser; parser = Object.create(null); parser[0] = new RegExp("(Python/3\\.\\d{1,3} aiohttp)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Python aiohttp"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[325] = parser; +exports.browser[326] = parser; parser = Object.create(null); parser[0] = new RegExp("(Java)[/ ]?\\d+\\.(\\d+)\\.(\\d+)[_-]*([a-zA-Z0-9]+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[326] = parser; +exports.browser[327] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Cyberduck)/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.\\d+|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[327] = parser; +exports.browser[328] = parser; parser = Object.create(null); parser[0] = new RegExp("^(S3 Browser) (\\d+)-(\\d+)-(\\d+)(?:\\s*http://s3browser\\.com|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[328] = parser; +exports.browser[329] = parser; parser = Object.create(null); parser[0] = new RegExp("(S3Gof3r)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[329] = parser; +exports.browser[330] = parser; parser = Object.create(null); parser[0] = new RegExp("\\b(ibm-cos-sdk-(?:core|java|js|python))/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[330] = parser; +exports.browser[331] = parser; parser = Object.create(null); parser[0] = new RegExp("^(rusoto)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[331] = parser; +exports.browser[332] = parser; parser = Object.create(null); parser[0] = new RegExp("^(rclone)/v(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[332] = parser; +exports.browser[333] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Roku)/DVP-(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[333] = parser; +exports.browser[334] = parser; parser = Object.create(null); parser[0] = new RegExp("(Kurio)\\/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "Kurio App"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[334] = parser; +exports.browser[335] = parser; parser = Object.create(null); parser[0] = new RegExp("^(Box(?: Sync)?)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[335] = parser; +exports.browser[336] = parser; parser = Object.create(null); parser[0] = new RegExp("^(ViaFree|Viafree)-(?:tvOS-)?[A-Z]{2}/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "ViaFree"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[336] = parser; +exports.browser[337] = parser; parser = Object.create(null); parser[0] = new RegExp("(Wget)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)"); parser[1] = 0; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[337] = parser; +exports.browser[338] = parser; parser = Object.create(null); parser[0] = new RegExp("(curl)/(\\d+)\\.(\\d+)\\.(\\d+)"); parser[1] = "cURL"; parser[2] = 0; parser[3] = 0; parser[4] = 0; -exports.browser[338] = parser; +exports.browser[339] = parser; -exports.browser.length = 339; +exports.browser.length = 340; exports.device = Object.create(null); diff --git a/lib/update.js b/lib/update.js index 288c05c..6682f2c 100644 --- a/lib/update.js +++ b/lib/update.js @@ -274,7 +274,7 @@ exports.generate = function generate(results, callback) { * @type {String} * @api private */ -exports.remote = process.env.USERAGENT_REMOTE ? process.env.USERAGENT_REMOTE : 'https://raw.githubusercontent.com/ua-parser/uap-core/master/regexes.yaml'; +exports.remote = process.env.USERAGENT_REMOTE ? process.env.USERAGENT_REMOTE : 'https://raw.githubusercontent.com/this-sam/uap-core/master/regexes.yaml'; /** * The locations of our local regexes yaml files.