# -*- coding: utf-8 -*- ############################################ # NOTICE: This file is autogenerated from # # regexes.yaml. Do not edit by hand, # # instead, re-run `setup.py build_regexes` # ############################################ from __future__ import absolute_import, unicode_literals from .user_agent_parser import ( UserAgentParser, DeviceParser, OSParser, ) __all__ = ( 'USER_AGENT_PARSERS', 'DEVICE_PARSERS', 'OS_PARSERS', ) USER_AGENT_PARSERS = [ UserAgentParser( '(ESPN)[%20| ]+Radio/(\\d+)\\.(\\d+)\\.(\\d+) CFNetwork', None, None, None, ), UserAgentParser( '(Antenna)/(\\d+) CFNetwork', 'AntennaPod', None, None, ), UserAgentParser( '(TopPodcasts)Pro/(\\d+) CFNetwork', None, None, None, ), UserAgentParser( '(MusicDownloader)Lite/(\\d+)\\.(\\d+)\\.(\\d+) CFNetwork', None, None, None, ), UserAgentParser( '^(.*)-iPad/(\\d+)\\.?(\\d+)?.?(\\d+)?.?(\\d+)? CFNetwork', None, None, None, ), UserAgentParser( '^(.*)-iPhone/(\\d+)\\.?(\\d+)?.?(\\d+)?.?(\\d+)? CFNetwork', None, None, None, ), UserAgentParser( '^(.*)/(\\d+)\\.?(\\d+)?.?(\\d+)?.?(\\d+)? CFNetwork', None, None, None, ), UserAgentParser( '(espn\\.go)', 'ESPN', None, None, ), UserAgentParser( '(espnradio\\.com)', 'ESPN', None, None, ), UserAgentParser( 'ESPN APP$', 'ESPN', None, None, ), UserAgentParser( '(audioboom\\.com)', 'AudioBoom', None, None, ), UserAgentParser( ' (Rivo) RHYTHM', None, None, None, ), UserAgentParser( '(CFNetwork)(?:/(\\d+)\\.(\\d+)\\.?(\\d+)?)?', 'CFNetwork', None, None, ), UserAgentParser( '(Pingdom.com_bot_version_)(\\d+)\\.(\\d+)', 'PingdomBot', None, None, ), UserAgentParser( '(PingdomTMS)/(\\d+)\\.(\\d+)\\.(\\d+)', 'PingdomBot', None, None, ), UserAgentParser( '(NewRelicPinger)/(\\d+)\\.(\\d+)', 'NewRelicPingerBot', None, None, ), UserAgentParser( '(Tableau)/(\\d+)\\.(\\d+)', 'Tableau', None, None, ), UserAgentParser( '(\\(StatusCake\\))', 'StatusCakeBot', None, None, ), UserAgentParser( '(facebookexternalhit)/(\\d+)\\.(\\d+)', 'FacebookBot', None, None, ), UserAgentParser( 'Google.*/\\+/web/snippet', 'GooglePlusBot', None, None, ), UserAgentParser( 'via ggpht.com GoogleImageProxy', 'GmailImageProxy', None, None, ), UserAgentParser( '(Twitterbot)/(\\d+)\\.(\\d+)', 'TwitterBot', None, None, ), UserAgentParser( '/((?:Ant-)?Nutch|[A-z]+[Bb]ot|[A-z]+[Ss]pider|Axtaris|fetchurl|Isara|ShopSalad|Tailsweep)[ \\-](\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?', None, None, None, ), UserAgentParser( '\\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+))?)?', None, None, None, ), UserAgentParser( '(MSIE) (\\d+)\\.(\\d+)([a-z]\\d?)?;.* MSIECrawler', 'MSIECrawler', None, None, ), UserAgentParser( '(DAVdroid)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( '(Google-HTTP-Java-Client|Apache-HttpClient|http%20client|Python-urllib|HttpMonitor|TLSProber|WinHTTP|JNLP|okhttp)(?:[ /](\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?)?', None, None, None, ), UserAgentParser( '(Pinterest(?:bot)?)/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?[;\\s\\(]+\\+https://www.pinterest.com/bot.html', 'Pinterestbot', None, None, ), UserAgentParser( '(1470\\.net crawler|50\\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]+-Agent|AdsBot-Google(?:-[a-z]+)?|altavista|AppEngine-Google|archive.*?\\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]+)*|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader(?: [A-Za-z]+)*|boitho.com-dc|BotSeer|BUbiNG|\\b\\w*favicon\\w*\\b|\\bYeti(?:-[a-z]+)?|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]+-)?Googlebot(?:-[a-zA-Z]+)?|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]+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 .*? Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media *)?|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]*|^NING|Nutch[^/]*|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]+|WhatWeb|WIRE|WordPress|Wotbox|www\\.almaden\\.ibm\\.com|Xenu(?:.s)? Link Sleuth|Xerka [A-z]+Bot|yacy(?:bot)?|Yahoo[a-z]*Seeker|Yahoo! Slurp|Yandex\\w+|YodaoBot(?:-[A-z]+)?|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\\.ze\\.bz|ZooShot|ZyBorg)(?:[ /]v?(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?)?', None, None, None, ), UserAgentParser( '(?:\\/[A-Za-z0-9\\.]+)? *([A-Za-z0-9 \\-_\\!\\[\\]:]*(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]*))/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?', None, None, None, ), UserAgentParser( '(?:\\/[A-Za-z0-9\\.]+)? *([A-Za-z0-9 _\\!\\[\\]:]*(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]*)) (\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?', None, None, None, ), UserAgentParser( '((?:[A-z0-9]+|[A-z\\-]+ ?)?(?: the )?(?:[Ss][Pp][Ii][Dd][Ee][Rr]|[Ss]crape|[A-Za-z0-9-]*(?:[^C][^Uu])[Bb]ot|[Cc][Rr][Aa][Ww][Ll])[A-z0-9]*)(?:(?:[ /]| v)(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?)?', None, None, None, ), UserAgentParser( '(HbbTV)/(\\d+)\\.(\\d+)\\.(\\d+) \\(', None, None, None, ), UserAgentParser( '(Chimera|SeaMonkey|Camino)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)?', None, None, None, ), UserAgentParser( '\\[FB.*;(FBAV)/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?', 'Facebook', None, None, ), UserAgentParser( '\\[(Pinterest)/[^\\]]+\\]', None, None, None, ), UserAgentParser( '(Pinterest)(?: for Android(?: Tablet)?)?/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?', None, None, None, ), UserAgentParser( '(PaleMoon)/(\\d+)\\.(\\d+)\\.?(\\d+)?', 'Pale Moon', None, None, ), UserAgentParser( '(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)', 'Firefox Mobile', None, None, ), UserAgentParser( '(Fennec)/(\\d+)\\.(\\d+)(pre)', 'Firefox Mobile', None, None, ), UserAgentParser( '(Fennec)/(\\d+)\\.(\\d+)', 'Firefox Mobile', None, None, ), UserAgentParser( '(?:Mobile|Tablet);.*(Firefox)/(\\d+)\\.(\\d+)', 'Firefox Mobile', None, None, ), UserAgentParser( '(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?)', 'Firefox ($1)', None, None, ), UserAgentParser( '(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)', 'Firefox Alpha', None, None, ), UserAgentParser( '(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)', 'Firefox Beta', None, None, ), UserAgentParser( '(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(a\\d+[a-z]*)', 'Firefox Alpha', None, None, ), UserAgentParser( '(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(b\\d+[a-z]*)', 'Firefox Beta', None, None, ), UserAgentParser( '(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?', 'Firefox ($1)', None, None, ), UserAgentParser( '(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)', 'MicroB', None, None, ), UserAgentParser( '(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?', None, None, None, ), UserAgentParser( '(FxiOS)/(\\d+)\\.(\\d+)(\\.(\\d+))?(\\.(\\d+))?', 'Firefox iOS', None, None, ), UserAgentParser( '(Flock)/(\\d+)\\.(\\d+)(b\\d+?)', None, None, None, ), UserAgentParser( '(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Netscape', None, None, ), UserAgentParser( '(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)', 'Netscape', None, None, ), UserAgentParser( '(Netscape6)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+)?', 'Netscape', None, None, ), UserAgentParser( '(MyIBrow)/(\\d+)\\.(\\d+)', 'My Internet Browser', None, None, ), UserAgentParser( '(UC? ?Browser|UCWEB|U3)[ /]?(\\d+)\\.(\\d+)\\.(\\d+)', 'UC Browser', None, None, ), UserAgentParser( '(Opera Tablet).*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( '(Opera Mini)(?:/att)?/?(\\d+)?(?:\\.(\\d+))?(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( '(Opera)/.+Opera Mobi.+Version/(\\d+)\\.(\\d+)', 'Opera Mobile', None, None, ), UserAgentParser( '(Opera)/(\\d+)\\.(\\d+).+Opera Mobi', 'Opera Mobile', None, None, ), UserAgentParser( 'Opera Mobi.+(Opera)(?:/|\\s+)(\\d+)\\.(\\d+)', 'Opera Mobile', None, None, ), UserAgentParser( 'Opera Mobi', 'Opera Mobile', None, None, ), UserAgentParser( '(Opera)/9.80.*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( '(?:Mobile Safari).*(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Opera Mobile', None, None, ), UserAgentParser( '(?:Chrome).*(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Opera', None, None, ), UserAgentParser( '(Coast)/(\\d+).(\\d+).(\\d+)', 'Opera Coast', None, None, ), UserAgentParser( '(OPiOS)/(\\d+).(\\d+).(\\d+)', 'Opera Mini', None, None, ), UserAgentParser( 'Chrome/.+( MMS)/(\\d+).(\\d+).(\\d+)', 'Opera Neon', None, None, ), UserAgentParser( '(hpw|web)OS/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'webOS Browser', None, None, ), UserAgentParser( '(luakit)', 'LuaKit', None, None, ), UserAgentParser( '(Snowshoe)/(\\d+)\\.(\\d+).(\\d+)', None, None, None, ), UserAgentParser( 'Gecko/\\d+ (Lightning)/(\\d+)\\.(\\d+)\\.?((?:[ab]?\\d+[a-z]*)|(?:\\d*))', None, None, None, ), UserAgentParser( '(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?) \\(Swiftfox\\)', 'Swiftfox', None, None, ), UserAgentParser( '(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)? \\(Swiftfox\\)', 'Swiftfox', None, None, ), UserAgentParser( '(rekonq)/(\\d+)\\.(\\d+)\\.?(\\d+)? Safari', 'Rekonq', None, None, ), UserAgentParser( 'rekonq', 'Rekonq', None, None, ), UserAgentParser( '(conkeror|Conkeror)/(\\d+)\\.(\\d+)\\.?(\\d+)?', 'Conkeror', None, None, ), UserAgentParser( '(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Konqueror', None, None, ), UserAgentParser( '(WeTab)-Browser', None, None, None, ), UserAgentParser( '(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Comodo Dragon', None, None, ), UserAgentParser( '(Symphony) (\\d+).(\\d+)', None, None, None, ), UserAgentParser( 'PLAYSTATION 3.+WebKit', 'NetFront NX', None, None, ), UserAgentParser( 'PLAYSTATION 3', 'NetFront', None, None, ), UserAgentParser( '(PlayStation Portable)', 'NetFront', None, None, ), UserAgentParser( '(PlayStation Vita)', 'NetFront NX', None, None, ), UserAgentParser( 'AppleWebKit.+ (NX)/(\\d+)\\.(\\d+)\\.(\\d+)', 'NetFront NX', None, None, ), UserAgentParser( '(Nintendo 3DS)', 'NetFront NX', None, None, ), UserAgentParser( '(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?', 'Amazon Silk', None, None, ), UserAgentParser( '(Puffin)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( 'Windows Phone .*(Edge)/(\\d+)\\.(\\d+)', 'Edge Mobile', None, None, ), UserAgentParser( '(SamsungBrowser)/(\\d+)\\.(\\d+)', 'Samsung Internet', None, None, ), UserAgentParser( '(SznProhlizec)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', u'Seznam prohl\xed\u017ee\u010d', None, None, ), UserAgentParser( '(coc_coc_browser)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'Coc Coc', None, None, ), UserAgentParser( '(baidubrowser)[/\\s](\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?', 'Baidu Browser', None, None, ), UserAgentParser( '(FlyFlow)/(\\d+)\\.(\\d+)', 'Baidu Explorer', None, None, ), UserAgentParser( '(MxBrowser)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'Maxthon', None, None, ), UserAgentParser( '(Crosswalk)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '; wv\\).+(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Mobile WebView', None, None, ), UserAgentParser( '(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Mobile', None, None, ), UserAgentParser( '(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Mobile iOS', None, None, ), UserAgentParser( '(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile(?:[ /]|$)', 'Chrome Mobile', None, None, ), UserAgentParser( ' Mobile .*(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Mobile', None, None, ), UserAgentParser( '(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Frame', None, None, ), UserAgentParser( '(SLP Browser)/(\\d+)\\.(\\d+)', 'Tizen Browser', None, None, ), UserAgentParser( '(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)', 'Sogou Explorer', None, None, ), UserAgentParser( '(MQQBrowser/Mini)(?:(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?)?', 'QQ Browser Mini', None, None, ), UserAgentParser( '(MQQBrowser)(?:/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?)?', 'QQ Browser Mobile', None, None, ), UserAgentParser( '(QQBrowser)(?:/(\\d+)(?:\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?)?)?', 'QQ Browser', None, None, ), UserAgentParser( '(Rackspace Monitoring)/(\\d+)\\.(\\d+)', 'RackspaceBot', None, None, ), UserAgentParser( '(PyAMF)/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(YaBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Yandex Browser', None, None, ), UserAgentParser( '(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+).* MRCHROME', 'Mail.ru Chromium Browser', None, None, ), UserAgentParser( '(AOL) (\\d+)\\.(\\d+); AOLBuild (\\d+)', None, None, None, ), UserAgentParser( '(PodCruncher|Downcast)[ /]?(\\d+)\\.?(\\d+)?\\.?(\\d+)?\\.?(\\d+)?', None, None, None, ), UserAgentParser( ' (BoxNotes)/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Slack_SSB)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Slack Desktop Client', None, None, ), UserAgentParser( '(HipChat)/?(\\d+)?', 'HipChat Desktop Client', None, None, ), UserAgentParser( '\\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+)', None, None, None, ), UserAgentParser( 'Microsoft Office Outlook 12\\.\\d+\\.\\d+|MSOffice 12', 'Outlook', '2007', None, ), UserAgentParser( 'Microsoft Outlook 14\\.\\d+\\.\\d+|MSOffice 14', 'Outlook', '2010', None, ), UserAgentParser( 'Microsoft Outlook 15\\.\\d+\\.\\d+', 'Outlook', '2013', None, ), UserAgentParser( 'Microsoft Outlook (?:Mail )?16\\.\\d+\\.\\d+', 'Outlook', '2016', None, ), UserAgentParser( 'Outlook-Express\\/7\\.0.*', 'Windows Live Mail', None, None, ), UserAgentParser( '(Airmail) (\\d+)\\.(\\d+)(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( '(Thunderbird)/(\\d+)\\.(\\d+)(?:\\.(\\d+(?:pre)?))?', 'Thunderbird', None, None, ), UserAgentParser( '(Postbox)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Postbox', None, None, ), UserAgentParser( '(Barca(?:Pro)?)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'Barca', None, None, ), UserAgentParser( '(Lotus-Notes)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'Lotus Notes', None, None, ), UserAgentParser( '(Vivaldi)/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Edge)/(\\d+)(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( '(brave)/(\\d+)\\.(\\d+)\\.(\\d+) Chrome', 'Brave', None, None, ), UserAgentParser( '(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)[\\d.]* Iron[^/]', 'Iron', None, None, ), UserAgentParser( '\\b(Dolphin)(?: |HDCN/|/INT\\-)(\\d+)\\.(\\d+)\\.?(\\d+)?', None, None, None, ), UserAgentParser( '(HeadlessChrome)(?:/(\\d+)\\.(\\d+)\\.(\\d+))?', None, None, None, ), UserAgentParser( '(Evolution)/(\\d+)\\.(\\d+)\\.(\\d+\\.\\d+)', None, None, None, ), UserAgentParser( '(RCM CardDAV plugin)/(\\d+)\\.(\\d+)\\.(\\d+(?:-dev)?)', None, None, None, ), UserAgentParser( '(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+))?', None, None, None, ), UserAgentParser( '(Chromium|Chrome)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( '(IEMobile)[ /](\\d+)\\.(\\d+)', 'IE Mobile', None, None, ), UserAgentParser( '(BacaBerita App)\\/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '^(bPod|Pocket Casts|Player FM)$', None, None, None, ), UserAgentParser( '^(AlexaMediaPlayer|VLC)/(\\d+)\\.(\\d+)\\.([^.\\s]+)', None, None, None, ), UserAgentParser( '^(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+)?', None, None, None, ), UserAgentParser( '^(Peapod|Liferea)/([^.\\s]+)\\.([^.\\s]+)?\\.?([^.\\s]+)?', None, None, None, ), UserAgentParser( '^(bPod|Player FM) BMID/(\\S+)', None, None, None, ), UserAgentParser( '^(Podcast ?Addict)/v(\\d+) ', None, None, None, ), UserAgentParser( '^(Podcast ?Addict) ', 'PodcastAddict', None, None, ), UserAgentParser( '(Replay) AV', None, None, None, ), UserAgentParser( '(VOX) Music Player', None, None, None, ), UserAgentParser( '(CITA) RSS Aggregator/(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Pocket Casts)$', None, None, None, ), UserAgentParser( '(Player FM)$', None, None, None, ), UserAgentParser( '(LG Player|Doppler|FancyMusic|MediaMonkey|Clementine) (\\d+)\\.(\\d+)\\.?([^.\\s]+)?\\.?([^.\\s]+)?', None, None, None, ), UserAgentParser( '(philpodder)/(\\d+)\\.(\\d+)\\.?([^.\\s]+)?\\.?([^.\\s]+)?', None, None, None, ), UserAgentParser( '(Player FM|Pocket Casts|DoggCatcher|Spotify|MediaMonkey|MediaGo|BashPodder)', None, None, None, ), UserAgentParser( '(QuickTime)\\.(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Kinoma)(\\d+)', None, None, None, ), UserAgentParser( '(Fancy) Cloud Music (\\d+)\\.(\\d+)', 'FancyMusic', None, None, ), UserAgentParser( 'EspnDownloadManager', 'ESPN', None, None, ), UserAgentParser( '(ESPN) Radio (\\d+)\\.(\\d+)\\.?(\\d+)? ?(?:rv:(\\d+))? ', None, None, None, ), UserAgentParser( '(podracer|jPodder) v ?(\\d+)\\.(\\d+)\\.?(\\d+)?', None, None, None, ), UserAgentParser( '(ZDM)/(\\d+)\\.(\\d+)[; ]?', None, None, None, ), UserAgentParser( '(Zune|BeyondPod) (\\d+)\\.?(\\d+)?[\\);]', None, None, None, ), UserAgentParser( '(WMPlayer)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '^(Lavf)', 'WMPlayer', None, None, ), UserAgentParser( '^(RSSRadio)[ /]?(\\d+)?', None, None, None, ), UserAgentParser( '(RSS_Radio) (\\d+)\\.(\\d+)', 'RSSRadio', None, None, ), UserAgentParser( '(Podkicker) \\S+/(\\d+)\\.(\\d+)\\.(\\d+)', 'Podkicker', None, None, ), UserAgentParser( '^(HTC) Streaming Player \\S+ / \\S+ / \\S+ / (\\d+)\\.(\\d+)\\.?(\\d+)?', None, None, None, ), UserAgentParser( '^(Stitcher)/iOS', None, None, None, ), UserAgentParser( '^(Stitcher)/Android', None, None, None, ), UserAgentParser( '^(VLC) .*version (\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( ' (VLC) for', None, None, None, ), UserAgentParser( '(vlc)/(\\d+)\\.(\\d+)\\.(\\d+)', 'VLC', None, None, ), UserAgentParser( '^(foobar)\\S+/([^.\\s]+)\\.([^.\\s]+)?\\.?([^.\\s]+)?', None, None, None, ), UserAgentParser( '^(Clementine)\\S+ ([^.\\s]+)\\.([^.\\s]+)?\\.?([^.\\s]+)?', None, None, None, ), UserAgentParser( '(amarok)/([^.\\s]+)\\.([^.\\s]+)?\\.?([^.\\s]+)?', 'Amarok', None, None, ), UserAgentParser( '(Custom)-Feed Reader', None, None, None, ), UserAgentParser( '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(iCab|Lunascape|Opera|Android|Jasmine|Polaris|Microsoft SkyDriveSync|The Bat!) (\\d+)\\.(\\d+)\\.?(\\d+)?', None, None, None, ), UserAgentParser( '(Kindle)/(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Android) Donut', None, '1', '2', ), UserAgentParser( '(Android) Eclair', None, '2', '1', ), UserAgentParser( '(Android) Froyo', None, '2', '2', ), UserAgentParser( '(Android) Gingerbread', None, '2', '3', ), UserAgentParser( '(Android) Honeycomb', None, '3', None, ), UserAgentParser( '(MSIE) (\\d+)\\.(\\d+).*XBLWP7', 'IE Large Screen', None, None, ), UserAgentParser( '(Nextcloud)', None, None, None, ), UserAgentParser( '(mirall)/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(ownCloud-android)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Owncloud', None, None, ), UserAgentParser( '(Obigo)InternetBrowser', None, None, None, ), UserAgentParser( '(Obigo)\\-Browser', None, None, None, ), UserAgentParser( '(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+))?', 'Obigo', None, None, ), UserAgentParser( '(MAXTHON|Maxthon) (\\d+)\\.(\\d+)', 'Maxthon', None, None, ), UserAgentParser( '(Maxthon|MyIE2|Uzbl|Shiira)', None, '0', None, ), UserAgentParser( '(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(NCSA_Mosaic)/(\\d+)\\.(\\d+)', 'NCSA Mosaic', None, None, ), UserAgentParser( '(POLARIS)/(\\d+)\\.(\\d+)', 'Polaris', None, None, ), UserAgentParser( '(Embider)/(\\d+)\\.(\\d+)', 'Polaris', None, None, ), UserAgentParser( '(BonEcho)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+)?', 'Bon Echo', None, None, ), UserAgentParser( '(iPod|iPhone|iPad).+Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*[ +]Safari', 'Mobile Safari', None, None, ), UserAgentParser( '(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\\d+)_(\\d+)(?:_(\\d+))?.* AppleNews\\/\\d+\\.\\d+\\.\\d+?', 'Mobile Safari UI/WKWebView', None, None, ), UserAgentParser( '(iPod|iPhone|iPad).+Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'Mobile Safari UI/WKWebView', None, None, ), UserAgentParser( '(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\\d+)_(\\d+)(?:_(\\d+))?.*Mobile.*[ +]Safari', 'Mobile Safari', None, None, ), UserAgentParser( '(iPod|iPod touch|iPhone|iPad);.*CPU.*OS[ +](\\d+)_(\\d+)(?:_(\\d+))?.*Mobile', 'Mobile Safari UI/WKWebView', None, None, ), UserAgentParser( '(iPod|iPhone|iPad).* Safari', 'Mobile Safari', None, None, ), UserAgentParser( '(iPod|iPhone|iPad)', 'Mobile Safari UI/WKWebView', None, None, ), UserAgentParser( '(Outlook-iOS)/\\d+\\.\\d+\\.prod\\.iphone \\((\\d+)\\.(\\d+)\\.(\\d+)\\)', None, None, None, ), UserAgentParser( '(AvantGo) (\\d+).(\\d+)', None, None, None, ), UserAgentParser( '(OneBrowser)/(\\d+).(\\d+)', 'ONE Browser', None, None, ), UserAgentParser( '(Avant)', None, '1', None, ), UserAgentParser( '(QtCarBrowser)', None, '1', None, ), UserAgentParser( '^(iBrowser/Mini)(\\d+).(\\d+)', 'iBrowser Mini', None, None, ), UserAgentParser( '^(iBrowser|iRAPP)/(\\d+).(\\d+)', None, None, None, ), UserAgentParser( '^(Nokia)', 'Nokia Services (WAP) Browser', None, None, ), UserAgentParser( '(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)', 'Nokia Browser', None, None, ), UserAgentParser( '(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)', 'Nokia Browser', None, None, ), UserAgentParser( '(NokiaBrowser)/(\\d+)\\.(\\d+)', 'Nokia Browser', None, None, ), UserAgentParser( '(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)', 'Nokia Browser', None, None, ), UserAgentParser( '(Series60)/5\\.0', 'Nokia Browser', '7', '0', ), UserAgentParser( '(Series60)/(\\d+)\\.(\\d+)', 'Nokia OSS Browser', None, None, ), UserAgentParser( '(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Ovi Browser', None, None, ), UserAgentParser( '(Nokia)[EN]?(\\d+)', None, None, None, ), UserAgentParser( '(PlayBook).+RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)', 'BlackBerry WebKit', None, None, ), UserAgentParser( '(Black[bB]erry|BB10).+Version/(\\d+)\\.(\\d+)\\.(\\d+)', 'BlackBerry WebKit', None, None, ), UserAgentParser( '(Black[bB]erry)\\s?(\\d+)', 'BlackBerry', None, None, ), UserAgentParser( '(OmniWeb)/v(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Blazer)/(\\d+)\\.(\\d+)', 'Palm Blazer', None, None, ), UserAgentParser( '(Pre)/(\\d+)\\.(\\d+)', 'Palm Pre', None, None, ), UserAgentParser( '(ELinks)/(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(ELinks) \\((\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Links) \\((\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(QtWeb) Internet Browser/(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(PhantomJS)/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(AppleWebKit)/(\\d+)\\.?(\\d+)?\\+ .* Safari', 'WebKit Nightly', None, None, ), UserAgentParser( '(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari/', 'Safari', None, None, ), UserAgentParser( '(Safari)/\\d+', None, None, None, ), UserAgentParser( '(OLPC)/Update(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(OLPC)/Update()\\.(\\d+)', None, '0', None, ), UserAgentParser( '(SEMC\\-Browser)/(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Teleca)', 'Teleca Browser', None, None, ), UserAgentParser( '(Phantom)/V(\\d+)\\.(\\d+)', 'Phantom Browser', None, None, ), UserAgentParser( '(Trident)/(7|8)\\.(0)', 'IE', '11', None, ), UserAgentParser( '(Trident)/(6)\\.(0)', 'IE', '10', None, ), UserAgentParser( '(Trident)/(5)\\.(0)', 'IE', '9', None, ), UserAgentParser( '(Trident)/(4)\\.(0)', 'IE', '8', None, ), UserAgentParser( '(Espial)/(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?', None, None, None, ), UserAgentParser( '(AppleWebKit)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Apple Mail', None, None, ), UserAgentParser( '(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*)?', None, None, None, ), UserAgentParser( '([MS]?IE) (\\d+)\\.(\\d+)', 'IE', None, None, ), UserAgentParser( '(python-requests)/(\\d+)\\.(\\d+)', 'Python Requests', None, None, ), UserAgentParser( '\\b(Windows-Update-Agent|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|Wget|OpenBSD ftp|jupdate)(?:[ /](\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?)?', None, None, None, ), UserAgentParser( '(Java)[/ ]{0,1}\\d+\\.(\\d+)\\.(\\d+)[_-]*([a-zA-Z0-9]+)*', None, None, None, ), UserAgentParser( '^(Roku)/DVP-(\\d+)\\.(\\d+)', None, None, None, ), UserAgentParser( '(Kurio)\\/(\\d+)\\.(\\d+)\\.(\\d+)', 'Kurio App', None, None, ), UserAgentParser( '^(Box(?: Sync)?)/(\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, ), ] DEVICE_PARSERS = [ DeviceParser( '(?:(?:iPhone|Windows CE|Windows Phone|Android).*(?:(?:Bot|Yeti)-Mobile|YRSpider|BingPreview|bots?/\\d|(?:bot|spider)\\.html)|AdsBot-Google-Mobile.*iPhone)', 'i', 'Spider', 'Spider', 'Smartphone', ), DeviceParser( '(?:DoCoMo|\\bMOT\\b|\\bLG\\b|Nokia|Samsung|SonyEricsson).*(?:(?:Bot|Yeti)-Mobile|bots?/\\d|(?:bot|crawler)\\.html|(?:jump|google|Wukong)bot|ichiro/mobile|/spider|YahooSeeker)', 'i', 'Spider', 'Spider', 'Feature Phone', ), DeviceParser( '\\bSmartWatch *\\( *([^;]+) *; *([^;]+) *;', None, '$1 $2', '$1', '$2', ), DeviceParser( 'Android Application[^\\-]+ - (Sony) ?(Ericsson)? (.+) \\w+ - ', None, '$1 $2', '$1$2', '$3', ), DeviceParser( 'Android Application[^\\-]+ - (?:HTC|HUAWEI|LGE|LENOVO|MEDION|TCT) (HTC|HUAWEI|LG|LENOVO|MEDION|ALCATEL)[ _\\-](.+) \\w+ - ', 'i', '$1 $2', '$1', '$2', ), DeviceParser( 'Android Application[^\\-]+ - ([^ ]+) (.+) \\w+ - ', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *([BLRQ]C\\d{4}[A-Z]+) +Build/', None, '3Q $1', '3Q', '$1', ), DeviceParser( '; *(?:3Q_)([^;/]+) +Build', None, '3Q $1', '3Q', '$1', ), DeviceParser( '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', None, '$1', 'Acer', '$1', ), DeviceParser( '; *Acer Iconia Tab ([^;/]+) Build', None, '$1', 'Acer', '$1', ), DeviceParser( '; *(Z1[1235]0|E320[^/]*|S500|S510|Liquid[^;/]*|Iconia A\\d+) Build', None, '$1', 'Acer', '$1', ), DeviceParser( '; *(Acer |ACER )([^;/]+) Build', None, '$1$2', 'Acer', '$2', ), DeviceParser( '; *(Advent )?(Vega(?:Bean|Comb)?).* Build', None, '$1$2', 'Advent', '$2', ), DeviceParser( '; *(Ainol )?((?:NOVO|[Nn]ovo)[^;/]+) Build', None, '$1$2', 'Ainol', '$2', ), DeviceParser( '; *AIRIS[ _\\-]?([^/;\\)]+) *(?:;|\\)|Build)', 'i', '$1', 'Airis', '$1', ), DeviceParser( '; *(OnePAD[^;/]+) Build', 'i', '$1', 'Airis', '$1', ), DeviceParser( '; *Airpad[ \\-]([^;/]+) Build', None, 'Airpad $1', 'Airpad', '$1', ), DeviceParser( '; *(one ?touch) (EVO7|T10|T20) Build', None, 'Alcatel One Touch $2', 'Alcatel', 'One Touch $2', ), DeviceParser( '; *(?:alcatel[ _])?(?:(?:one[ _]?touch[ _])|ot[ \\-])([^;/]+);? Build', 'i', 'Alcatel One Touch $1', 'Alcatel', 'One Touch $1', ), DeviceParser( '; *(TCL)[ _]([^;/]+) Build', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *(Vodafone Smart II|Optimus_Madrid) Build', None, 'Alcatel $1', 'Alcatel', '$1', ), DeviceParser( '; *BASE_Lutea_3 Build', None, 'Alcatel One Touch 998', 'Alcatel', 'One Touch 998', ), DeviceParser( '; *BASE_Varia Build', None, 'Alcatel One Touch 918D', 'Alcatel', 'One Touch 918D', ), DeviceParser( '; *((?:FINE|Fine)\\d[^;/]+) Build', None, '$1', 'Allfine', '$1', ), DeviceParser( '; *(ALLVIEW[ _]?|Allview[ _]?)((?:Speed|SPEED).*) Build/', None, '$1$2', 'Allview', '$2', ), DeviceParser( '; *(ALLVIEW[ _]?|Allview[ _]?)?(AX1_Shine|AX2_Frenzy) Build', None, '$1$2', 'Allview', '$2', ), DeviceParser( '; *(ALLVIEW[ _]?|Allview[ _]?)([^;/]*) Build', None, '$1$2', 'Allview', '$2', ), DeviceParser( '; *(A13-MID) Build', None, '$1', 'Allwinner', '$1', ), DeviceParser( '; *(Allwinner)[ _\\-]?([^;/]+) Build', None, '$1 $2', 'Allwinner', '$1', ), DeviceParser( '; *(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', None, '$1', 'Amaway', '$1', ), DeviceParser( '; *(?:AMOI|Amoi)[ _]([^;/]+) Build', None, 'Amoi $1', 'Amoi', '$1', ), DeviceParser( '^(?:AMOI|Amoi)[ _]([^;/]+) Linux', None, 'Amoi $1', 'Amoi', '$1', ), DeviceParser( '; *(MW(?:0[789]|10)[^;/]+) Build', None, '$1', 'Aoc', '$1', ), DeviceParser( '; *(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', None, 'Aoson $1', 'Aoson', '$1', ), DeviceParser( '; *Aoson ([^;/]+) Build', 'i', 'Aoson $1', 'Aoson', '$1', ), DeviceParser( '; *[Aa]panda[ _\\-]([^;/]+) Build', None, 'Apanda $1', 'Apanda', '$1', ), DeviceParser( '; *(?:ARCHOS|Archos) ?(GAMEPAD.*?)(?: Build|[;/\\(\\)\\-])', None, 'Archos $1', 'Archos', '$1', ), DeviceParser( 'ARCHOS; GOGI; ([^;]+);', None, 'Archos $1', 'Archos', '$1', ), DeviceParser( '(?:ARCHOS|Archos)[ _]?(.*?)(?: Build|[;/\\(\\)\\-]|$)', None, 'Archos $1', 'Archos', '$1', ), DeviceParser( '; *(AN(?:7|8|9|10|13)[A-Z0-9]{1,4}) Build', None, 'Archos $1', 'Archos', '$1', ), DeviceParser( '; *(A28|A32|A43|A70(?:BHT|CHT|HB|S|X)|A101(?:B|C|IT)|A7EB|A7EB-WK|101G9|80G9) Build', None, 'Archos $1', 'Archos', '$1', ), DeviceParser( '; *(PAD-FMD[^;/]+) Build', None, '$1', 'Arival', '$1', ), DeviceParser( '; *(BioniQ) ?([^;/]+) Build', None, '$1 $2', 'Arival', '$1 $2', ), DeviceParser( '; *(AN\\d[^;/]+|ARCHM\\d+) Build', None, 'Arnova $1', 'Arnova', '$1', ), DeviceParser( '; *(?:ARNOVA|Arnova) ?([^;/]+) Build', None, 'Arnova $1', 'Arnova', '$1', ), DeviceParser( '; *(?:ASSISTANT )?(AP)-?([1789]\\d{2}[A-Z]{0,2}|80104) Build', None, 'Assistant $1-$2', 'Assistant', '$1-$2', ), DeviceParser( '; *(ME17\\d[^;/]*|ME3\\d{2}[^;/]+|K00[A-Z]|Nexus 10|Nexus 7(?: 2013)?|PadFone[^;/]*|Transformer[^;/]*|TF\\d{3}[^;/]*|eeepc) Build', None, 'Asus $1', 'Asus', '$1', ), DeviceParser( '; *ASUS[ _]*([^;/]+) Build', None, 'Asus $1', 'Asus', '$1', ), DeviceParser( '; *Garmin-Asus ([^;/]+) Build', None, 'Garmin-Asus $1', 'Garmin-Asus', '$1', ), DeviceParser( '; *(Garminfone) Build', None, 'Garmin $1', 'Garmin-Asus', '$1', ), DeviceParser( '; (@TAB-[^;/]+) Build', None, '$1', 'Attab', '$1', ), DeviceParser( '; *(T-(?:07|[^0]\\d)[^;/]+) Build', None, '$1', 'Audiosonic', '$1', ), DeviceParser( '; *(?:Axioo[ _\\-]([^;/]+)|(picopad)[ _\\-]([^;/]+)) Build', 'i', 'Axioo $1$2 $3', 'Axioo', '$1$2 $3', ), DeviceParser( '; *(V(?:100|700|800)[^;/]*) Build', None, '$1', 'Azend', '$1', ), DeviceParser( '; *(IBAK\\-[^;/]*) Build', 'i', '$1', 'Bak', '$1', ), DeviceParser( '; *(HY5001|HY6501|X12|X21|I5) Build', None, 'Bedove $1', 'Bedove', '$1', ), DeviceParser( '; *(JC-[^;/]*) Build', None, 'Benss $1', 'Benss', '$1', ), DeviceParser( '; *(BB) ([^;/]+) Build', None, '$1 $2', 'Blackberry', '$2', ), DeviceParser( '; *(BlackBird)[ _](I8.*) Build', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *(BlackBird)[ _](.*) Build', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *([0-9]+BP[EM][^;/]*|Endeavour[^;/]+) Build', None, 'Blaupunkt $1', 'Blaupunkt', '$1', ), DeviceParser( '; *((?:BLU|Blu)[ _\\-])([^;/]+) Build', None, '$1$2', 'Blu', '$2', ), DeviceParser( '; *(?:BMOBILE )?(Blu|BLU|DASH [^;/]+|VIVO 4\\.3|TANK 4\\.5) Build', None, '$1', 'Blu', '$1', ), DeviceParser( '; *(TOUCH\\d[^;/]+) Build', None, '$1', 'Blusens', '$1', ), DeviceParser( '; *(AX5\\d+) Build', None, '$1', 'Bmobile', '$1', ), DeviceParser( '; *([Bb]q) ([^;/]+);? Build', None, '$1 $2', 'bq', '$2', ), DeviceParser( '; *(Maxwell [^;/]+) Build', None, '$1', 'bq', '$1', ), DeviceParser( '; *((?:B-Tab|B-TAB) ?\\d[^;/]+) Build', None, '$1', 'Braun', '$1', ), DeviceParser( '; *(Broncho) ([^;/]+) Build', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *CAPTIVA ([^;/]+) Build', None, 'Captiva $1', 'Captiva', '$1', ), DeviceParser( '; *(C771|CAL21|IS11CA) Build', None, '$1', 'Casio', '$1', ), DeviceParser( '; *(?:Cat|CAT) ([^;/]+) Build', None, 'Cat $1', 'Cat', '$1', ), DeviceParser( '; *(?:Cat)(Nova.*) Build', None, 'Cat $1', 'Cat', '$1', ), DeviceParser( '; *(INM8002KP|ADM8000KP_[AB]) Build', None, '$1', 'Cat', 'Tablet PHOENIX 8.1J0', ), DeviceParser( '; *(?:[Cc]elkon[ _\\*]|CELKON[ _\\*])([^;/\\)]+) ?(?:Build|;|\\))', None, '$1', 'Celkon', '$1', ), DeviceParser( 'Build/(?:[Cc]elkon)+_?([^;/_\\)]+)', None, '$1', 'Celkon', '$1', ), DeviceParser( '; *(CT)-?(\\d+) Build', None, '$1$2', 'Celkon', '$1$2', ), DeviceParser( '; *(A19|A19Q|A105|A107[^;/\\)]*) ?(?:Build|;|\\))', None, '$1', 'Celkon', '$1', ), DeviceParser( '; *(TPC[0-9]{4,5}) Build', None, '$1', 'ChangJia', '$1', ), DeviceParser( '; *(Cloudfone)[ _](Excite)([^ ][^;/]+) Build', None, '$1 $2 $3', 'Cloudfone', '$1 $2 $3', ), DeviceParser( '; *(Excite|ICE)[ _](\\d+[^;/]+) Build', None, 'Cloudfone $1 $2', 'Cloudfone', 'Cloudfone $1 $2', ), DeviceParser( '; *(Cloudfone|CloudPad)[ _]([^;/]+) Build', None, '$1 $2', 'Cloudfone', '$1 $2', ), DeviceParser( '; *((?:Aquila|Clanga|Rapax)[^;/]+) Build', 'i', '$1', 'Cmx', '$1', ), DeviceParser( '; *(?:CFW-|Kyros )?(MID[0-9]{4}(?:[ABC]|SR|TV)?)(\\(3G\\)-4G| GB 8K| 3G| 8K| GB)? *(?:Build|[;\\)])', None, 'CobyKyros $1$2', 'CobyKyros', '$1$2', ), DeviceParser( '; *([^;/]*)Coolpad[ _]([^;/]+) Build', None, '$1$2', 'Coolpad', '$1$2', ), DeviceParser( '; *(CUBE[ _])?([KU][0-9]+ ?GT.*|A5300) Build', 'i', '$1$2', 'Cube', '$2', ), DeviceParser( '; *CUBOT ([^;/]+) Build', 'i', '$1', 'Cubot', '$1', ), DeviceParser( '; *(BOBBY) Build', 'i', '$1', 'Cubot', '$1', ), DeviceParser( '; *(Dslide [^;/]+) Build', None, '$1', 'Danew', '$1', ), DeviceParser( '; *(XCD)[ _]?(28|35) Build', None, 'Dell $1$2', 'Dell', '$1$2', ), DeviceParser( '; *(001DL) Build', None, 'Dell $1', 'Dell', 'Streak', ), DeviceParser( '; *(?:Dell|DELL) (Streak) Build', None, 'Dell $1', 'Dell', 'Streak', ), DeviceParser( '; *(101DL|GS01|Streak Pro[^;/]*) Build', None, 'Dell $1', 'Dell', 'Streak Pro', ), DeviceParser( '; *([Ss]treak ?7) Build', None, 'Dell $1', 'Dell', 'Streak 7', ), DeviceParser( '; *(Mini-3iX) Build', None, 'Dell $1', 'Dell', '$1', ), DeviceParser( '; *(?:Dell|DELL)[ _](Aero|Venue|Thunder|Mini.*|Streak[ _]Pro) Build', None, 'Dell $1', 'Dell', '$1', ), DeviceParser( '; *Dell[ _]([^;/]+) Build', None, 'Dell $1', 'Dell', '$1', ), DeviceParser( '; *Dell ([^;/]+) Build', None, 'Dell $1', 'Dell', '$1', ), DeviceParser( '; *(TA[CD]-\\d+[^;/]*) Build', None, '$1', 'Denver', '$1', ), DeviceParser( '; *(iP[789]\\d{2}(?:-3G)?|IP10\\d{2}(?:-8GB)?) Build', None, '$1', 'Dex', '$1', ), DeviceParser( '; *(AirTab)[ _\\-]([^;/]+) Build', None, '$1 $2', 'DNS', '$1 $2', ), DeviceParser( '; *(F\\-\\d[^;/]+) Build', None, '$1', 'Fujitsu', '$1', ), DeviceParser( '; *(HT-03A) Build', None, '$1', 'HTC', 'Magic', ), DeviceParser( '; *(HT\\-\\d[^;/]+) Build', None, '$1', 'HTC', '$1', ), DeviceParser( '; *(L\\-\\d[^;/]+) Build', None, '$1', 'LG', '$1', ), DeviceParser( '; *(N\\-\\d[^;/]+) Build', None, '$1', 'Nec', '$1', ), DeviceParser( '; *(P\\-\\d[^;/]+) Build', None, '$1', 'Panasonic', '$1', ), DeviceParser( '; *(SC\\-\\d[^;/]+) Build', None, '$1', 'Samsung', '$1', ), DeviceParser( '; *(SH\\-\\d[^;/]+) Build', None, '$1', 'Sharp', '$1', ), DeviceParser( '; *(SO\\-\\d[^;/]+) Build', None, '$1', 'SonyEricsson', '$1', ), DeviceParser( '; *(T\\-0[12][^;/]+) Build', None, '$1', 'Toshiba', '$1', ), DeviceParser( '; *(DOOV)[ _]([^;/]+) Build', None, '$1 $2', 'DOOV', '$2', ), DeviceParser( '; *(Enot|ENOT)[ -]?([^;/]+) Build', None, '$1 $2', 'Enot', '$2', ), DeviceParser( '; *[^;/]+ Build/(?:CROSS|Cross)+[ _\\-]([^\\)]+)', None, 'CROSS $1', 'Evercoss', 'Cross $1', ), DeviceParser( '; *(CROSS|Cross)[ _\\-]([^;/]+) Build', None, '$1 $2', 'Evercoss', 'Cross $2', ), DeviceParser( '; *Explay[_ ](.+?)(?:[\\)]| Build)', None, '$1', 'Explay', '$1', ), DeviceParser( '; *(IQ.*) Build', None, '$1', 'Fly', '$1', ), DeviceParser( '; *(Fly|FLY)[ _](IQ[^;]+|F[34]\\d+[^;]*);? Build', None, '$1 $2', 'Fly', '$2', ), DeviceParser( '; *(M532|Q572|FJL21) Build/', None, '$1', 'Fujitsu', '$1', ), DeviceParser( '; *(G1) Build', None, '$1', 'Galapad', '$1', ), DeviceParser( '; *(Geeksphone) ([^;/]+) Build', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *(G[^F]?FIVE) ([^;/]+) Build', None, '$1 $2', 'Gfive', '$2', ), DeviceParser( '; *(Gionee)[ _\\-]([^;/]+)(?:/[^;/]+)? Build', 'i', '$1 $2', 'Gionee', '$2', ), DeviceParser( '; *(GN\\d+[A-Z]?|INFINITY_PASSION|Ctrl_V1) Build', None, 'Gionee $1', 'Gionee', '$1', ), DeviceParser( '; *(E3) Build/JOP40D', None, 'Gionee $1', 'Gionee', '$1', ), DeviceParser( '\\sGIONEE[-\\s_](\\w*)', 'i', 'Gionee $1', 'Gionee', '$1', ), DeviceParser( '; *((?:FONE|QUANTUM|INSIGNIA) \\d+[^;/]*|PLAYTAB) Build', None, 'GoClever $1', 'GoClever', '$1', ), DeviceParser( '; *GOCLEVER ([^;/]+) Build', None, 'GoClever $1', 'GoClever', '$1', ), DeviceParser( '; *(Glass \\d+) Build', None, '$1', 'Google', '$1', ), DeviceParser( '; *(Pixel \\w+) Build', None, '$1', 'Google', '$1', ), DeviceParser( '; *(GSmart)[ -]([^/]+) Build', None, '$1 $2', 'Gigabyte', '$1 $2', ), DeviceParser( '; *(imx5[13]_[^/]+) Build', None, 'Freescale $1', 'Freescale', '$1', ), DeviceParser( '; *Haier[ _\\-]([^/]+) Build', None, 'Haier $1', 'Haier', '$1', ), DeviceParser( '; *(PAD1016) Build', None, 'Haipad $1', 'Haipad', '$1', ), DeviceParser( '; *(M701|M7|M8|M9) Build', None, 'Haipad $1', 'Haipad', '$1', ), DeviceParser( '; *(SN\\d+T[^;\\)/]*)(?: Build|[;\\)])', None, 'Hannspree $1', 'Hannspree', '$1', ), DeviceParser( 'Build/HCL ME Tablet ([^;\\)]+)[\\);]', None, 'HCLme $1', 'HCLme', '$1', ), DeviceParser( '; *([^;\\/]+) Build/HCL', None, 'HCLme $1', 'HCLme', '$1', ), DeviceParser( '; *(MID-?\\d{4}C[EM]) Build', None, 'Hena $1', 'Hena', '$1', ), DeviceParser( '; *(EG\\d{2,}|HS-[^;/]+|MIRA[^;/]+) Build', None, 'Hisense $1', 'Hisense', '$1', ), DeviceParser( '; *(andromax[^;/]+) Build', 'i', 'Hisense $1', 'Hisense', '$1', ), DeviceParser( '; *(?:AMAZE[ _](S\\d+)|(S\\d+)[ _]AMAZE) Build', None, 'AMAZE $1$2', 'hitech', 'AMAZE $1$2', ), DeviceParser( '; *(PlayBook) Build', None, 'HP $1', 'HP', '$1', ), DeviceParser( '; *HP ([^/]+) Build', None, 'HP $1', 'HP', '$1', ), DeviceParser( '; *([^/]+_tenderloin) Build', None, 'HP TouchPad', 'HP', 'TouchPad', ), DeviceParser( '; *(HUAWEI |Huawei-)?([UY][^;/]+) Build/(?:Huawei|HUAWEI)([UY][^\\);]+)\\)', None, '$1$2', 'Huawei', '$2', ), DeviceParser( '; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\\d+[^\\);]+)[^\\);]*\\)', None, '$1', 'Huawei', '$2', ), DeviceParser( '; *(S7|M860) Build', None, '$1', 'Huawei', '$1', ), DeviceParser( '; *((?:HUAWEI|Huawei)[ \\-]?)(MediaPad) Build', None, '$1$2', 'Huawei', '$2', ), DeviceParser( '; *((?:HUAWEI[ _]?|Huawei[ _])?Ascend[ _])([^;/]+) Build', None, '$1$2', 'Huawei', '$2', ), DeviceParser( '; *((?:HUAWEI|Huawei)[ _\\-]?)((?:G700-|MT-)[^;/]+) Build', None, '$1$2', 'Huawei', '$2', ), DeviceParser( '; *((?:HUAWEI|Huawei)[ _\\-]?)([^;/]+) Build', None, '$1$2', 'Huawei', '$2', ), DeviceParser( '; *(MediaPad[^;]+|SpringBoard) Build/Huawei', None, '$1', 'Huawei', '$1', ), DeviceParser( '; *([^;]+) Build/(?:Huawei|HUAWEI)', None, '$1', 'Huawei', '$1', ), DeviceParser( '; *([Uu])([89]\\d{3}) Build', None, '$1$2', 'Huawei', 'U$2', ), DeviceParser( '; *(?:Ideos |IDEOS )(S7) Build', None, 'Huawei Ideos$1', 'Huawei', 'Ideos$1', ), DeviceParser( '; *(?:Ideos |IDEOS )([^;/]+\\s*|\\s*)Build', None, 'Huawei Ideos$1', 'Huawei', 'Ideos$1', ), DeviceParser( '; *(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660|Nexus 6P|ATH-.+?) Build[/ ]', None, 'Huawei $1', 'Huawei', '$1', ), DeviceParser( '; *HTC[ _]([^;]+); Windows Phone', None, 'HTC $1', 'HTC', '$1', ), DeviceParser( '; *(?:HTC[ _/])+([^ _/]+)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: *Build|\\))', None, 'HTC $1', 'HTC', '$1', ), DeviceParser( '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+))?(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: *Build|\\))', None, 'HTC $1 $2', 'HTC', '$1 $2', ), DeviceParser( '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+))?)?(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: *Build|\\))', None, 'HTC $1 $2 $3', 'HTC', '$1 $2 $3', ), DeviceParser( '; *(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+))?)?)?(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: *Build|\\))', None, 'HTC $1 $2 $3 $4', 'HTC', '$1 $2 $3 $4', ), DeviceParser( '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/;]+)(?: *Build|[;\\)]| - )', None, 'HTC $1', 'HTC', '$1', ), DeviceParser( '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/;\\)]+))?(?: *Build|[;\\)]| - )', None, 'HTC $1 $2', 'HTC', '$1 $2', ), DeviceParser( '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/;\\)]+))?)?(?: *Build|[;\\)]| - )', None, 'HTC $1 $2 $3', 'HTC', '$1 $2 $3', ), DeviceParser( '; *(?:(?:HTC|htc)(?:_blocked)*[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ /;]+))?)?)?(?: *Build|[;\\)]| - )', None, 'HTC $1 $2 $3 $4', 'HTC', '$1 $2 $3 $4', ), DeviceParser( 'HTC Streaming Player [^\\/]*/[^\\/]*/ htc_([^/]+) /', None, 'HTC $1', 'HTC', '$1', ), DeviceParser( '(?:[;,] *|^)(?:htccn_chs-)?HTC[ _-]?([^;]+?)(?: *Build|clay|Android|-?Mozilla| Opera| Profile| UNTRUSTED|[;/\\(\\)]|$)', 'i', 'HTC $1', 'HTC', '$1', ), DeviceParser( '; *(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|[/;\\(\\)])', 'i', 'HTC $1', 'HTC', '$1', ), DeviceParser( '; *(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)', 'i', 'HTC $1 $2', 'HTC', '$1 $2', ), DeviceParser( '; *HYUNDAI (T\\d[^/]*) Build', None, 'Hyundai $1', 'Hyundai', '$1', ), DeviceParser( '; *HYUNDAI ([^;/]+) Build', None, 'Hyundai $1', 'Hyundai', '$1', ), DeviceParser( '; *(X700|Hold X|MB-6900) Build', None, 'Hyundai $1', 'Hyundai', '$1', ), DeviceParser( '; *(?:iBall[ _\\-])?(Andi)[ _]?(\\d[^;/]*) Build', 'i', '$1 $2', 'iBall', '$1 $2', ), DeviceParser( '; *(IBall)(?:[ _]([^;/]+)|) Build', 'i', '$1 $2', 'iBall', '$2', ), DeviceParser( '; *(NT-\\d+[^ ;/]*|Net[Tt]AB [^;/]+|Mercury [A-Z]+|iconBIT)(?: S/N:[^;/]+)? Build', None, '$1', 'IconBIT', '$1', ), DeviceParser( '; *(IMO)[ _]([^;/]+) Build', 'i', '$1 $2', 'IMO', '$2', ), DeviceParser( '; *i-?mobile[ _]([^/]+) Build/', 'i', 'i-mobile $1', 'imobile', '$1', ), DeviceParser( '; *(i-(?:style|note)[^/]*) Build/', 'i', 'i-mobile $1', 'imobile', '$1', ), DeviceParser( '; *(ImPAD) ?(\\d+(?:.)*) Build', None, '$1 $2', 'Impression', '$1 $2', ), DeviceParser( '; *(Infinix)[ _]([^;/]+) Build', None, '$1 $2', 'Infinix', '$2', ), DeviceParser( '; *(Informer)[ \\-]([^;/]+) Build', None, '$1 $2', 'Informer', '$2', ), DeviceParser( '; *(TAB) ?([78][12]4) Build', None, 'Intenso $1', 'Intenso', '$1 $2', ), DeviceParser( '; *(?:Intex[ _])?(AQUA|Aqua)([ _\\.\\-])([^;/]+) *(?:Build|;)', None, '$1$2$3', 'Intex', '$1 $3', ), DeviceParser( '; *(?:INTEX|Intex)(?:[_ ]([^\\ _;/]+))(?:[_ ]([^\\ _;/]+))? *(?:Build|;)', None, '$1 $2', 'Intex', '$1 $2', ), DeviceParser( '; *([iI]Buddy)[ _]?(Connect)(?:_|\\?_| )?([^;/]*) *(?:Build|;)', None, '$1 $2 $3', 'Intex', 'iBuddy $2 $3', ), DeviceParser( '; *(I-Buddy)[ _]([^;/]+) *(?:Build|;)', None, '$1 $2', 'Intex', 'iBuddy $2', ), DeviceParser( '; *(iOCEAN) ([^/]+) Build', 'i', '$1 $2', 'iOCEAN', '$2', ), DeviceParser( '; *(TP\\d+(?:\\.\\d+)?\\-\\d[^;/]+) Build', None, 'ionik $1', 'ionik', '$1', ), DeviceParser( '; *(M702pro) Build', None, '$1', 'Iru', '$1', ), DeviceParser( '; *(DE88Plus|MD70) Build', None, '$1', 'Ivio', '$1', ), DeviceParser( '; *IVIO[_\\-]([^;/]+) Build', None, '$1', 'Ivio', '$1', ), DeviceParser( '; *(TPC-\\d+|JAY-TECH) Build', None, '$1', 'Jaytech', '$1', ), DeviceParser( '; *(JY-[^;/]+|G[234]S?) Build', None, '$1', 'Jiayu', '$1', ), DeviceParser( '; *(JXD)[ _\\-]([^;/]+) Build', None, '$1 $2', 'JXD', '$2', ), DeviceParser( '; *Karbonn[ _]?([^;/]+) *(?:Build|;)', 'i', '$1', 'Karbonn', '$1', ), DeviceParser( '; *([^;]+) Build/Karbonn', None, '$1', 'Karbonn', '$1', ), DeviceParser( '; *(A11|A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2|Titanium S\\d) +Build', None, '$1', 'Karbonn', '$1', ), DeviceParser( '; *(IS01|IS03|IS05|IS\\d{2}SH) Build', None, '$1', 'Sharp', '$1', ), DeviceParser( '; *(IS04) Build', None, '$1', 'Regza', '$1', ), DeviceParser( '; *(IS06|IS\\d{2}PT) Build', None, '$1', 'Pantech', '$1', ), DeviceParser( '; *(IS11S) Build', None, '$1', 'SonyEricsson', 'Xperia Acro', ), DeviceParser( '; *(IS11CA) Build', None, '$1', 'Casio', 'GzOne $1', ), DeviceParser( '; *(IS11LG) Build', None, '$1', 'LG', 'Optimus X', ), DeviceParser( '; *(IS11N) Build', None, '$1', 'Medias', '$1', ), DeviceParser( '; *(IS11PT) Build', None, '$1', 'Pantech', 'MIRACH', ), DeviceParser( '; *(IS12F) Build', None, '$1', 'Fujitsu', 'Arrows ES', ), DeviceParser( '; *(IS12M) Build', None, '$1', 'Motorola', 'XT909', ), DeviceParser( '; *(IS12S) Build', None, '$1', 'SonyEricsson', 'Xperia Acro HD', ), DeviceParser( '; *(ISW11F) Build', None, '$1', 'Fujitsu', 'Arrowz Z', ), DeviceParser( '; *(ISW11HT) Build', None, '$1', 'HTC', 'EVO', ), DeviceParser( '; *(ISW11K) Build', None, '$1', 'Kyocera', 'DIGNO', ), DeviceParser( '; *(ISW11M) Build', None, '$1', 'Motorola', 'Photon', ), DeviceParser( '; *(ISW11SC) Build', None, '$1', 'Samsung', 'GALAXY S II WiMAX', ), DeviceParser( '; *(ISW12HT) Build', None, '$1', 'HTC', 'EVO 3D', ), DeviceParser( '; *(ISW13HT) Build', None, '$1', 'HTC', 'J', ), DeviceParser( '; *(ISW?[0-9]{2}[A-Z]{0,2}) Build', None, '$1', 'KDDI', '$1', ), DeviceParser( '; *(INFOBAR [^;/]+) Build', None, '$1', 'KDDI', '$1', ), DeviceParser( '; *(JOYPAD|Joypad)[ _]([^;/]+) Build/', None, '$1 $2', 'Kingcom', '$1 $2', ), DeviceParser( '; *(Vox|VOX|Arc|K080) Build/', 'i', '$1', 'Kobo', '$1', ), DeviceParser( '\\b(Kobo Touch)\\b', None, '$1', 'Kobo', '$1', ), DeviceParser( '; *(K-Touch)[ _]([^;/]+) Build', 'i', '$1 $2', 'Ktouch', '$2', ), DeviceParser( '; *((?:EV|KM)-S\\d+[A-Z]?) Build', 'i', '$1', 'KTtech', '$1', ), DeviceParser( '; *(Zio|Hydro|Torque|Event|EVENT|Echo|Milano|Rise|URBANO PROGRESSO|WX04K|WX06K|WX10K|KYL21|101K|C5[12]\\d{2}) Build/', None, '$1', 'Kyocera', '$1', ), DeviceParser( '; *(?:LAVA[ _])?IRIS[ _\\-]?([^/;\\)]+) *(?:;|\\)|Build)', 'i', 'Iris $1', 'Lava', 'Iris $1', ), DeviceParser( '; *LAVA[ _]([^;/]+) Build', None, '$1', 'Lava', '$1', ), DeviceParser( '; *(?:(Aspire A1)|(?:LEMON|Lemon)[ _]([^;/]+))_? Build', None, 'Lemon $1$2', 'Lemon', '$1$2', ), DeviceParser( '; *(TAB-1012) Build/', None, 'Lenco $1', 'Lenco', '$1', ), DeviceParser( '; Lenco ([^;/]+) Build/', None, 'Lenco $1', 'Lenco', '$1', ), DeviceParser( '; *(A1_07|A2107A-H|S2005A-H|S1-37AH0) Build', None, '$1', 'Lenovo', '$1', ), DeviceParser( '; *(Idea[Tp]ab)[ _]([^;/]+);? Build', None, 'Lenovo $1 $2', 'Lenovo', '$1 $2', ), DeviceParser( '; *(Idea(?:Tab|pad)) ?([^;/]+) Build', None, 'Lenovo $1 $2', 'Lenovo', '$1 $2', ), DeviceParser( '; *(ThinkPad) ?(Tablet) Build/', None, 'Lenovo $1 $2', 'Lenovo', '$1 $2', ), DeviceParser( '; *(?:LNV-)?(?:=?[Ll]enovo[ _\\-]?|LENOVO[ _])+(.+?)(?:Build|[;/\\)])', None, 'Lenovo $1', 'Lenovo', '$1', ), DeviceParser( '[;,] (?:Vodafone )?(SmartTab) ?(II) ?(\\d+) Build/', None, 'Lenovo $1 $2 $3', 'Lenovo', '$1 $2 $3', ), DeviceParser( '; *(?:Ideapad )?K1 Build/', None, 'Lenovo Ideapad K1', 'Lenovo', 'Ideapad K1', ), DeviceParser( '; *(3GC101|3GW10[01]|A390) Build/', None, '$1', 'Lenovo', '$1', ), DeviceParser( '\\b(?:Lenovo|LENOVO)+[ _\\-]?([^,;:/ ]+)', None, 'Lenovo $1', 'Lenovo', '$1', ), DeviceParser( '; *(MFC\\d+)[A-Z]{2}([^;,/]*),? Build', None, '$1$2', 'Lexibook', '$1$2', ), DeviceParser( '; *(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|;)', None, '$1', 'LG', '$1', ), DeviceParser( '[;:] *(L-\\d+[A-Z]|LGL\\d+[A-Z]?)(?:/V\\d+)? *(?:Build|[;\\)])', None, '$1', 'LG', '$1', ), DeviceParser( '; *(LG-)([A-Z]{1,2}\\d{2,}[^,;/\\)\\(]*?)(?:Build| V\\d+|[,;/\\)\\(]|$)', None, '$1$2', 'LG', '$2', ), DeviceParser( '; *(LG[ \\-]|LG)([^;/]+)[;/]? Build', None, '$1$2', 'LG', '$2', ), DeviceParser( '^(LG)-([^;/]+)/ Mozilla/.*; Android', None, '$1 $2', 'LG', '$2', ), DeviceParser( '(Web0S); Linux/(SmartTV)', None, 'LG $1 $2', 'LG', '$1 $2', ), DeviceParser( '; *((?:SMB|smb)[^;/]+) Build/', None, '$1', 'Malata', '$1', ), DeviceParser( '; *(?:Malata|MALATA) ([^;/]+) Build/', None, '$1', 'Malata', '$1', ), DeviceParser( '; *(MS[45][0-9]{3}|MID0[568][NS]?|MID[1-9]|MID[78]0[1-9]|MID970[1-9]|MID100[1-9]) Build/', None, '$1', 'Manta', '$1', ), DeviceParser( '; *(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/', None, '$1', 'Match', '$1', ), DeviceParser( '; *(GenxDroid7|MSD7.*|AX\\d.*|Tab 701|Tab 722) Build/', None, 'Maxx $1', 'Maxx', '$1', ), DeviceParser( '; *(M-PP[^;/]+|PhonePad ?\\d{2,}[^;/]+) Build', None, 'Mediacom $1', 'Mediacom', '$1', ), DeviceParser( '; *(M-MP[^;/]+|SmartPad ?\\d{2,}[^;/]+) Build', None, 'Mediacom $1', 'Mediacom', '$1', ), DeviceParser( '; *(?:MD_)?LIFETAB[ _]([^;/]+) Build', 'i', 'Medion Lifetab $1', 'Medion', 'Lifetab $1', ), DeviceParser( '; *MEDION ([^;/]+) Build', None, 'Medion $1', 'Medion', '$1', ), DeviceParser( '; *(M030|M031|M035|M040|M065|m9) Build', None, 'Meizu $1', 'Meizu', '$1', ), DeviceParser( '; *(?:meizu_|MEIZU )(.+?) *(?:Build|[;\\)])', None, 'Meizu $1', 'Meizu', '$1', ), DeviceParser( '; *(?:Micromax[ _](A111|A240)|(A111|A240)) Build', 'i', 'Micromax $1$2', 'Micromax', '$1$2', ), DeviceParser( '; *Micromax[ _](A\\d{2,3}[^;/]*) Build', 'i', 'Micromax $1', 'Micromax', '$1', ), DeviceParser( '; *(A\\d{2}|A[12]\\d{2}|A90S|A110Q) Build', 'i', 'Micromax $1', 'Micromax', '$1', ), DeviceParser( '; *Micromax[ _](P\\d{3}[^;/]*) Build', 'i', 'Micromax $1', 'Micromax', '$1', ), DeviceParser( '; *(P\\d{3}|P\\d{3}\\(Funbook\\)) Build', 'i', 'Micromax $1', 'Micromax', '$1', ), DeviceParser( '; *(MITO)[ _\\-]?([^;/]+) Build', 'i', '$1 $2', 'Mito', '$2', ), DeviceParser( '; *(Cynus)[ _](F5|T\\d|.+?) *(?:Build|[;/\\)])', 'i', '$1 $2', 'Mobistel', '$1 $2', ), DeviceParser( '; *(MODECOM )?(FreeTab) ?([^;/]+) Build', 'i', '$1$2 $3', 'Modecom', '$2 $3', ), DeviceParser( '; *(MODECOM )([^;/]+) Build', 'i', '$1 $2', 'Modecom', '$2', ), DeviceParser( '; *(MZ\\d{3}\\+?|MZ\\d{3} 4G|Xoom|XOOM[^;/]*) Build', None, 'Motorola $1', 'Motorola', '$1', ), DeviceParser( '; *(Milestone )(XT[^;/]*) Build', None, 'Motorola $1$2', 'Motorola', '$2', ), DeviceParser( '; *(Motoroi ?x|Droid X|DROIDX) Build', 'i', 'Motorola $1', 'Motorola', 'DROID X', ), DeviceParser( '; *(Droid[^;/]*|DROID[^;/]*|Milestone[^;/]*|Photon|Triumph|Devour|Titanium) Build', None, 'Motorola $1', 'Motorola', '$1', ), DeviceParser( '; *(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', None, '$1', 'Motorola', '$1', ), DeviceParser( '; *(Motorola MOT-|Motorola[ _\\-]|MOT\\-?)([^;/]+) Build', None, '$1$2', 'Motorola', '$2', ), DeviceParser( '; *(Moto[_ ]?|MOT\\-)([^;/]+) Build', None, '$1$2', 'Motorola', '$2', ), DeviceParser( '; *((?: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', None, '$1', 'Mpman', '$1', ), DeviceParser( '; *(?:MSI[ _])?(Primo\\d+|Enjoy[ _\\-][^;/]+) Build', 'i', '$1', 'Msi', '$1', ), DeviceParser( '; *Multilaser[ _]([^;/]+) Build', None, '$1', 'Multilaser', '$1', ), DeviceParser( '; *(My)[_]?(Pad)[ _]([^;/]+) Build', None, '$1$2 $3', 'MyPhone', '$1$2 $3', ), DeviceParser( '; *(My)\\|?(Phone)[ _]([^;/]+) Build', None, '$1$2 $3', 'MyPhone', '$3', ), DeviceParser( '; *(A\\d+)[ _](Duo)? Build', 'i', '$1 $2', 'MyPhone', '$1 $2', ), DeviceParser( '; *(myTab[^;/]*) Build', None, '$1', 'Mytab', '$1', ), DeviceParser( '; *(NABI2?-)([^;/]+) Build/', None, '$1$2', 'Nabi', '$2', ), DeviceParser( '; *(N-\\d+[CDE]) Build/', None, '$1', 'Nec', '$1', ), DeviceParser( '; ?(NEC-)(.*) Build/', None, '$1$2', 'Nec', '$2', ), DeviceParser( '; *(LT-NA7) Build/', None, '$1', 'Nec', 'Lifetouch Note', ), DeviceParser( '; *(NXM\\d+[A-z0-9_]*|Next\\d[A-z0-9_ \\-]*|NEXT\\d[A-z0-9_ \\-]*|Nextbook [A-z0-9_ ]*|DATAM803HC|M805)(?: Build|[\\);])', None, '$1', 'Nextbook', '$1', ), DeviceParser( '; *(Nokia)([ _\\-]*)([^;/]*) Build', 'i', '$1$2$3', 'Nokia', '$3', ), DeviceParser( '; *(Nook ?|Barnes & Noble Nook |BN )([^;/]+) Build', None, '$1$2', 'Nook', '$2', ), DeviceParser( '; *(NOOK )?(BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2) Build', None, '$1$2', 'Nook', '$2', ), DeviceParser( '; Build/(Nook)', None, '$1', 'Nook', 'Tablet', ), DeviceParser( '; *(OP110|OliPad[^;/]+) Build', None, 'Olivetti $1', 'Olivetti', '$1', ), DeviceParser( '; *OMEGA[ _\\-](MID[^;/]+) Build', None, 'Omega $1', 'Omega', '$1', ), DeviceParser( '^(MID7500|MID\\d+) Mozilla/5\\.0 \\(iPad;', None, 'Omega $1', 'Omega', '$1', ), DeviceParser( '; *((?:CIUS|cius)[^;/]*) Build', None, 'Openpeak $1', 'Openpeak', '$1', ), DeviceParser( '; *(Find ?(?:5|7a)|R8[012]\\d{1,2}|T703\\d{0,1}|U70\\d{1,2}T?|X90\\d{1,2}) Build', None, 'Oppo $1', 'Oppo', '$1', ), DeviceParser( '; *OPPO ?([^;/]+) Build/', None, 'Oppo $1', 'Oppo', '$1', ), DeviceParser( '; *(?:Odys\\-|ODYS\\-|ODYS )([^;/]+) Build', None, 'Odys $1', 'Odys', '$1', ), DeviceParser( '; *(SELECT) ?(7) Build', None, 'Odys $1 $2', 'Odys', '$1 $2', ), DeviceParser( '; *(PEDI)_(PLUS)_(W) Build', None, 'Odys $1 $2 $3', 'Odys', '$1 $2 $3', ), DeviceParser( '; *(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', None, 'Odys $1', 'Odys', '$1', ), DeviceParser( '; (ONE [a-zA-Z]\\d+) Build/', None, 'OnePlus $1', 'OnePlus', '$1', ), DeviceParser( '; (ONEPLUS [a-zA-Z]\\d+) Build/', None, 'OnePlus $1', 'OnePlus', '$1', ), DeviceParser( '; *(TP-\\d+) Build/', None, 'Orion $1', 'Orion', '$1', ), DeviceParser( '; *(G100W?) Build/', None, 'PackardBell $1', 'PackardBell', '$1', ), DeviceParser( '; *(Panasonic)[_ ]([^;/]+) Build', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *(FZ-A1B|JT-B1) Build', None, 'Panasonic $1', 'Panasonic', '$1', ), DeviceParser( '; *(dL1|DL1) Build', None, 'Panasonic $1', 'Panasonic', '$1', ), DeviceParser( '; *(SKY[ _])?(IM\\-[AT]\\d{3}[^;/]+).* Build/', None, 'Pantech $1$2', 'Pantech', '$1$2', ), DeviceParser( '; *((?:ADR8995|ADR910L|ADR930L|ADR930VW|PTL21|P8000)(?: 4G)?) Build/', None, '$1', 'Pantech', '$1', ), DeviceParser( '; *Pantech([^;/]+).* Build/', None, 'Pantech $1', 'Pantech', '$1', ), DeviceParser( '; *(papyre)[ _\\-]([^;/]+) Build/', 'i', '$1 $2', 'Papyre', '$2', ), DeviceParser( '; *(?:Touchlet )?(X10\\.[^;/]+) Build/', None, 'Pearl $1', 'Pearl', '$1', ), DeviceParser( '; PHICOMM (i800) Build/', None, 'Phicomm $1', 'Phicomm', '$1', ), DeviceParser( '; PHICOMM ([^;/]+) Build/', None, 'Phicomm $1', 'Phicomm', '$1', ), DeviceParser( '; *(FWS\\d{3}[^;/]+) Build/', None, 'Phicomm $1', 'Phicomm', '$1', ), DeviceParser( '; *(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', None, '$1', 'Philips', '$1', ), DeviceParser( '; *(?:Philips|PHILIPS)[ _]([^;/]+) Build', None, 'Philips $1', 'Philips', '$1', ), DeviceParser( 'Android 4\\..*; *(M[12356789]|U[12368]|S[123])\\ ?(pro)? Build', None, 'Pipo $1$2', 'Pipo', '$1$2', ), DeviceParser( '; *(MOMO[^;/]+) Build', None, '$1', 'Ployer', '$1', ), DeviceParser( '; *(?:Polaroid[ _])?((?:MIDC\\d{3,}|PMID\\d{2,}|PTAB\\d{3,})[^;/]*)(\\/[^;/]*)? Build/', None, '$1', 'Polaroid', '$1', ), DeviceParser( '; *(?:Polaroid )(Tablet) Build/', None, '$1', 'Polaroid', '$1', ), DeviceParser( '; *(POMP)[ _\\-](.+?) *(?:Build|[;/\\)])', None, '$1 $2', 'Pomp', '$2', ), DeviceParser( '; *(TB07STA|TB10STA|TB07FTA|TB10FTA) Build/', None, '$1', 'Positivo', '$1', ), DeviceParser( '; *(?:Positivo )?((?:YPY|Ypy)[^;/]+) Build/', None, '$1', 'Positivo', '$1', ), DeviceParser( '; *(MOB-[^;/]+) Build/', None, '$1', 'POV', '$1', ), DeviceParser( '; *POV[ _\\-]([^;/]+) Build/', None, 'POV $1', 'POV', '$1', ), DeviceParser( '; *((?:TAB-PLAYTAB|TAB-PROTAB|PROTAB|PlayTabPro|Mobii[ _\\-]|TAB-P)[^;/]*) Build/', None, 'POV $1', 'POV', '$1', ), DeviceParser( '; *(?:Prestigio )?((?:PAP|PMP)\\d[^;/]+) Build/', None, 'Prestigio $1', 'Prestigio', '$1', ), DeviceParser( '; *(PLT[0-9]{4}.*) Build/', None, '$1', 'Proscan', '$1', ), DeviceParser( '; *(A2|A5|A8|A900)_?(Classic)? Build', None, '$1 $2', 'Qmobile', '$1 $2', ), DeviceParser( '; *(Q[Mm]obile)_([^_]+)_([^_]+) Build', None, 'Qmobile $2 $3', 'Qmobile', '$2 $3', ), DeviceParser( '; *(Q\\-?[Mm]obile)[_ ](A[^;/]+) Build', None, 'Qmobile $2', 'Qmobile', '$2', ), DeviceParser( '; *(Q\\-Smart)[ _]([^;/]+) Build/', None, '$1 $2', 'Qmobilevn', '$2', ), DeviceParser( '; *(Q\\-?[Mm]obile)[ _\\-](S[^;/]+) Build/', None, '$1 $2', 'Qmobilevn', '$2', ), DeviceParser( '; *(TA1013) Build', None, '$1', 'Quanta', '$1', ), DeviceParser( '; (RCT\\w+) Build/', None, '$1', 'RCA', '$1', ), DeviceParser( '; RCA (\\w+) Build/', None, 'RCA $1', 'RCA', '$1', ), DeviceParser( '; *(RK\\d+),? Build/', None, '$1', 'Rockchip', '$1', ), DeviceParser( ' Build/(RK\\d+)', None, '$1', 'Rockchip', '$1', ), DeviceParser( '; *(SAMSUNG |Samsung )?((?:Galaxy (?:Note II|S\\d)|GT-I9082|GT-I9205|GT-N7\\d{3}|SM-N9005)[^;/]*)\\/?[^;/]* Build/', None, 'Samsung $1$2', 'Samsung', '$2', ), DeviceParser( '; *(Google )?(Nexus [Ss](?: 4G)?) Build/', None, 'Samsung $1$2', 'Samsung', '$2', ), DeviceParser( '; *(SAMSUNG |Samsung )([^\\/]*)\\/[^ ]* Build/', None, 'Samsung $2', 'Samsung', '$2', ), DeviceParser( '; *(Galaxy(?: Ace| Nexus| S ?II+|Nexus S| with MCR 1.2| Mini Plus 4G)?) Build/', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( '; *(SAMSUNG[ _\\-] *)+([^;/]+) Build', None, 'Samsung $2', 'Samsung', '$2', ), DeviceParser( '; *(SAMSUNG-)?(GT\\-[BINPS]\\d{4}[^\\/]*)(\\/[^ ]*) Build', None, 'Samsung $1$2$3', 'Samsung', '$2', ), DeviceParser( '(?:; *|^)((?:GT\\-[BIiNPS]\\d{4}|I9\\d{2}0[A-Za-z\\+]?\\b)[^;/\\)]*?)(?:Build|Linux|MIUI|[;/\\)])', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( '; (SAMSUNG-)([A-Za-z0-9\\-]+).* Build/', None, 'Samsung $1$2', 'Samsung', '$2', ), DeviceParser( '; *((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\\-[A-Za-z0-9 ]+)(/?[^ ]*)? Build', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( ' ((?:SCH)\\-[A-Za-z0-9 ]+)(/?[^ ]*)? Build', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( '; *(Behold ?(?:2|II)|YP\\-G[^;/]+|EK-GC100|SCL21|I9300) Build', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( '; *(SH\\-?\\d\\d[^;/]+|SBM\\d[^;/]+) Build', None, '$1', 'Sharp', '$1', ), DeviceParser( '; *(SHARP[ -])([^;/]+) Build', None, '$1$2', 'Sharp', '$2', ), DeviceParser( '; *(SPX[_\\-]\\d[^;/]*) Build/', None, '$1', 'Simvalley', '$1', ), DeviceParser( '; *(SX7\\-PEARL\\.GmbH) Build/', None, '$1', 'Simvalley', '$1', ), DeviceParser( '; *(SP[T]?\\-\\d{2}[^;/]*) Build/', None, '$1', 'Simvalley', '$1', ), DeviceParser( '; *(SK\\-.*) Build/', None, '$1', 'SKtelesys', '$1', ), DeviceParser( '; *(?:SKYTEX|SX)-([^;/]+) Build', None, '$1', 'Skytex', '$1', ), DeviceParser( '; *(IMAGINE [^;/]+) Build', None, '$1', 'Skytex', '$1', ), DeviceParser( '; *(SmartQ) ?([^;/]+) Build/', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *(WF7C|WF10C|SBT[^;/]+) Build', None, '$1', 'Smartbitt', '$1', ), DeviceParser( '; *(SBM(?:003SH|005SH|006SH|007SH|102SH)) Build', None, '$1', 'Sharp', '$1', ), DeviceParser( '; *(003P|101P|101P11C|102P) Build', None, '$1', 'Panasonic', '$1', ), DeviceParser( '; *(00\\dZ) Build/', None, '$1', 'ZTE', '$1', ), DeviceParser( '; HTC(X06HT) Build', None, '$1', 'HTC', '$1', ), DeviceParser( '; *(001HT|X06HT) Build', None, '$1', 'HTC', '$1', ), DeviceParser( '; *(201M) Build', None, '$1', 'Motorola', 'XT902', ), DeviceParser( '; *(ST\\d{4}.*)Build/ST', None, 'Trekstor $1', 'Trekstor', '$1', ), DeviceParser( '; *(ST\\d{4}.*) Build/', None, 'Trekstor $1', 'Trekstor', '$1', ), DeviceParser( '; *(Sony ?Ericsson ?)([^;/]+) Build', None, '$1$2', 'SonyEricsson', '$2', ), DeviceParser( '; *((?:SK|ST|E|X|LT|MK|MT|WT)\\d{2}[a-z0-9]*(?:-o)?|R800i|U20i) Build', None, '$1', 'SonyEricsson', '$1', ), DeviceParser( '; *(Xperia (?:A8|Arc|Acro|Active|Live with Walkman|Mini|Neo|Play|Pro|Ray|X\\d+)[^;/]*) Build', 'i', '$1', 'SonyEricsson', '$1', ), DeviceParser( '; Sony (Tablet[^;/]+) Build', None, 'Sony $1', 'Sony', '$1', ), DeviceParser( '; Sony ([^;/]+) Build', None, 'Sony $1', 'Sony', '$1', ), DeviceParser( '; *(Sony)([A-Za-z0-9\\-]+) Build', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *(Xperia [^;/]+) Build', None, '$1', 'Sony', '$1', ), DeviceParser( '; *(C(?:1[0-9]|2[0-9]|53|55|6[0-9])[0-9]{2}|D[25]\\d{3}|D6[56]\\d{2}) Build', None, '$1', 'Sony', '$1', ), DeviceParser( '; *(SGP\\d{3}|SGPT\\d{2}) Build', None, '$1', 'Sony', '$1', ), DeviceParser( '; *(NW-Z1000Series) Build', None, '$1', 'Sony', '$1', ), DeviceParser( 'PLAYSTATION 3', None, 'PlayStation 3', 'Sony', 'PlayStation 3', ), DeviceParser( '(PlayStation (?:Portable|Vita|\\d+))', None, '$1', 'Sony', '$1', ), DeviceParser( '; *((?:CSL_Spice|Spice|SPICE|CSL)[ _\\-]?)?([Mm][Ii])([ _\\-])?(\\d{3}[^;/]*) Build/', None, '$1$2$3$4', 'Spice', 'Mi$4', ), DeviceParser( '; *(Sprint )(.+?) *(?:Build|[;/])', None, '$1$2', 'Sprint', '$2', ), DeviceParser( '\\b(Sprint)[: ]([^;,/ ]+)', None, '$1$2', 'Sprint', '$2', ), DeviceParser( '; *(TAGI[ ]?)(MID) ?([^;/]+) Build/', None, '$1$2$3', 'Tagi', '$2$3', ), DeviceParser( '; *(Oyster500|Opal 800) Build', None, 'Tecmobile $1', 'Tecmobile', '$1', ), DeviceParser( '; *(TECNO[ _])([^;/]+) Build/', None, '$1$2', 'Tecno', '$2', ), DeviceParser( '; *Android for (Telechips|Techvision) ([^ ]+) ', 'i', '$1 $2', '$1', '$2', ), DeviceParser( '; *(T-Hub2) Build/', None, '$1', 'Telstra', '$1', ), DeviceParser( '; *(PAD) ?(100[12]) Build/', None, 'Terra $1$2', 'Terra', '$1$2', ), DeviceParser( '; *(T[BM]-\\d{3}[^;/]+) Build/', None, '$1', 'Texet', '$1', ), DeviceParser( '; *(tolino [^;/]+) Build', None, '$1', 'Thalia', '$1', ), DeviceParser( '; *Build/.* (TOLINO_BROWSER)', None, '$1', 'Thalia', 'Tolino Shine', ), DeviceParser( '; *(?:CJ[ -])?(ThL|THL)[ -]([^;/]+) Build/', None, '$1 $2', 'Thl', '$2', ), DeviceParser( '; *(T100|T200|T5|W100|W200|W8s) Build/', None, '$1', 'Thl', '$1', ), DeviceParser( '; *(T-Mobile[ _]G2[ _]Touch) Build', None, '$1', 'HTC', 'Hero', ), DeviceParser( '; *(T-Mobile[ _]G2) Build', None, '$1', 'HTC', 'Desire Z', ), DeviceParser( '; *(T-Mobile myTouch Q) Build', None, '$1', 'Huawei', 'U8730', ), DeviceParser( '; *(T-Mobile myTouch) Build', None, '$1', 'Huawei', 'U8680', ), DeviceParser( '; *(T-Mobile_Espresso) Build', None, '$1', 'HTC', 'Espresso', ), DeviceParser( '; *(T-Mobile G1) Build', None, '$1', 'HTC', 'Dream', ), DeviceParser( '\\b(T-Mobile ?)?(myTouch)[ _]?([34]G)[ _]?([^\\/]*) (?:Mozilla|Build)', None, '$1$2 $3 $4', 'HTC', '$2 $3 $4', ), DeviceParser( '\\b(T-Mobile)_([^_]+)_(.*) Build', None, '$1 $2 $3', 'Tmobile', '$2 $3', ), DeviceParser( '\\b(T-Mobile)[_ ]?(.*?)Build', None, '$1 $2', 'Tmobile', '$2', ), DeviceParser( ' (ATP[0-9]{4}) Build', None, '$1', 'Tomtec', '$1', ), DeviceParser( ' *(TOOKY)[ _\\-]([^;/]+) ?(?:Build|;)', 'i', '$1 $2', 'Tooky', '$2', ), DeviceParser( '\\b(TOSHIBA_AC_AND_AZ|TOSHIBA_FOLIO_AND_A|FOLIO_AND_A)', None, '$1', 'Toshiba', 'Folio 100', ), DeviceParser( '; *([Ff]olio ?100) Build/', None, '$1', 'Toshiba', 'Folio 100', ), DeviceParser( '; *(AT[0-9]{2,3}(?:\\-A|LE\\-A|PE\\-A|SE|a)?|AT7-A|AT1S0|Hikari-iFrame/WDPF-[^;/]+|THRiVE|Thrive) Build/', None, 'Toshiba $1', 'Toshiba', '$1', ), DeviceParser( '; *(TM-MID\\d+[^;/]+|TOUCHMATE|MID-750) Build', None, '$1', 'Touchmate', '$1', ), DeviceParser( '; *(TM-SM\\d+[^;/]+) Build', None, '$1', 'Touchmate', '$1', ), DeviceParser( '; *(A10 [Bb]asic2?) Build/', None, '$1', 'Treq', '$1', ), DeviceParser( '; *(TREQ[ _\\-])([^;/]+) Build', 'i', '$1$2', 'Treq', '$2', ), DeviceParser( '; *(X-?5|X-?3) Build/', None, '$1', 'Umeox', '$1', ), DeviceParser( '; *(A502\\+?|A936|A603|X1|X2) Build/', None, '$1', 'Umeox', '$1', ), DeviceParser( '(TOUCH(?:TAB|PAD).+?) Build/', 'i', 'Versus $1', 'Versus', '$1', ), DeviceParser( '(VERTU) ([^;/]+) Build/', None, '$1 $2', 'Vertu', '$2', ), DeviceParser( '; *(Videocon)[ _\\-]([^;/]+) *(?:Build|;)', None, '$1 $2', 'Videocon', '$2', ), DeviceParser( ' (VT\\d{2}[A-Za-z]*) Build', None, '$1', 'Videocon', '$1', ), DeviceParser( '; *((?:ViewPad|ViewPhone|VSD)[^;/]+) Build/', None, '$1', 'Viewsonic', '$1', ), DeviceParser( '; *(ViewSonic-)([^;/]+) Build/', None, '$1$2', 'Viewsonic', '$2', ), DeviceParser( '; *(GTablet.*) Build/', None, '$1', 'Viewsonic', '$1', ), DeviceParser( '; *([Vv]ivo)[ _]([^;/]+) Build', None, '$1 $2', 'vivo', '$2', ), DeviceParser( '(Vodafone) (.*) Build/', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *(?:Walton[ _\\-])?(Primo[ _\\-][^;/]+) Build', 'i', 'Walton $1', 'Walton', '$1', ), DeviceParser( '; *(?:WIKO[ \\-])?(CINK\\+?|BARRY|BLOOM|DARKFULL|DARKMOON|DARKNIGHT|DARKSIDE|FIZZ|HIGHWAY|IGGY|OZZY|RAINBOW|STAIRWAY|SUBLIM|WAX|CINK [^;/]+) Build/', 'i', 'Wiko $1', 'Wiko', '$1', ), DeviceParser( '; *WellcoM-([^;/]+) Build', None, 'Wellcom $1', 'Wellcom', '$1', ), DeviceParser( '(?:(WeTab)-Browser|; (wetab) Build)', None, '$1', 'WeTab', 'WeTab', ), DeviceParser( '; *(AT-AS[^;/]+) Build', None, 'Wolfgang $1', 'Wolfgang', '$1', ), DeviceParser( '; *(?:Woxter|Wxt) ([^;/]+) Build', None, 'Woxter $1', 'Woxter', '$1', ), DeviceParser( '; *(?: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/', None, 'Yarvik $1', 'Yarvik', '$1', ), DeviceParser( '; *([A-Z]{2,4})(M\\d{3,}[A-Z]{2})([^;\\)\\/]*)(?: Build|[;\\)])', None, 'Yifang $1$2$3', 'Yifang', '$2', ), DeviceParser( '; *((MI|HM|MI-ONE|Redmi)[ -](NOTE |Note )?[^;/]*) (Build|MIUI)/', None, 'XiaoMi $1', 'XiaoMi', '$1', ), DeviceParser( '; *XOLO[ _]([^;/]*tab.*) Build', 'i', 'Xolo $1', 'Xolo', '$1', ), DeviceParser( '; *XOLO[ _]([^;/]+) Build', 'i', 'Xolo $1', 'Xolo', '$1', ), DeviceParser( '; *(q\\d0{2,3}[a-z]?) Build', 'i', 'Xolo $1', 'Xolo', '$1', ), DeviceParser( '; *(PAD ?[79]\\d+[^;/]*|TelePAD\\d+[^;/]) Build', None, 'Xoro $1', 'Xoro', '$1', ), DeviceParser( '; *(?:(?:ZOPO|Zopo)[ _]([^;/]+)|(ZP ?(?:\\d{2}[^;/]+|C2))|(C[2379])) Build', None, '$1$2$3', 'Zopo', '$1$2$3', ), DeviceParser( '; *(ZiiLABS) (Zii[^;/]*) Build', None, '$1 $2', 'ZiiLabs', '$2', ), DeviceParser( '; *(Zii)_([^;/]*) Build', None, '$1 $2', 'ZiiLabs', '$2', ), DeviceParser( '; *(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', None, '$1', 'ZTE', '$1', ), DeviceParser( '; *([A-Z]\\d+)_USA_[^;]* Build', None, '$1', 'ZTE', '$1', ), DeviceParser( '; *(SmartTab\\d+)[^;]* Build', None, '$1', 'ZTE', '$1', ), DeviceParser( '; *(?:Blade|BLADE|ZTE-BLADE)([^;/]*) Build', None, 'ZTE Blade$1', 'ZTE', 'Blade$1', ), DeviceParser( '; *(?:Skate|SKATE|ZTE-SKATE)([^;/]*) Build', None, 'ZTE Skate$1', 'ZTE', 'Skate$1', ), DeviceParser( '; *(Orange |Optimus )(Monte Carlo|San Francisco) Build', None, '$1$2', 'ZTE', '$1$2', ), DeviceParser( '; *(?:ZXY-ZTE_|ZTE\\-U |ZTE[\\- _]|ZTE-C[_ ])([^;/]+) Build', None, 'ZTE $1', 'ZTE', '$1', ), DeviceParser( '; (BASE) (lutea|Lutea 2|Tab[^;]*) Build', None, '$1 $2', 'ZTE', '$1 $2', ), DeviceParser( '; (Avea inTouch 2|soft stone|tmn smart a7|Movistar[ _]Link) Build', 'i', '$1', 'ZTE', '$1', ), DeviceParser( '; *(vp9plus)\\)', None, '$1', 'ZTE', '$1', ), DeviceParser( '; ?(Cloud[ _]Z5|z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900) Build/', None, '$1', 'Zync', '$1', ), DeviceParser( '; ?(KFOT|Kindle Fire) Build\\b', None, 'Kindle Fire', 'Amazon', 'Kindle Fire', ), DeviceParser( '; ?(KFOTE|Amazon Kindle Fire2) Build\\b', None, 'Kindle Fire 2', 'Amazon', 'Kindle Fire 2', ), DeviceParser( '; ?(KFTT) Build\\b', None, 'Kindle Fire HD', 'Amazon', 'Kindle Fire HD 7"', ), DeviceParser( '; ?(KFJWI) Build\\b', None, 'Kindle Fire HD 8.9" WiFi', 'Amazon', 'Kindle Fire HD 8.9" WiFi', ), DeviceParser( '; ?(KFJWA) Build\\b', None, 'Kindle Fire HD 8.9" 4G', 'Amazon', 'Kindle Fire HD 8.9" 4G', ), DeviceParser( '; ?(KFSOWI) Build\\b', None, 'Kindle Fire HD 7" WiFi', 'Amazon', 'Kindle Fire HD 7" WiFi', ), DeviceParser( '; ?(KFTHWI) Build\\b', None, 'Kindle Fire HDX 7" WiFi', 'Amazon', 'Kindle Fire HDX 7" WiFi', ), DeviceParser( '; ?(KFTHWA) Build\\b', None, 'Kindle Fire HDX 7" 4G', 'Amazon', 'Kindle Fire HDX 7" 4G', ), DeviceParser( '; ?(KFAPWI) Build\\b', None, 'Kindle Fire HDX 8.9" WiFi', 'Amazon', 'Kindle Fire HDX 8.9" WiFi', ), DeviceParser( '; ?(KFAPWA) Build\\b', None, 'Kindle Fire HDX 8.9" 4G', 'Amazon', 'Kindle Fire HDX 8.9" 4G', ), DeviceParser( '; ?Amazon ([^;/]+) Build\\b', None, '$1', 'Amazon', '$1', ), DeviceParser( '; ?(Kindle) Build\\b', None, 'Kindle', 'Amazon', 'Kindle', ), DeviceParser( '; ?(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))? Build\\b', None, 'Kindle Fire', 'Amazon', 'Kindle Fire$2', ), DeviceParser( ' (Kindle)/(\\d+\\.\\d+)', None, 'Kindle', 'Amazon', '$1 $2', ), DeviceParser( ' (Silk|Kindle)/(\\d+)\\.', None, 'Kindle', 'Amazon', 'Kindle', ), DeviceParser( '(sprd)\\-([^/]+)/', None, '$1 $2', '$1', '$2', ), DeviceParser( '; *(H\\d{2}00\\+?) Build', None, '$1', 'Hero', '$1', ), DeviceParser( '; *(iphone|iPhone5) Build/', None, 'Xianghe $1', 'Xianghe', '$1', ), DeviceParser( '; *(e\\d{4}[a-z]?_?v\\d+|v89_[^;/]+)[^;/]+ Build/', None, 'Xianghe $1', 'Xianghe', '$1', ), DeviceParser( '\\bUSCC[_\\-]?([^ ;/\\)]+)', None, '$1', 'Cellular', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:ALCATEL)[^;]*; *([^;,\\)]+)', None, 'Alcatel $1', 'Alcatel', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:ASUS|Asus)[^;]*; *([^;,\\)]+)', None, 'Asus $1', 'Asus', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:DELL|Dell)[^;]*; *([^;,\\)]+)', None, 'Dell $1', 'Dell', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:HTC|Htc|HTC_blocked[^;]*)[^;]*; *(?:HTC)?([^;,\\)]+)', None, 'HTC $1', 'HTC', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:HUAWEI)[^;]*; *(?:HUAWEI )?([^;,\\)]+)', None, 'Huawei $1', 'Huawei', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:LG|Lg)[^;]*; *(?:LG[ \\-])?([^;,\\)]+)', None, 'LG $1', 'LG', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:rv:11; )?(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?)*(\\d{3,}[^;\\)]*)', None, 'Lumia $1', 'Nokia', 'Lumia $1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:NOKIA|Nokia)[^;]*; *(RM-\\d{3,})', None, 'Nokia $1', 'Nokia', '$1', ), DeviceParser( '(?:Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)]|WPDesktop;) ?(?:ARM; ?Touch; ?|Touch; ?)?(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?)*([^;\\)]+)', None, 'Nokia $1', 'Nokia', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:Microsoft(?: Corporation)?)[^;]*; *([^;,\\)]+)', None, 'Microsoft $1', 'Microsoft', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:SAMSUNG)[^;]*; *(?:SAMSUNG )?([^;,\\.\\)]+)', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?(?:TOSHIBA|FujitsuToshibaMobileCommun)[^;]*; *([^;,\\)]+)', None, 'Toshiba $1', 'Toshiba', '$1', ), DeviceParser( 'Windows Phone [^;]+; .*?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?)?([^;]+); *([^;,\\)]+)', None, '$1 $2', '$1', '$2', ), DeviceParser( '(?:^|; )SAMSUNG\\-([A-Za-z0-9\\-]+).* Bada/', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( '\\(Mobile; ALCATEL ?(One|ONE) ?(Touch|TOUCH) ?([^;/]+)(?:/[^;]+)?; rv:[^\\)]+\\) Gecko/[^\\/]+ Firefox/', None, 'Alcatel $1 $2 $3', 'Alcatel', 'One Touch $3', ), DeviceParser( '\\(Mobile; (?:ZTE([^;]+)|(OpenC)); rv:[^\\)]+\\) Gecko/[^\\/]+ Firefox/', None, 'ZTE $1$2', 'ZTE', '$1$2', ), DeviceParser( 'Nokia(N[0-9]+)([A-z_\\-][A-z0-9_\\-]*)', None, 'Nokia $1', 'Nokia', '$1$2', ), DeviceParser( '(?:NOKIA|Nokia)(?:\\-| *)(?:([A-Za-z0-9]+)\\-[0-9a-f]{32}|([A-Za-z0-9\\-]+)(?:UCBrowser)|([A-Za-z0-9\\-]+))', None, 'Nokia $1$2$3', 'Nokia', '$1$2$3', ), DeviceParser( 'Lumia ([A-Za-z0-9\\-]+)', None, 'Lumia $1', 'Nokia', 'Lumia $1', ), DeviceParser( '\\(Symbian; U; S60 V5; [A-z]{2}\\-[A-z]{2}; (SonyEricsson|Samsung|Nokia|LG)([^;/]+)\\)', None, '$1 $2', '$1', '$2', ), DeviceParser( '\\(Symbian(?:/3)?; U; ([^;]+);', None, 'Nokia $1', 'Nokia', '$1', ), DeviceParser( 'BB10; ([A-Za-z0-9\\- ]+)\\)', None, 'BlackBerry $1', 'BlackBerry', '$1', ), DeviceParser( 'Play[Bb]ook.+RIM Tablet OS', None, 'BlackBerry Playbook', 'BlackBerry', 'Playbook', ), DeviceParser( 'Black[Bb]erry ([0-9]+);', None, 'BlackBerry $1', 'BlackBerry', '$1', ), DeviceParser( 'Black[Bb]erry([0-9]+)', None, 'BlackBerry $1', 'BlackBerry', '$1', ), DeviceParser( 'Black[Bb]erry;', None, 'BlackBerry', 'BlackBerry', None, ), DeviceParser( '(Pre|Pixi)/\\d+\\.\\d+', None, 'Palm $1', 'Palm', '$1', ), DeviceParser( 'Palm([0-9]+)', None, 'Palm $1', 'Palm', '$1', ), DeviceParser( 'Treo([A-Za-z0-9]+)', None, 'Palm Treo $1', 'Palm', 'Treo $1', ), DeviceParser( 'webOS.*(P160U(?:NA)?)/(\\d+).(\\d+)', None, 'HP Veer', 'HP', 'Veer', ), DeviceParser( '(Touch[Pp]ad)/\\d+\\.\\d+', None, 'HP TouchPad', 'HP', 'TouchPad', ), DeviceParser( 'HPiPAQ([A-Za-z0-9]+)/\\d+.\\d+', None, 'HP iPAQ $1', 'HP', 'iPAQ $1', ), DeviceParser( 'PDA; (PalmOS)/sony/model ([a-z]+)/Revision', None, '$1', 'Sony', '$1 $2', ), DeviceParser( '(Apple\\s?TV)', None, 'AppleTV', 'Apple', 'AppleTV', ), DeviceParser( '(QtCarBrowser)', None, 'Tesla Model S', 'Tesla', 'Model S', ), DeviceParser( '(iPhone|iPad|iPod)(\\d+,\\d+)', None, '$1', 'Apple', '$1$2', ), DeviceParser( '(iPad)(?:;| Simulator;)', None, '$1', 'Apple', '$1', ), DeviceParser( '(iPod)(?:;| touch;| Simulator;)', None, '$1', 'Apple', '$1', ), DeviceParser( '(iPhone)(?:;| Simulator;)', None, '$1', 'Apple', '$1', ), DeviceParser( 'iPhone', None, 'iPhone', 'Apple', 'iPhone', ), DeviceParser( 'CFNetwork/.* Darwin/\\d.*\\(((?:Mac|iMac|PowerMac|PowerBook)[^\\d]*)(\\d+)(?:,|%2C)(\\d+)', None, '$1$2,$3', 'Apple', '$1$2,$3', ), DeviceParser( 'CFNetwork/.* Darwin/\\d+\\.\\d+\\.\\d+ \\(x86_64\\)', None, 'Mac', 'Apple', 'Mac', ), DeviceParser( 'CFNetwork/.* Darwin/\\d', None, 'iOS-Device', 'Apple', 'iOS-Device', ), DeviceParser( 'Outlook-(iOS)/\\d+\\.\\d+\\.prod\\.iphone', None, 'iPhone', 'Apple', 'iPhone', ), DeviceParser( 'acer_([A-Za-z0-9]+)_', None, 'Acer $1', 'Acer', '$1', ), DeviceParser( '(?:ALCATEL|Alcatel)-([A-Za-z0-9\\-]+)', None, 'Alcatel $1', 'Alcatel', '$1', ), DeviceParser( '(?:Amoi|AMOI)\\-([A-Za-z0-9]+)', None, 'Amoi $1', 'Amoi', '$1', ), DeviceParser( '(?:; |\\/|^)((?:Transformer (?:Pad|Prime) |Transformer |PadFone[ _]?)[A-Za-z0-9]*)', None, 'Asus $1', 'Asus', '$1', ), DeviceParser( '(?:asus.*?ASUS|Asus|ASUS|asus)[\\- ;]*((?:Transformer (?:Pad|Prime) |Transformer |Padfone |Nexus[ _])?[A-Za-z0-9]+)', None, 'Asus $1', 'Asus', '$1', ), DeviceParser( '\\bBIRD[ \\-\\.]([A-Za-z0-9]+)', None, 'Bird $1', 'Bird', '$1', ), DeviceParser( '\\bDell ([A-Za-z0-9]+)', None, 'Dell $1', 'Dell', '$1', ), DeviceParser( 'DoCoMo/2\\.0 ([A-Za-z0-9]+)', None, 'DoCoMo $1', 'DoCoMo', '$1', ), DeviceParser( '([A-Za-z0-9]+)_W;FOMA', None, 'DoCoMo $1', 'DoCoMo', '$1', ), DeviceParser( '([A-Za-z0-9]+);FOMA', None, 'DoCoMo $1', 'DoCoMo', '$1', ), DeviceParser( '\\b(?:HTC/|HTC/[a-z0-9]+/)?HTC[ _\\-;]? *(.*?)(?:-?Mozilla|fingerPrint|[;/\\(\\)]|$)', None, 'HTC $1', 'HTC', '$1', ), DeviceParser( 'Huawei([A-Za-z0-9]+)', None, 'Huawei $1', 'Huawei', '$1', ), DeviceParser( 'HUAWEI-([A-Za-z0-9]+)', None, 'Huawei $1', 'Huawei', '$1', ), DeviceParser( 'vodafone([A-Za-z0-9]+)', None, 'Huawei Vodafone $1', 'Huawei', 'Vodafone $1', ), DeviceParser( 'i\\-mate ([A-Za-z0-9]+)', None, 'i-mate $1', 'i-mate', '$1', ), DeviceParser( 'Kyocera\\-([A-Za-z0-9]+)', None, 'Kyocera $1', 'Kyocera', '$1', ), DeviceParser( 'KWC\\-([A-Za-z0-9]+)', None, 'Kyocera $1', 'Kyocera', '$1', ), DeviceParser( 'Lenovo[_\\-]([A-Za-z0-9]+)', None, 'Lenovo $1', 'Lenovo', '$1', ), DeviceParser( '(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+ \\([^;]*; *(LG)E *; *([^;]*) *;[^;]*;[^;]*;\\)', None, '$1', '$2', '$3', ), DeviceParser( '(HbbTV)/1\\.1\\.1.*CE-HTML/1\\.\\d;(Vendor/)*(THOM[^;]*?)[;\\s](?:.*SW-Version/.*)*(LF[^;]+);?', None, '$1', 'Thomson', '$4', ), DeviceParser( '(HbbTV)(?:/1\\.1\\.1)?(?: ?\\(;;;;;\\))?; *CE-HTML(?:/1\\.\\d)?; *([^ ]+) ([^;]+);', None, '$1', '$2', '$3', ), DeviceParser( '(HbbTV)/1\\.1\\.1 \\(;;;;;\\) Maple_2011', None, '$1', 'Samsung', None, ), DeviceParser( '(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+ \\([^;]*; *(?:CUS:([^;]*)|([^;]+)) *; *([^;]*) *;.*;', None, '$1', '$2$3', '$4', ), DeviceParser( '(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+', None, '$1', None, None, ), DeviceParser( 'LGE; (?:Media\\/)?([^;]*);[^;]*;[^;]*;?\\); "?LG NetCast(\\.TV|\\.Media|)-\\d+', None, 'NetCast$2', 'LG', '$1', ), DeviceParser( 'InettvBrowser/[0-9]+\\.[0-9A-Z]+ \\([^;]*;(Sony)([^;]*);[^;]*;[^\\)]*\\)', None, 'Inettv', '$1', '$2', ), DeviceParser( 'InettvBrowser/[0-9]+\\.[0-9A-Z]+ \\([^;]*;([^;]*);[^;]*;[^\\)]*\\)', None, 'Inettv', 'Generic_Inettv', '$1', ), DeviceParser( '(?:InettvBrowser|TSBNetTV|NETTV|HBBTV)', None, 'Inettv', 'Generic_Inettv', None, ), DeviceParser( 'Series60/\\d\\.\\d (LG)[\\-]?([A-Za-z0-9 \\-]+)', None, '$1 $2', '$1', '$2', ), DeviceParser( '\\b(?:LGE[ \\-]LG\\-(?:AX)?|LGE |LGE?-LG|LGE?[ \\-]|LG[ /\\-]|lg[\\-])([A-Za-z0-9]+)\\b', None, 'LG $1', 'LG', '$1', ), DeviceParser( '(?:^LG[\\-]?|^LGE[\\-/]?)([A-Za-z]+[0-9]+[A-Za-z]*)', None, 'LG $1', 'LG', '$1', ), DeviceParser( '^LG([0-9]+[A-Za-z]*)', None, 'LG $1', 'LG', '$1', ), DeviceParser( '(KIN\\.[^ ]+) (\\d+)\\.(\\d+)', None, 'Microsoft $1', 'Microsoft', '$1', ), DeviceParser( '(?:MSIE|XBMC).*\\b(Xbox)\\b', None, '$1', 'Microsoft', '$1', ), DeviceParser( '; ARM; Trident/6\\.0; Touch[\\);]', None, 'Microsoft Surface RT', 'Microsoft', 'Surface RT', ), DeviceParser( 'Motorola\\-([A-Za-z0-9]+)', None, 'Motorola $1', 'Motorola', '$1', ), DeviceParser( 'MOTO\\-([A-Za-z0-9]+)', None, 'Motorola $1', 'Motorola', '$1', ), DeviceParser( 'MOT\\-([A-z0-9][A-z0-9\\-]*)', None, 'Motorola $1', 'Motorola', '$1', ), DeviceParser( 'Nintendo WiiU', None, 'Nintendo Wii U', 'Nintendo', 'Wii U', ), DeviceParser( 'Nintendo (DS|3DS|DSi|Wii);', None, 'Nintendo $1', 'Nintendo', '$1', ), DeviceParser( '(?:Pantech|PANTECH)[ _-]?([A-Za-z0-9\\-]+)', None, 'Pantech $1', 'Pantech', '$1', ), DeviceParser( 'Philips([A-Za-z0-9]+)', None, 'Philips $1', 'Philips', '$1', ), DeviceParser( 'Philips ([A-Za-z0-9]+)', None, 'Philips $1', 'Philips', '$1', ), DeviceParser( '(SMART-TV); .* Tizen ', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( 'SymbianOS/9\\.\\d.* Samsung[/\\-]([A-Za-z0-9 \\-]+)', None, 'Samsung $1', 'Samsung', '$1', ), DeviceParser( '(Samsung)(SGH)(i[0-9]+)', None, '$1 $2$3', '$1', '$2-$3', ), DeviceParser( 'SAMSUNG-ANDROID-MMS/([^;/]+)', None, '$1', 'Samsung', '$1', ), DeviceParser( 'SAMSUNG(?:; |[ -/])([A-Za-z0-9\\-]+)', 'i', 'Samsung $1', 'Samsung', '$1', ), DeviceParser( '(Dreamcast)', None, 'Sega $1', 'Sega', '$1', ), DeviceParser( '^SIE-([A-Za-z0-9]+)', None, 'Siemens $1', 'Siemens', '$1', ), DeviceParser( 'Softbank/[12]\\.0/([A-Za-z0-9]+)', None, 'Softbank $1', 'Softbank', '$1', ), DeviceParser( 'SonyEricsson ?([A-Za-z0-9\\-]+)', None, 'Ericsson $1', 'SonyEricsson', '$1', ), DeviceParser( 'Android [^;]+; ([^ ]+) (Sony)/', None, '$2 $1', '$2', '$1', ), DeviceParser( '(Sony)(?:BDP\\/|\\/)?([^ /;\\)]+)[ /;\\)]', None, '$1 $2', '$1', '$2', ), DeviceParser( 'Puffin/[\\d\\.]+IT', None, 'iPad', 'Apple', 'iPad', ), DeviceParser( 'Puffin/[\\d\\.]+IP', None, 'iPhone', 'Apple', 'iPhone', ), DeviceParser( 'Puffin/[\\d\\.]+AT', None, 'Generic Tablet', 'Generic', 'Tablet', ), DeviceParser( 'Puffin/[\\d\\.]+AP', None, 'Generic Smartphone', 'Generic', 'Smartphone', ), DeviceParser( 'Android[\\- ][\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{0,2}; WOWMobile (.+) Build[/ ]', None, None, 'Generic_Android', '$1', ), DeviceParser( 'Android[\\- ][\\d]+\\.[\\d]+\\-update1; [A-Za-z]{2}\\-[A-Za-z]{0,2} *; *(.+?) Build[/ ]', None, None, 'Generic_Android', '$1', ), DeviceParser( 'Android[\\- ][\\d]+(?:\\.[\\d]+){1,2}; *[A-Za-z]{2}[_\\-][A-Za-z]{0,2}\\-? *; *(.+?) Build[/ ]', None, None, 'Generic_Android', '$1', ), DeviceParser( 'Android[\\- ][\\d]+(?:\\.[\\d]+){1,2}; *[A-Za-z]{0,2}\\- *; *(.+?) Build[/ ]', None, None, 'Generic_Android', '$1', ), DeviceParser( 'Android[\\- ][\\d]+(?:\\.[\\d]+){1,2}; *[a-z]{0,2}[_\\-]?[A-Za-z]{0,2};? Build[/ ]', None, 'Generic Smartphone', 'Generic', 'Smartphone', ), DeviceParser( 'Android[\\- ][\\d]+(?:\\.[\\d]+){1,2}; *\\-?[A-Za-z]{2}; *(.+?) Build[/ ]', None, None, 'Generic_Android', '$1', ), DeviceParser( 'Android[\\- ][\\d]+(?:\\.[\\d]+){1,2}(?:;.*)?; *(.+?) Build[/ ]', None, None, 'Generic_Android', '$1', ), DeviceParser( '(GoogleTV)', None, None, 'Generic_Inettv', '$1', ), DeviceParser( '(WebTV)/\\d+.\\d+', None, None, 'Generic_Inettv', '$1', ), DeviceParser( '^(Roku)/DVP-\\d+\\.\\d+', None, None, 'Generic_Inettv', '$1', ), DeviceParser( '(Android 3\\.\\d|Opera Tablet|Tablet; .+Firefox/|Android.*(?:Tab|Pad))', 'i', 'Generic Tablet', 'Generic', 'Tablet', ), DeviceParser( '(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)', None, 'Generic Smartphone', 'Generic', 'Smartphone', ), DeviceParser( '(hiptop|avantgo|plucker|xiino|blazer|elaine)', 'i', 'Generic Smartphone', 'Generic', 'Smartphone', ), DeviceParser( '(bot|BUbiNG|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|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)', 'i', 'Spider', 'Spider', 'Desktop', ), DeviceParser( '^(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)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone', ), DeviceParser( '^(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)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone', ), DeviceParser( '^(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)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone', ), DeviceParser( '^(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_)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone', ), DeviceParser( '^(Ice)$', None, 'Generic Feature Phone', 'Generic', 'Feature Phone', ), DeviceParser( '(wap[\\-\\ ]browser|maui|netfront|obigo|teleca|up\\.browser|midp|Opera Mini)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone', ), ] OS_PARSERS = [ OSParser( 'HbbTV/\\d+\\.\\d+\\.\\d+ \\( ;(LG)E ;NetCast 4.0', None, '2013', None, None, None, ), OSParser( 'HbbTV/\\d+\\.\\d+\\.\\d+ \\( ;(LG)E ;NetCast 3.0', None, '2012', None, None, None, ), OSParser( 'HbbTV/1.1.1 \\(;;;;;\\) Maple_2011', 'Samsung', '2011', None, None, None, ), OSParser( 'HbbTV/\\d+\\.\\d+\\.\\d+ \\(;(Samsung);SmartTV([0-9]{4});.*FXPDEUC', None, None, 'UE40F7000', None, None, ), OSParser( 'HbbTV/\\d+\\.\\d+\\.\\d+ \\(;(Samsung);SmartTV([0-9]{4});.*MST12DEUC', None, None, 'UE32F4500', None, None, ), OSParser( 'HbbTV/1.1.1 \\(; (Philips);.*NETTV/4', None, '2013', None, None, None, ), OSParser( 'HbbTV/1.1.1 \\(; (Philips);.*NETTV/3', None, '2012', None, None, None, ), OSParser( 'HbbTV/1.1.1 \\(; (Philips);.*NETTV/2', None, '2011', None, None, None, ), OSParser( 'HbbTV/\\d+\\.\\d+\\.\\d+.*(firetv)-firefox-plugin (\\d+).(\\d+).(\\d+)', 'FireHbbTV', None, None, None, None, ), OSParser( 'HbbTV/\\d+\\.\\d+\\.\\d+ \\(.*; ?([a-zA-Z]+) ?;.*(201[1-9]).*\\)', None, None, None, None, None, ), OSParser( '(Windows Phone) (?:OS[ /])?(\\d+)\\.(\\d+)', None, None, None, None, None, ), OSParser( '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone)[ +]+(\\d+)[_\\.](\\d+)(?:[_\\.](\\d+))?.*Outlook-iOS-Android', 'iOS', None, None, None, None, ), OSParser( '(Android)[ \\-/](\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?', None, None, None, None, None, ), OSParser( '(Android) Donut', None, '1', '2', None, None, ), OSParser( '(Android) Eclair', None, '2', '1', None, None, ), OSParser( '(Android) Froyo', None, '2', '2', None, None, ), OSParser( '(Android) Gingerbread', None, '2', '3', None, None, ), OSParser( '(Android) Honeycomb', None, '3', None, None, None, ), OSParser( '^UCWEB.*; (Adr) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?;', 'Android', None, None, None, None, ), OSParser( '^UCWEB.*; (iPad|iPh|iPd) OS (\\d+)_(\\d+)(?:_(\\d+))?;', 'iOS', None, None, None, None, ), OSParser( '^UCWEB.*; (wds) (\\d+)\\.(\\d+)(?:\\.(\\d+))?;', 'Windows Phone', None, None, None, None, ), OSParser( '^(JUC).*; ?U; ?(?:Android)?(\\d+)\\.(\\d+)(?:[\\.\\-]([a-z0-9]+))?', 'Android', None, None, None, None, ), OSParser( '(Silk-Accelerated=[a-z]{4,5})', 'Android', None, None, None, None, ), OSParser( '(XBLWP7)', 'Windows Phone', None, None, None, None, ), OSParser( '(Windows ?Mobile)', 'Windows Mobile', None, None, None, None, ), OSParser( '(Windows (?:NT 5\\.2|NT 5\\.1))', 'Windows', 'XP', None, None, None, ), OSParser( '(Windows NT 6\\.1)', 'Windows', '7', None, None, None, ), OSParser( '(Windows NT 6\\.0)', 'Windows', 'Vista', None, None, None, ), OSParser( '(Win 9x 4\\.90)', 'Windows', 'ME', None, None, None, ), OSParser( '(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\\.0|Windows Vista|Windows 2000|Windows 3.1)', None, None, None, None, None, ), OSParser( '(Windows NT 6\\.2; ARM;)', 'Windows', 'RT', None, None, None, ), OSParser( '(Windows NT 6\\.2)', 'Windows', '8', None, None, None, ), OSParser( '(Windows NT 6\\.3; ARM;)', 'Windows', 'RT 8.1', None, None, None, ), OSParser( '(Windows NT 6\\.3)', 'Windows', '8.1', None, None, None, ), OSParser( '(Windows NT 6\\.4)', 'Windows', '10', None, None, None, ), OSParser( '(Windows NT 10\\.0)', 'Windows', '10', None, None, None, ), OSParser( '(Windows NT 5\\.0)', 'Windows', '2000', None, None, None, ), OSParser( '(WinNT4.0)', 'Windows', 'NT 4.0', None, None, None, ), OSParser( '(Windows ?CE)', 'Windows', 'CE', None, None, None, ), OSParser( 'Win ?(95|98|3.1|NT|ME|2000)', 'Windows', '$1', None, None, None, ), OSParser( 'Win16', 'Windows', '3.1', None, None, None, ), OSParser( 'Win32', 'Windows', '95', None, None, None, ), OSParser( '^Box.*Windows/([\\d.]+);', 'Windows', '$1', None, None, None, ), OSParser( '(Tizen)[/ ](\\d+)\\.(\\d+)', None, None, None, None, None, ), OSParser( '((?:Mac[ +]?|; )OS[ +]X)[\\s+/](?:(\\d+)[_.](\\d+)(?:[_.](\\d+))?|Mach-O)', 'Mac OS X', None, None, None, None, ), OSParser( ' (Dar)(win)/(9).(\\d+).*\\((?:i386|x86_64|Power Macintosh)\\)', 'Mac OS X', '10', '5', None, None, ), OSParser( ' (Dar)(win)/(10).(\\d+).*\\((?:i386|x86_64)\\)', 'Mac OS X', '10', '6', None, None, ), OSParser( ' (Dar)(win)/(11).(\\d+).*\\((?:i386|x86_64)\\)', 'Mac OS X', '10', '7', None, None, ), OSParser( ' (Dar)(win)/(12).(\\d+).*\\((?:i386|x86_64)\\)', 'Mac OS X', '10', '8', None, None, ), OSParser( ' (Dar)(win)/(13).(\\d+).*\\((?:i386|x86_64)\\)', 'Mac OS X', '10', '9', None, None, ), OSParser( 'Mac_PowerPC', 'Mac OS', None, None, None, None, ), OSParser( '(?:PPC|Intel) (Mac OS X)', None, None, None, None, None, ), OSParser( '^Box.*;(Darwin)/(10)\\.(1\\d)(?:\\.(\\d+))?', 'Mac OS X', None, None, None, None, ), OSParser( '(Apple\\s?TV)(?:/(\\d+)\\.(\\d+))?', 'ATV OS X', None, None, None, None, ), OSParser( '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS)[ +]+(\\d+)[_\\.](\\d+)(?:[_\\.](\\d+))?', 'iOS', None, None, None, None, ), OSParser( '(iPhone|iPad|iPod); Opera', 'iOS', None, None, None, None, ), OSParser( '(iPhone|iPad|iPod).*Mac OS X.*Version/(\\d+)\\.(\\d+)', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/(5)48\\.0\\.3.* Darwin/11\\.0\\.0', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/(5)48\\.(0)\\.4.* Darwin/(1)1\\.0\\.0', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/(5)48\\.(1)\\.4', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/(4)85\\.1(3)\\.9', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/(6)09\\.(1)\\.4', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/(6)(0)9', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/6(7)2\\.(1)\\.13', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/6(7)2\\.(1)\\.(1)4', 'iOS', None, None, None, None, ), OSParser( '(CF)(Network)/6(7)(2)\\.1\\.15', 'iOS', '7', '1', None, None, ), OSParser( '(CFNetwork)/6(7)2\\.(0)\\.(?:2|8)', 'iOS', None, None, None, None, ), OSParser( '(CFNetwork)/709\\.1', 'iOS', '8', '0.b5', None, None, ), OSParser( '(CF)(Network)/711\\.(\\d)', 'iOS', '8', None, None, None, ), OSParser( '(CF)(Network)/(720)\\.(\\d)', 'Mac OS X', '10', '10', None, None, ), OSParser( '(CF)(Network)/(760)\\.(\\d)', 'Mac OS X', '10', '11', None, None, ), OSParser( '(CF)(Network)/758\\.(\\d)', 'iOS', '9', None, None, None, ), OSParser( '(CF)(Network)/808\\.(\\d)', 'iOS', '10', None, None, None, ), OSParser( 'CFNetwork/.* Darwin/17\\.\\d+.*\\(x86_64\\)', 'Mac OS X', '10', '13', None, None, ), OSParser( 'CFNetwork/.* Darwin/16\\.\\d+.*\\(x86_64\\)', 'Mac OS X', '10', '12', None, None, ), OSParser( 'CFNetwork/8.* Darwin/15\\.\\d+.*\\(x86_64\\)', 'Mac OS X', '10', '11', None, None, ), OSParser( 'CFNetwork/.* Darwin/(9)\\.\\d+', 'iOS', '1', None, None, None, ), OSParser( 'CFNetwork/.* Darwin/(10)\\.\\d+', 'iOS', '4', None, None, None, ), OSParser( 'CFNetwork/.* Darwin/(11)\\.\\d+', 'iOS', '5', None, None, None, ), OSParser( 'CFNetwork/.* Darwin/(13)\\.\\d+', 'iOS', '6', None, None, None, ), OSParser( 'CFNetwork/6.* Darwin/(14)\\.\\d+', 'iOS', '7', None, None, None, ), OSParser( 'CFNetwork/7.* Darwin/(14)\\.\\d+', 'iOS', '8', '0', None, None, ), OSParser( 'CFNetwork/7.* Darwin/(15)\\.\\d+', 'iOS', '9', '0', None, None, ), OSParser( 'CFNetwork/8.* Darwin/16\\.5\\.\\d+', 'iOS', '10', '3', None, None, ), OSParser( 'CFNetwork/8.* Darwin/16\\.6\\.\\d+', 'iOS', '10', '3', '2', None, ), OSParser( 'CFNetwork/8.* Darwin/16\\.7\\.\\d+', 'iOS', '10', '3', '3', None, ), OSParser( 'CFNetwork/8.* Darwin/(16)\\.\\d+', 'iOS', '10', None, None, None, ), OSParser( 'CFNetwork/8.* Darwin/17\\.0\\.\\d+', 'iOS', '11', '0', None, None, ), OSParser( 'CFNetwork/8.* Darwin/17\\.2\\.\\d+', 'iOS', '11', '1', None, None, ), OSParser( 'CFNetwork/8.* Darwin/17\\.3\\.\\d+', 'iOS', '11', '2', None, None, ), OSParser( 'CFNetwork/8.* Darwin/(17)\\.\\d+', 'iOS', '11', None, None, None, ), OSParser( 'CFNetwork/.* Darwin/', 'iOS', None, None, None, None, ), OSParser( '\\b(iOS[ /]|iOS; |iPhone(?:/| v|[ _]OS[/,]|; | OS : |\\d,\\d/|\\d,\\d; )|iPad/)(\\d{1,2})[_\\.](\\d{1,2})(?:[_\\.](\\d+))?', 'iOS', None, None, None, None, ), OSParser( '\\((iOS);', None, None, None, None, None, ), OSParser( 'Outlook-(iOS)/\\d+\\.\\d+\\.prod\\.iphone', None, None, None, None, None, ), OSParser( '(tvOS)/(\\d+).(\\d+)', 'tvOS', None, None, None, None, ), OSParser( '(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'Chrome OS', None, None, None, None, ), OSParser( '([Dd]ebian)', 'Debian', None, None, None, None, ), OSParser( '(Linux Mint)(?:/(\\d+))?', None, None, None, None, None, ), OSParser( '(Mandriva)(?: Linux)?/(?:[\\d.-]+m[a-z]{2}(\\d+).(\\d))?', None, None, None, None, None, ), OSParser( '(Symbian[Oo][Ss])[/ ](\\d+)\\.(\\d+)', 'Symbian OS', None, None, None, None, ), OSParser( '(Symbian/3).+NokiaBrowser/7\\.3', 'Symbian^3 Anna', None, None, None, None, ), OSParser( '(Symbian/3).+NokiaBrowser/7\\.4', 'Symbian^3 Belle', None, None, None, None, ), OSParser( '(Symbian/3)', 'Symbian^3', None, None, None, None, ), OSParser( '\\b(Series 60|SymbOS|S60Version|S60V\\d|S60\\b)', 'Symbian OS', None, None, None, None, ), OSParser( '(MeeGo)', None, None, None, None, None, ), OSParser( 'Symbian [Oo][Ss]', 'Symbian OS', None, None, None, None, ), OSParser( 'Series40;', 'Nokia Series 40', None, None, None, None, ), OSParser( 'Series30Plus;', 'Nokia Series 30 Plus', None, None, None, None, ), OSParser( '(BB10);.+Version/(\\d+)\\.(\\d+)\\.(\\d+)', 'BlackBerry OS', None, None, None, None, ), OSParser( '(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'BlackBerry OS', None, None, None, None, ), OSParser( '(Black[Bb]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'BlackBerry OS', None, None, None, None, ), OSParser( '(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)', 'BlackBerry Tablet OS', None, None, None, None, ), OSParser( '(Play[Bb]ook)', 'BlackBerry Tablet OS', None, None, None, None, ), OSParser( '(Black[Bb]erry)', 'BlackBerry OS', None, None, None, None, ), OSParser( '\\((?:Mobile|Tablet);.+Gecko/18.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '0', '1', None, ), OSParser( '\\((?:Mobile|Tablet);.+Gecko/18.1 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '1', None, None, ), OSParser( '\\((?:Mobile|Tablet);.+Gecko/26.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '2', None, None, ), OSParser( '\\((?:Mobile|Tablet);.+Gecko/28.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '3', None, None, ), OSParser( '\\((?:Mobile|Tablet);.+Gecko/30.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '4', None, None, ), OSParser( '\\((?:Mobile|Tablet);.+Gecko/32.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '2', '0', None, None, ), OSParser( '\\((?:Mobile|Tablet);.+Gecko/34.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '2', '1', None, None, ), OSParser( '\\((?:Mobile|Tablet);.+Firefox/\\d+\\.\\d+', 'Firefox OS', None, None, None, None, ), OSParser( '(BREW)[ /](\\d+)\\.(\\d+)\\.(\\d+)', None, None, None, None, None, ), OSParser( '(BREW);', None, None, None, None, None, ), OSParser( '(Brew MP|BMP)[ /](\\d+)\\.(\\d+)\\.(\\d+)', 'Brew MP', None, None, None, None, ), OSParser( 'BMP;', 'Brew MP', None, None, None, None, ), OSParser( '(GoogleTV)(?: (\\d+)\\.(\\d+)(?:\\.(\\d+))?|/[\\da-z]+)', None, None, None, None, None, ), OSParser( '(WebTV)/(\\d+).(\\d+)', None, None, None, None, None, ), OSParser( '(CrKey)(?:[/](\\d+)\\.(\\d+)(?:\\.(\\d+))?)?', 'Chromecast', None, None, None, None, ), OSParser( '(hpw|web)OS/(\\d+)\\.(\\d+)(?:\\.(\\d+))?', 'webOS', None, None, None, None, ), OSParser( '(VRE);', None, None, None, None, None, ), OSParser( '(Fedora|Red Hat|PCLinuxOS|Puppy|Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Slackware|(?:Free|Open|Net|\\b)BSD)[/ ](\\d+)\\.(\\d+)(?:\\.(\\d+)(?:\\.(\\d+))?)?', None, None, None, None, None, ), OSParser( '(Linux)[ /](\\d+)\\.(\\d+)(?:\\.(\\d+))?.*gentoo', 'Gentoo', None, None, None, None, ), OSParser( '\\((Bada);', None, None, None, None, None, ), OSParser( '(Windows|Android|WeTab|Maemo|Web0S)', None, None, None, None, None, ), OSParser( '(Ubuntu|Kubuntu|Arch Linux|CentOS|Slackware|Gentoo|openSUSE|SUSE|Red Hat|Fedora|PCLinuxOS|Mageia|(?:Free|Open|Net|\\b)BSD)', None, None, None, None, None, ), OSParser( '(Linux)(?:[ /](\\d+)\\.(\\d+)(?:\\.(\\d+))?)?', None, None, None, None, None, ), OSParser( 'SunOS', 'Solaris', None, None, None, None, ), OSParser( '^(Roku)/DVP-(\\d+)\\.(\\d+)', None, None, None, None, None, ), ]