/* ******************************************* 
// Copyright 2010, Anthony Hand 
// 
// File version date: November 28, 2010 
// 
// LICENSE INFORMATION 
// Licensed under the Apache License, Version 2.0 (the "License");  
// you may not use this file except in compliance with the License.  
// You may obtain a copy of the License at  
//        http://www.apache.org/licenses/LICENSE-2.0  
// Unless required by applicable law or agreed to in writing,  
// software distributed under the License is distributed on an  
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,  
// either express or implied. See the License for the specific  
// language governing permissions and limitations under the License.  
// 
// 
// ABOUT THIS PROJECT 
//   Project Owner: Anthony Hand 
//   Email: anthony.hand@gmail.com 
//   Web Site: http://www.mobileesp.com 
//   Source Files: http://code.google.com/p/mobileesp/ 
//    
//   Versions of this code are available for: 
//      PHP, JavaScript, Java, ASP.NET (C#), and Ruby 
// 
// 
// WARNING:  
//   These JavaScript-based device detection features may ONLY work  
//   for the newest generation of smartphones, such as the iPhone,  
//   Android and Palm WebOS devices. 
//   These device detection features may NOT work for older smartphones  
//   which had poor support for JavaScript, including  
//   older BlackBerry, PalmOS, and Windows Mobile devices.  
//   Additionally, because JavaScript support is extremely poor among  
//   'feature phones', these features may not work at all on such devices. 
//   For better results, consider using a server-based version of this code,  
//   such as Java, APS.NET, PHP, or Ruby. 
// 
// ******************************************* 
*/ 
 
//Optional: Store values for quickly accessing same info multiple times. 
//Stores whether the device is an iPhone or iPod Touch. 
var isIphone = false;  
//Stores whether is the iPhone tier of devices. 
var isTierIphone = false;  
//Stores whether the device can probably support Rich CSS, but JavaScript support is not assumed. (e.g., newer BlackBerry, Windows Mobile) 
var isTierRichCss = false;  
//Stores whether it is another mobile device, which cannot be assumed to support CSS or JS (eg, older BlackBerry, RAZR) 
var isTierGenericMobile = false;  
 
//Initialize some initial string variables we'll look for later. 
var engineWebKit = "webkit"; 
var deviceIphone = "iphone"; 
var deviceIpod = "ipod"; 
var deviceIpad = "ipad"; 
var deviceMacPpc = "macintosh"; //Used for disambiguation 
 
var deviceAndroid = "android"; 
var deviceGoogleTV = "googletv"; 
 
var deviceNuvifone = "nuvifone"; //Garmin Nuvifone 
 
var deviceSymbian = "symbian"; 
var deviceS60 = "series60"; 
var deviceS70 = "series70"; 
var deviceS80 = "series80"; 
var deviceS90 = "series90"; 
 
var deviceWinPhone7 = "windows phone os 7";  
var deviceWinMob = "windows ce"; 
var deviceWindows = "windows"; 
var deviceIeMob = "iemobile"; 
var devicePpc = "ppc"; //Stands for PocketPC 
var enginePie = "wm5 pie";  //An old Windows Mobile 
 
var deviceBB = "blackberry"; 
var vndRIM = "vnd.rim"; //Detectable when BB devices emulate IE or Firefox 
var deviceBBStorm = "blackberry95"; //Storm 1 and 2 
var deviceBBBold = "blackberry97"; //Bold 
var deviceBBTour = "blackberry96"; //Tour 
var deviceBBCurve = "blackberry89"; //Curve 2 
var deviceBBTorch = "blackberry 98"; //Torch 
 
var devicePalm = "palm"; 
var deviceWebOS = "webos"; //For Palm's new WebOS devices 
var engineBlazer = "blazer"; //Old Palm browser 
var engineXiino = "xiino"; 
 
var deviceKindle = "kindle"; //Amazon Kindle, eInk one. 
 
//Initialize variables for mobile-specific content. 
var vndwap = "vnd.wap"; 
var wml = "wml"; 
 
