");
}
while($left<=$right){
$index=intval(($left+$right)/2);
$realIndex=$index*3;
if($debug){
//debugEcho("[".$array[$realIndex]." ".$string." ".
// strcmp($array[$realIndex],$string)." ".
// $array[$realIndex+1]." ".$array[$realIndex+2]."]
");
}
$cmp=strcmp($array[$realIndex],$string);
if($cmp==0){
return array($array[$realIndex+1],$array[$realIndex+2]);
} else if ($cmp<0){
$left=$index+1;
} else {
$right=$index-1;
}
}
return false;
}
function stripStringAtEnd($ua,$string){
$stringlen=strlen($string);
$ualen=strlen($ua);
if($ualen>=$stringlen && substr($ua,$ualen-$stringlen)==$string){
$ua=substr($ua,0,$ualen-$stringlen);
}
return $ua;
}
function isObscureDesktop($ua){
if(strpos($ua,"Mozilla/5.0 (compatible; Konqueror/")===0|| // KDE; Version no. follows "Konqueror/"
strpos($ua," (MacBook")!==false|| // ex. MacBook3%2C1
(strpos($ua,"Opera/")===0 && strpos($ua," (Linux")!==false) ||
(preg_match("/^Opera\\/(8|9|\\d\\d+)\\.\\d+ \\(Windows NT \\d+\\.\\d/",$ua)) ||
strpos($ua,"Windows ME")!==false||
strpos($ua,"Mac_PowerPC")!==false
){
return true;
}
return false;
}
function isOldBrowser($ua){
if(strpos($ua,"Mozilla/")===0){
// Old Internet Explorer
if(preg_match("/^Mozilla\\/1\\.22 \\(compatible; MSIE 2\\.0; [^\\)]+\\)$/",$ua) ||
preg_match("/^Mozilla\\/2\\.0 \\(compatible; MSIE 3\\.0[abB12]; [^\\)]+\\)$/",$ua) ||
preg_match("/^Mozilla\\/3\\.0 \\(compatible; MSIE 4\\.0p1; [^\\)]+\\)$/",$ua) ||
preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE 4\\.0(b1|b2|1)?; [^\\)]+\\)$/",$ua) ||
preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE 5\\.(0|0b1|01|5); [^\\)]+\\)$/",$ua))
{
// May include "AOL 3.0" in extra data, ignore UAs with 'Windows CE'
if(strpos($ua,"Windows CE")===false){
return true;
}
}
// Mozilla 1, 2, or 3 with no language
if(preg_match("/^Mozilla\\/[123]\\.\\d+\\S* \\((Win95|Win98|WinNT|X11|Win16); [IU][^\\)]*\\)$/",$ua)){
return true;
}
// Mozilla 3 or 4 with language
if(preg_match("/^Mozilla\\/[34]\\.\\d+\\S* \\[\\w\\w\\] \\((Win95|Win98|WinNT|X11|Win16); [IU][^\\)]*\\)$/",$ua)){
return true;
}
// Mozilla 4 for Mac
if(preg_match("/^Mozilla\\/4\\.\\d+\\S* \\(Macintosh; [IU][^\\)]*\\)$/",$ua)){
return true;
}
}
if($ua=="Mozilla/2.0 (compatible; NetPositive; BeOS)"||
strpos($ua,"aolbrowser/1.1")===0||
strpos($ua,"IWENG/1.2.003")===0||
strpos($ua,"IBM-WebExplorer-DLL/v")===0||
strpos($ua,"Mozilla/2.0 (compatible; MS FrontPage 4.0)")===0||
strpos($ua,"NCSA Mosaic/")===0||
strpos($ua,"Mozilla/3.0 (compatible; Opera/")===0|| // Version no. follows "Opera/"
strpos($ua,"Mozilla/2.0 (Sextant v")===0|| // Version no. follows "Sextant v"
strpos($ua,"HotJava/1.1 FCS")===0||
strpos($ua,"OmniWeb/")===0||
strpos($ua,"Mozilla/2.0 (compatible; AOL 3.0")===0||
strpos($ua,"Emacs-W3/")===0||
strpos($ua,"Mozilla/2.0 (Compatible; AOL-IWENG 3.0")===0||
preg_match("/^Lynx[ \\/]2[-\\.]\\d[-\\.\\d]*\\S*\\s+/",$ua) // Lynx browser
){
return true;
}
return false;
}
// Determines whether a user-agent matches a very common user agent string
// (Internet Explorer, Firefox, Safari, Opera). Only UAs for desktop operating
// systems are checked (e.g. Windows, Linux, Macintosh).
function isVeryWellKnown($ua){
if(strpos($ua,"Mozilla/5.0 (")===0){
// Firefox on Windows or X11; BonEcho, DeerPark, and Minefield are prerelease codenames
$ua=stripStringAtEnd($ua,",gzip(gfe) (via translate.google.com)");
$ua=stripStringAtEnd($ua," (via babelfish.yahoo.com)");
if(preg_match("/^Mozilla\\/5\\.0 \\((Windows|X11); U; [^;]+; \\w+(?:-\\w+)?; rv:\\d[\\d\\.ab]+\\) Gecko\\/\\d{8,12} [^\\(]*?(Camino|BonEcho|DeerPark|Minefield|Firefox|Netscape)\\/\\d[\\d\\.ab]+/",$ua)){
return true;
}
if(preg_match("/^Mozilla\\/5\\.0 \\((Windows|X11); U; [^;]+; \\w+(?:-\\w+)?; rv:\\d[\\d\\.ab]+\\) Gecko\\/\\d{8,12} Ubuntu\\/\\d[\\d\\.ab]+.*? (Camino|BonEcho|DeerPark|Minefield|Firefox|Netscape)\\/\\d[\\d\\.ab]+/",$ua)){
return true;
}
// Firefox on Mac
if(preg_match("/^Mozilla\\/5\\.0 \\(Macintosh; U; (Intel|PPC)(?: Mac OS X[^;]*)?; \\w+(?:-\\w+)?; rv:\\d[\\d\\.]+\\) Gecko\\/\\d{8,12} [^\\(]*?(BonEcho|DeerPark|Minefield|Firefox|Netscape)\\/\\d[\\d\\.ab]+/",$ua)){
return true;
}
// Safari on Windows
if(preg_match("/^Mozilla\\/5\\.0 \\(Windows; U; Windows NT \\d+\\.\\d; \\w+(?:-\\w+)?\\) ".
"AppleWebKit\\/\\d[\\d\\.]+ \\(KHTML, like Gecko\\)(?: Version\\/\\d[\\d\\.]+)? .*?Safari\\/\\d[\\d\\.]+$/",$ua)){
// May contain Chrome/[version]
return true;
}
// Safari on Mac
if(preg_match("/^Mozilla\\/5\\.0 \\((Macintosh); U; (Intel|PPC) Mac OS X( 10(_\\d+(?:_\\d+)?))?; \\w+(?:-\\w+)?\\) ".
"AppleWebKit\\/\\d[\\d\\.]+ \\(KHTML, like Gecko\\)(?: Version\\/\\d[\\d\\.]+)? .*?Safari\\/\\d[\\d\\.]+$/",$ua)){
// May contain Chrome/[version]
return true;
}
} else if(strpos($ua,"Mozilla/4.0 (compatible; MSIE ")===0){
// IE on Windows NT
$ua=stripStringAtEnd($ua,",gzip(gfe) (via translate.google.com)");
$ua=stripStringAtEnd($ua," (via babelfish.yahoo.com)");
$matches=array();
if(preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE (5\\.5|6\\.0|7\\.0|8\\.0); Windows NT \\d+\\.\\d(\\)|; (.+?)\\))$/",$ua)){
return true;
}
// IE Quirks Mode
if(preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE (6\\.0|7\\.0|8\\.0); Windows NT \\d+\\.\\d; ([^;\\)]*; )*?Mozilla\\/4\\.0 \\(compatible; MSIE 6\\.0; Windows NT 5\\.1; SV1\\) ?(; [^\\;\\)]*)*\\)$/"
,$ua)){
return true;
}
} else if(strpos($ua,"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1")===0){
if(preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE (5\\.5|6\\.0|7\\.0|8\\.0); Windows NT \\d+\\.\\d(\\)|; [^\\)]+\\))$/",$ua)){
return true;
}
} else if(strpos($ua,"Opera/")===0){
// Opera on Windows NT
$ua=stripStringAtEnd($ua,",gzip(gfe) (via translate.google.com)");
$ua=stripStringAtEnd($ua," (via babelfish.yahoo.com)");
if(preg_match("/^Opera\\/(8|9|\\d\\d+)\\.\\d+ \\(Windows NT \\d+\\.\\d; U; \\w+(?:-\\w+)?\\)( Presto\\/\\d[\\d\\.]+)?/",$ua)){
return true;
}
// Opera on Mac
if(preg_match("/^Opera\\/(8|9|\\d\\d+)\\.\\d+ \\(Macintosh; (Intel|PPC) Mac OS X; U; \\w+(?:-\\w+)?\\)( Presto\\/\\d[\\d\\.]+)?/",$ua)){
return true;
}
}
return false;
}
function isConsole($ua){
return getBrowserType($ua)==3;
}
/*
Returns the type of user agent represented in a user agent string:
0 - Banned (malicious bots)
1 - Bot (beneficial bots)
2 - Handheld mobile device
3 - Game console (relatively high resolution, but no keyboard; e.g. PLAYSTATION 3; Wii)
4 - Desktop browser (Internet Explorer, Firefox, Opera, etc.)
5 - Unknown (can be treated like bots)
*/
function getBrowserType($ua){
$ua=stripStringAtEnd($ua,",gzip(gfe) (via translate.google.com)");
$ua=stripStringAtEnd($ua," (via babelfish.yahoo.com)");
// Check for common browsers
if(isVeryWellKnown($ua))
return 4;
// Check for banned browsers
if(isBanned($ua))
return 0;
if(preg_match("/Nintendo Wii|Wii Shop Channel|PLAYSTATION 3/",$ua))
// Game console
return 3;
// Check for bots
if(isBot($ua))
return 1;
// Check for other kinds of desktop browsers
if(isWellKnown($ua) || isOldBrowser($ua) || isObscureDesktop($ua))
return 4;
// Check for mobile browsers
if(isMobile($ua))
return 2;
// Unknown browser
return 5;
}
function isWellKnown($ua){
$op9=strpos($ua,"Opera/9");
if($op9!==false && $op9>0)
return false;
if(strpos($ua,"HTC")===0)
return false;
if(strpos($ua,"; Windows NT ")!==false||
strpos($ua,"Mozilla/4.0 (compatible; MSIE 7.0")!==false||
strpos($ua,"Mozilla/4.0 (compatible; MSIE 8.0")!==false||
strpos($ua,"; Windows 95")!==false||
strpos($ua,"MSIE 999.1")!==false|| // used in stealthing
strpos($ua,"Windows ME")!==false||
strpos($ua,"(X11; U; ")!==false||
strpos($ua," Firefox/")!==false||
strpos($ua,"Intel Mac OS X")!==false||
strpos($ua,"; Linux i686;")!==false||
strpos($ua,"; Linux x86_64;")!==false||
strpos($ua,"PPC Mac OS X")!==false
)
return true;
if(strpos($ua,"Windows 98")!==false &&
strpos($ua,"PalmSource")===false) // Palm browsers use Windows 98 moniker
return true;
return false;
}
// Determines whether a user agent represents a bot
function isBot($ua){
global $bots;
// Treat empty and too-short UAs as bots
if(strlen($ua)<=2)return true;
// Bots are not mobile browsers
for($i=0;$i100 ? 102400 : $cache[1]*1024;
}
return 5*1024;
} else if(preg_match("/^Mozilla\\/(5\\.0|4\\.08)\\s+\\(([\\w\\+]+);FOMA;([^\\)]+)\\)/",$ua,$matches)){
// FOMA
$tokens=explode(";",$matches[1]);
if($tokens[0] && preg_match("/^c(\\d+)$/",$tokens[0],$cache)){
// cache size
return $cache[1]*1>100 ? 102400 : $cache[1]*1024;
}
return 5*1024;
} else if(IsSoftBank($ua)!=""){
if(preg_match("/^J-PHONE\\/(\\d+)/",$ua,$matches)){
if($matches[1]=="3")return 6*1024;
if($matches[1]=="4")return 12*1024;
if($matches[1]=="5")return 40*1024;
return 6*1024;
}
return 9*1024;
} else if(preg_match("/^(?:DOCOMO|DoCoMo|portalmmm)\\/2\\.0\\s+([\\w\\+]+)\\(([^\\)]+)\\)/",$ua,$matches)){
// Docomo phone 2.0
$model=$matches[1];
$tokens=explode(";",$matches[2]);
$cache=array();
if($tokens[0] && preg_match("/^c(\\d+)$/",$tokens[0],$cache)){
// cache size
$maxsize=$cache[1];
if($maxsize>30){
$maxsize=30;
}
return $maxsize*1024;
}
return 10*1024;
}
// For other browsers, guess maximum from screen size
$size=getScreenSize($ua);
if($size[0]>=800 && $size[1]>=600){
// high resolution
return 200000;
}
// unknown screen size
if($size[0]==-1 || $size[1]==-1){
return 4096;
}
$suggestedMaxSize=$size[0]; // width
$suggestedMaxSize*=$size[1]; // height
$suggestedMaxSize*=4;
$suggestedMaxSize/=27;
$suggestedMaxSize=floor($suggestedMaxSize);
if($suggestedMaxSize>20000){
$suggestedMaxSize=20000;
}
if($suggestedMaxSize<4096){
$suggestedMaxSize=4096;
}
return $suggestedMaxSize;
}
// Guesses the screen size given information in
// the user request
function getScreenSizeThis(){
// Try parsing the HTTP headers first
$display=$_SERVER['HTTP_X_JPHONE_DISPLAY'];
if(isset($display)){
$matches=array();
if(preg_match("/^\\s*(\\d+)\\*(\\d+)/",$display,$matches)){
return array($matches[1]*1,$matches[2]*1);
}
}
$display=$_SERVER['HTTP_X_EMULATOR_DISPLAY'];
if(isset($display)){
$matches=array();
if(preg_match("/^\\s*(\\d+)\\*(\\d+)/",$display,$matches)){
return array($matches[1]*1,$matches[2]*1);
}
}
$display=$_SERVER['HTTP_X_UP_DEVCAP_SCREENPIXELS'];
if(isset($display)){
$matches=array();
if(preg_match("/^\\s*(\\d+)\\s*[,x]\\s*(\\d+)/",$display,$matches)){
return array($matches[1]*1,$matches[2]*1);
}
}
$display=$_SERVER['HTTP_UA_PIXELS'];
if(isset($display)){
$matches=array();
if(preg_match("/^\\s*(\\d+)\\s*[,x]\\s*(\\d+)/",$display,$matches)){
return array($matches[1]*1,$matches[2]*1);
}
}
$display=$_SERVER['HTTP_X_SKYFIRE_SCREEN'];
if(isset($display)){
$matches=array();
// fullscreenWidth,fullscreenHeight,canvasWidth,canvasHeight
if(preg_match("/^\\s*(\\d+),(\\d+),(\\d+),(\\d+)/",$display,$matches)){
return array($matches[3]*1,$matches[4]*1);
}
}
$display=$_SERVER['HTTP_X_OS_PREFS'];
if(isset($display)){
$matches=array();
$ret=array(128,128);
if(preg_match("/fw\\:(\\d+)/",$display,$matches)){
$ret[0]=$matches[1]*1;
}
if(preg_match("/fh\\:(\\d+)/",$display,$matches)){
$ret[1]=$matches[1]*1;
}
return $ret;
}
$display=$_SERVER['HTTP_X_S_DISPLAY_INFO'];
if(isset($display)){
$matches=array();
// canvas size/character size/TB or TC
if(preg_match("/^\\s*(\\d+)\\*(\\d+)\\/(\\d+)\\*(\\d+)\\/(TB|TC)/",$display,$matches)){
return array($matches[1]*1,$matches[2]*1);
}
}
// Try deriving the screen size from the user agent
return getScreenSize(getRealUserAgent());
}
function supportsImagesThis(){
// Try parsing the HTTP headers first
$display=$_SERVER['HTTP_X_S_DISPLAY_INFO'];
if(isset($display)){
$matches=array();
// canvas size/character size/TB or TC
if(preg_match("/^\\s*(\\d+)\\*(\\d+)\\/(\\d+)\\*(\\d+)\\/(TB|TC)/",$display,$matches)){
return $matches[5]=="TB";
}
}
return supportsImages(getRealUserAgent());
}
function supportsImages($ua){
// All very well known UAs support images
if(isVeryWellKnown($ua))
return true;
// Lynx is text-based
if(preg_match("/^Lynx[ \\/]2[-\\.]\\d[-\\.\\d]*\\S*\\s+/",$ua)){
return false;
}
if(preg_match("/^(DOCOMO|DoCoMo)\\/1\\.0\\//",$ua)){
// Docomo phone 1.0
$tokens=explode("/",$ua);
// If fifth token is TC (as opposed to TB or absent), images are disabled
if($tokens[4]=="TC")return false;
} else if(preg_match("/^Mozilla\\/4\\.08\\s+\\(([\\w\\+]+);FOMA;([^\\)]+)\\)/",$ua,$matches)){
// FOMA
$model=$matches[0];
$tokens=explode(";",$matches[1]);
if($tokens[1]=="TC"){
return false;
}
} else if(preg_match("/^(?:DOCOMO|DoCoMo|portalmmm)\\/2\\.0\\s+([\\w\\+]+)\\(([^\\)]+)\\)/",$ua,$matches)){
// Docomo phone 2.0
$model=$matches[1];
$tokens=explode(";",$matches[2]);
if($tokens[2]=="TC"){
// images are disabled
}
}
return true;
}
// Guesses the screen size given a user agent string
function getScreenSize($ua,$debug/*def*/=false/*enddef*/){
global $docomo;
global $dimensions;
global $dimensionsExact;
global $MobilePhone;
global $nonwireless;
global $kddi;
global $softbank;
global $openwave;
global $cldc;
global $devices;
// well-known browsers
if(isWellKnown($ua) || $ua=="")
return array(-1,-1);
if($ua=="UNTRUSTED/1.0") // J2ME application
return array(200,200);
if(preg_match("/^MobileSafari\\//",$ua)) // iPhone/iPod helper UA
return array(320,396);
if(preg_match("/^UP\\.Link\\/[\\d\\.]+$/",$ua)) // Unknown
return array(200,200);
$ua=clipDevice($ua);
$matches=array();
$fallback=array(-1,-1);
if(strpos($ua,"Opera Mini")!==false ||
strpos($ua,"(compatible; OpenWeb ")!==false ||
$ua=="Skyfire Downloader"){
// Opera Mini/Skyfire hides user agent info
return array(200,200);
} else if(preg_match("/^PDXGW\\/[0-9\\.]+\s*\\(([^\\)]+)\\)/",$ua,$matches)){
// PDXGW/1.0 (TX=8;TY=7;GX=96;GY=84;C=C256;G=BF;GI=2)
// C=CF means C=65536; C=G2 means C=C2
$tokens=explode(";",$matches[1]);
$ret=array(200,200);
for($i=0;$i");
if(preg_match("/^(.*?)([ \\/\\*]|$)/",$ua,$matches)){
//if($debug)debugEcho("common: ".$matches[1]."
");
$ret=searchWidthHeightExact($cldc,$matches[1],$debug);
if($ret!==false)return $ret;
$ret=searchWidthHeightExact($openwave,$matches[1]);
if($ret!==false)return $ret;
$ret=searchWidthHeightExact($devices,$matches[1]);
if($ret!==false)return $ret;
}
} else if(preg_match("/^Mozilla\\/4\\.0 \\(MobilePhone ([A-Z]+-?\\d+)\\//",$ua,$matches)){
$model=$matches[1];
$ret=searchWidthHeightExact($MobilePhone,$model);
if($ret!==false)
return $ret;
} else if(
preg_match("/^UP\\.Browser\\/(?:[\\d\\._A-Za-z]+)\\s+(KDDI-\\w+)/",$ua,$matches) || // HDML
preg_match("/^Mozilla\\/4\\.0 \\(compatible; MSIE 6\\.0; (KDDI-\\w+)/",$ua,$matches)
){
$model=$matches[1];
$ret=searchWidthHeightExact($openwave,$model);
if($ret===false)
return array(-1,-1);
return $ret;
} else if(preg_match("/^([^\\/\\s\\*]+)(?:\\*[^\\/\\s]*)?(?:\\/\\S*)? UP\\.Browser\\/(\\d+[\\d\\._A-Za-z]+) (\\(GUI\\) )?MMP\\/\\d+\\.\\d+/",$ua,$matches)){
$model=$matches[1];
$ret=searchWidthHeightExact($openwave,$model);
if($ret!==false)
return $ret;
} else if(preg_match("/^Mozilla\\/5\\.0 \\(SymbianOS\\/[^;]+; U; Series\\d+\\/\\S+ ([^\\/\\s]+)\\/(\\S*) Profile\\/MIDP-\\d+\\.\\d+ Configuration\\/CLDC-\\d+\\.\\d+[;\\s]*\\) AppleWebKit\\//",$ua,$matches)){
// CLDC Safari
$model=$matches[1];
$ret=searchWidthHeightExact($cldc,$model);
if($ret!==false)
return $ret;
} else if(preg_match("/^([^\\/\\s]+)(?:\\/(\\S*))?.*? [Pp]rofile\\/MIDP-\\d+\\.\\d+ [Cc]onfiguration\\/CLDC-\\d+\\.\\d+(?= |$)/",$ua,$matches) &&
strpos($ua,"Mozilla/")==false){
// CLDC
$model=$matches[1];
$ret=searchWidthHeightExact($cldc,$model);
if($ret!==false)
return $ret;
} else if(preg_match("/^([^\\/\\s]+)(?:\\/(\\S*))?.*? MIDP-\\d+\\.\\d+\\/CLDC-\\d+\\.\\d+(?= |$)/",$ua,$matches) &&
strpos($ua,"Mozilla/")==false){
// CLDC
$model=$matches[1];
$ret=searchWidthHeightExact($cldc,$model);
if($ret!==false)
return $ret;
} else if(
preg_match("/^Mozilla\\/4\\.0\\s+\\(jig browser[^;]+; ([\\w\\+]+); \\d+\\)/",$ua,$matches) ||
preg_match("/^Mozilla\\/4\\.0\\s+\\(jig browser[^;]+; [\\d\\.]+; ([\\w\\+]+)\\)/",$ua,$matches)){
// Docomo jig browser
$model=$matches[1];
for($i=0;$i100 && $height>100){
return array($width,$height);
}
}
for($i=0;$i