//Initialize variables for random devices and mobile browsers. 
//Some of these may not support JavaScript 
var deviceBrew = "brew"; 
var deviceDanger = "danger"; 
var deviceHiptop = "hiptop"; 
var devicePlaystation = "playstation"; 
var deviceNintendoDs = "nitro"; 
var deviceNintendo = "nintendo"; 
var deviceWii = "wii"; 
var deviceXbox = "xbox"; 
var deviceArchos = "archos"; 
 
var engineOpera = "opera"; //Popular browser 
var engineNetfront = "netfront"; //Common embedded OS browser 
var engineUpBrowser = "up.browser"; //common on some phones 
var engineOpenWeb = "openweb"; //Transcoding by OpenWave server 
var deviceMidp = "midp"; //a mobile Java technology 
var uplink = "up.link"; 
var engineTelecaQ = 'teleca q'; //a modern feature phone browser 
 
var devicePda = "pda"; 
var mini = "mini";  //Some mobile browsers put 'mini' in their names. 
var mobile = "mobile"; //Some mobile browsers put 'mobile' in their user agent strings. 
var mobi = "mobi"; //Some mobile browsers put 'mobi' in their user agent strings. 
 
//Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets. 
var maemo = "maemo"; 
var maemoTablet = "tablet"; 
var linux = "linux"; 
var qtembedded = "qt embedded"; //for Sony Mylo and others 
var mylocom2 = "com2"; //for Sony Mylo also 
 
//In some UserAgents, the only clue is the manufacturer. 
var manuSonyEricsson = "sonyericsson"; 
var manuericsson = "ericsson"; 
var manuSamsung1 = "sec-sgh"; 
var manuSony = "sony"; 
var manuHtc = "htc"; //Popular Android and WinMo manufacturer 
 
//In some UserAgents, the only clue is the operator. 
var svcDocomo = "docomo"; 
var svcKddi = "kddi"; 
var svcVodafone = "vodafone"; 
 
//Disambiguation strings. 
var disUpdate = "update"; //pda vs. update 
 
 
 
//Initialize our user agent string. 
var uagent = navigator.userAgent.toLowerCase(); 
 
 
//************************** 
// Detects if the current device is an iPhone. 
function DetectIphone() 
{ 
   if (uagent.search(deviceIphone) > -1) 
   { 
      //The iPad and iPod Touch say they're an iPhone! So let's disambiguate. 
      if (DetectIpad() || 
          DetectIpod()) 
         return false; 
      else  
         return true; 
   } 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current device is an iPod Touch. 
function DetectIpod() 
{ 
   if (uagent.search(deviceIpod) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current device is an iPad tablet. 
function DetectIpad() 
{ 
   if (uagent.search(deviceIpad) > -1  && DetectWebkit()) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current device is an iPhone or iPod Touch. 
function DetectIphoneOrIpod() 
{ 
   //We repeat the searches here because some iPods  
   //  may report themselves as an iPhone, which is ok. 
   if (uagent.search(deviceIphone) > -1 || 
       uagent.search(deviceIpod) > -1) 
       return true; 
    else 
       return false; 
} 
 
//************************** 
// Detects if the current device is an Android OS-based device. 
function DetectAndroid() 
{ 
   if (uagent.search(deviceAndroid) > -1) 
      return true; 
   else 
      return false; 
} 
 
 
//************************** 
// Detects if the current device is an Android OS-based device and 
//   the browser is based on WebKit. 
function DetectAndroidWebKit() 
{ 
   if (DetectAndroid() && DetectWebkit()) 
      return true; 
   else 
      return false; 
} 
 
 
//************************** 
// Detects if the current device is a GoogleTV. 
function DetectGoogleTV() 
{ 
   if (uagent.search(deviceGoogleTV) > -1) 
      return true; 
   else 
      return false; 
} 
 
 
//************************** 
// Detects if the current browser is based on WebKit. 
function DetectWebkit() 
{ 
   if (uagent.search(engineWebKit) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is the Nokia S60 Open Source Browser. 
function DetectS60OssBrowser() 
{ 
   if (DetectWebkit()) 
   { 
     if ((uagent.search(deviceS60) > -1 ||  
          uagent.search(deviceSymbian) > -1)) 
        return true; 
     else 
        return false; 
   } 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current device is any Symbian OS-based device, 
//   including older S60, Series 70, Series 80, Series 90, and UIQ,  
//   or other browsers running on these devices. 
function DetectSymbianOS() 
{ 
   if (uagent.search(deviceSymbian) > -1 || 
       uagent.search(deviceS60) > -1 || 
       uagent.search(deviceS70) > -1 || 
       uagent.search(deviceS80) > -1 || 
       uagent.search(deviceS90) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a  
// Windows Phone 7 device. 
function DetectWindowsPhone7() 
{ 
   if (uagent.search(deviceWinPhone7) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a Windows Mobile device. 
// Excludes Windows Phone 7 devices.  
// Focuses on Windows Mobile 6.xx and earlier. 
function DetectWindowsMobile() 
{ 
   //Exclude new Windows Phone 7. 
   if (DetectWindowsPhone7()) 
      return false; 
   //Most devices use 'Windows CE', but some report 'iemobile'  
   //  and some older ones report as 'PIE' for Pocket IE.  
   if (uagent.search(deviceWinMob) > -1 || 
       uagent.search(deviceIeMob) > -1 || 
       uagent.search(enginePie) > -1) 
      return true; 
   //Test for Windows Mobile PPC but not old Macintosh PowerPC. 
   if ((uagent.search(devicePpc) > -1) &&  
       !(uagent.search(deviceMacPpc) > -1)) 
      return true; 
   //Test for Windwos Mobile-based HTC devices. 
   if (uagent.search(manuHtc) > -1 && 
       uagent.search(deviceWindows) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a BlackBerry of some sort. 
function DetectBlackBerry() 
{ 
   if (uagent.search(deviceBB) > -1) 
      return true; 
   if (uagent.search(vndRIM) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a BlackBerry device AND uses a 
//    WebKit-based browser. These are signatures for the new BlackBerry OS 6. 
//    Examples: Torch 
function DetectBlackBerryWebKit() 
{ 
   if (uagent.search(deviceBB) > -1 && 
       uagent.search(engineWebKit) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a BlackBerry Touch 
//    device, such as the Storm or Torch. 
function DetectBlackBerryTouch() 
{ 
   if ((uagent.search(deviceBBStorm) > -1) || 
    (uagent.search(deviceBBTorch) > -1)) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a BlackBerry OS 5 device AND 
//    has a more capable recent browser.  
//    Examples, Storm, Bold, Tour, Curve2 
//    Excludes the new BlackBerry OS 6 browser!! 
function DetectBlackBerryHigh() 
{ 
   //Disambiguate for BlackBerry OS 6 (WebKit) browser 
   if (DetectBlackBerryWebKit()) 
      return false; 
   if (DetectBlackBerry()) 
   { 
     if (DetectBlackBerryTouch() || 
        uagent.search(deviceBBBold) > -1 ||  
        uagent.search(deviceBBTour) > -1 ||  
        uagent.search(deviceBBCurve) > -1) 
        return true; 
     else 
        return false; 
   } 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a BlackBerry device AND 
//    has an older, less capable browser.  
//    Examples: Pearl, 8800, Curve1. 
function DetectBlackBerryLow() 
{ 
   if (DetectBlackBerry()) 
   { 
     //Assume that if it's not in the High tier, then it's Low. 
     if (DetectBlackBerryHigh()) 
        return false; 
     else 
        return true; 
   } 
   else 
      return false; 
} 
 
 
//************************** 
// Detects if the current browser is on a PalmOS device. 
function DetectPalmOS() 
{ 
   //Most devices nowadays report as 'Palm',  
   //  but some older ones reported as Blazer or Xiino. 
   if (uagent.search(devicePalm) > -1 || 
       uagent.search(engineBlazer) > -1 || 
       uagent.search(engineXiino) > -1) 
   { 
     //Make sure it's not WebOS first 
     if (DetectPalmWebOS()) 
        return false; 
     else 
        return true; 
   } 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is on a Palm device 
//   running the new WebOS. 
function DetectPalmWebOS() 
{ 
   if (uagent.search(deviceWebOS) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a 
//   Garmin Nuvifone. 
function DetectGarminNuvifone() 
{ 
   if (uagent.search(deviceNuvifone) > -1) 
      return true; 
   else 
      return false; 
} 
 
 
//************************** 
// Check to see whether the device is a 'smartphone'. 
//   You might wish to send smartphones to a more capable web page 
//   than a dumbed down WAP page.  
function DetectSmartphone() 
{ 
   if (DetectIphoneOrIpod()) 
      return true; 
   if (DetectS60OssBrowser()) 
      return true; 
   if (DetectSymbianOS()) 
      return true; 
   if (DetectWindowsMobile()) 
      return true; 
   if (DetectWindowsPhone7()) 
      return true; 
   if (DetectAndroid()) 
      return true; 
   if (DetectBlackBerry()) 
      return true; 
   if (DetectPalmWebOS()) 
      return true; 
   if (DetectPalmOS()) 
      return true; 
   if (DetectGarminNuvifone()) 
      return true; 
 
   //Otherwise, return false. 
   return false; 
}; 
 
//************************** 
// Detects if the current device is an Archos media player/Internet tablet. 
function DetectArchos() 
{ 
   if (uagent.search(deviceArchos) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects whether the device is a Brew-powered device. 
function DetectBrewDevice() 
{ 
   if (uagent.search(deviceBrew) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects the Danger Hiptop device. 
function DetectDangerHiptop() 
{ 
   if (uagent.search(deviceDanger) > -1 || 
       uagent.search(deviceHiptop) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current device is on one of  
// the Maemo-based Nokia Internet Tablets. 
function DetectMaemoTablet() 
{ 
   if (uagent.search(maemo) > -1) 
      return true; 
   //Must be Linux + Tablet, or else it could be something else. 
   if (uagent.search(maemoTablet) > -1 && 
       uagent.search(linux) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is a Sony Mylo device. 
function DetectSonyMylo() 
{ 
   if (uagent.search(manuSony) > -1) 
   { 
     if (uagent.search(qtembedded) > -1 || 
         uagent.search(mylocom2) > -1) 
        return true; 
     else 
        return false; 
   } 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current browser is Opera Mobile or Mini. 
function DetectOperaMobile() 
{ 
   if (uagent.search(engineOpera) > -1) 
   { 
     if (uagent.search(mini) > -1 || 
         uagent.search(mobi) > -1) 
        return true; 
     else 
        return false; 
   } 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current device is a Sony Playstation. 
function DetectSonyPlaystation() 
{ 
   if (uagent.search(devicePlaystation) > -1) 
      return true; 
   else 
      return false; 
}; 
 
//************************** 
// Detects if the current device is a Nintendo game device. 
function DetectNintendo() 
{ 
   if (uagent.search(deviceNintendo) > -1   ||  
        uagent.search(deviceWii) > -1 || 
        uagent.search(deviceNintendoDs) > -1) 
      return true; 
   else 
      return false; 
}; 
 
//************************** 
// Detects if the current device is a Microsoft Xbox. 
function DetectXbox() 
{ 
   if (uagent.search(deviceXbox) > -1) 
      return true; 
   else 
      return false; 
}; 
 
//************************** 
// Detects if the current device is an Internet-capable game console. 
function DetectGameConsole() 
{ 
   if (DetectSonyPlaystation()) 
      return true; 
   if (DetectNintendo()) 
      return true; 
   if (DetectXbox()) 
      return true; 
   else 
      return false; 
}; 
 
//************************** 
// Detects if the current device is a Kindle. 
function DetectKindle() 
{ 
   if (uagent.search(deviceKindle) > -1) 
      return true; 
   else 
      return false; 
} 
 
//************************** 
// Detects if the current device is a mobile device. 
//  This method catches most of the popular modern devices. 
//  Excludes Apple iPads. 
function DetectMobileQuick() 
{ 
   //Let's say no if it's an iPad, which contains 'mobile' in its user agent. 
   if (DetectIpad()) 
      return false; 
 
   //Most mobile browsing is done on smartphones 
   if (DetectSmartphone()) 
      return true; 
 
   if (uagent.search(deviceMidp) > -1 || 
        DetectBrewDevice()) 
      return true; 
 
   if (DetectOperaMobile()) 
      return true; 
 
   if (uagent.search(engineNetfront) > -1) 
      return true; 
   if (uagent.search(engineUpBrowser) > -1) 
      return true; 
   if (uagent.search(engineOpenWeb) > -1) 
      return true; 
 
   if (DetectDangerHiptop()) 
      return true; 
       
   if (DetectMaemoTablet()) 
      return true; 
   if (DetectArchos()) 
      return true; 
 
   if ((uagent.search(devicePda) > -1) && 
        (uagent.search(disUpdate) < 0)) //no index found 
      return true; 
   if (uagent.search(mobile) > -1) 
      return true; 
 
   if (DetectKindle()) 
      return true; 
       
   return false; 
}; 
 
 
//************************** 
// Detects in a more comprehensive way if the current device is a mobile device. 
function DetectMobileLong() 
{ 
   if (DetectMobileQuick()) 
      return true; 
   if (DetectGameConsole()) 
      return true; 
   if (DetectSonyMylo()) 
      return true; 
 
   //Detect for certain very old devices with stupid useragent strings. 
   if (uagent.search(manuSamsung1) > -1 || 
        uagent.search(manuSonyEricsson) > -1 ||  
        uagent.search(manuericsson) > -1) 
      return true; 
 
   if (uagent.search(svcDocomo) > -1) 
      return true; 
   if (uagent.search(svcKddi) > -1) 
      return true; 
   if (uagent.search(svcVodafone) > -1) 
      return true; 
 
 
   return false; 
}; 
 
 
//***************************** 
// For Mobile Web Site Design 
//***************************** 
 
//************************** 
// The quick way to detect for a tier of devices. 
//   This method detects for devices which can  
//   display iPhone-optimized web content. 
//   Includes iPhone, iPod Touch, Android, WebOS, etc. 
function DetectTierIphone() 
{ 
   if (DetectIphoneOrIpod()) 
      return true; 
   if (DetectAndroid()) 
      return true; 
   if (DetectAndroidWebKit()) 
      return true; 
   if (DetectWindowsPhone7()) 
      return true; 
   if (DetectBlackBerryWebKit()) 
      return true; 
   if (DetectPalmWebOS()) 
      return true; 
   if (DetectGarminNuvifone()) 
      return true; 
   if (DetectMaemoTablet()) 
      return true; 
   else 
      return false; 
}; 
 
//************************** 
// The quick way to detect for a tier of devices. 
//   This method detects for devices which are likely to be  
//   capable of viewing CSS content optimized for the iPhone,  
//   but may not necessarily support JavaScript. 
//   Excludes all iPhone Tier devices. 
function DetectTierRichCss() 
{ 
    if (DetectMobileQuick()) 
    { 
       if (DetectTierIphone()) 
          return false; 
           
       //The following devices are explicitly ok. 
       if (DetectWebkit()) 
          return true; 
       if (DetectS60OssBrowser()) 
          return true; 
 
       //Note: 'High' BlackBerry devices ONLY 
       if (DetectBlackBerryHigh()) 
          return true; 
 
       if (DetectWindowsMobile()) 
          return true; 
           
       if (uagent.search(engineTelecaQ) > -1) 
          return true; 
           
       else 
          return false; 
    } 
    else 
      return false; 
}; 
 
//************************** 
// The quick way to detect for a tier of devices. 
//   This method detects for all other types of phones, 
//   but excludes the iPhone and RichCSS Tier devices. 
// NOTE: This method probably won't work due to poor 
//  support for JavaScript among other devices.  
function DetectTierOtherPhones() 
{ 
    if (DetectMobileLong()) 
    { 
       //Exclude devices in the other 2 categories 
       if (DetectTierIphone()) 
          return false; 
       if (DetectTierRichCss()) 
          return false; 
 
       //Otherwise, it's a YES 
       else 
          return true; 
    } 
    else 
      return false; 
}; 


