3v4l.org

run code in 300+ PHP versions simultaneously
<?php /** * Mobile Detect Library * ===================== * * Motto: "Every business should have a mobile detection script to detect mobile readers" * * Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets). * It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment. * * @author Current authors: Serban Ghita <serbanghita@gmail.com>, Nick Ilyin <nick.ilyin@gmail.com> * Original author: Victor Stanciu <vic.stanciu@gmail.com> * * @license Code and contributions have 'MIT License' * More details: https://github.com/serbanghita/Mobile-Detect/blob/master/LICENSE.txt * * @link Homepage: http://mobiledetect.net * GitHub Repo: https://github.com/serbanghita/Mobile-Detect * Google Code: http://code.google.com/p/php-mobile-detect/ * README: https://github.com/serbanghita/Mobile-Detect/blob/master/README.md * HOWTO: https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples * * @version 2.8.5 */ class Mobile_Detect { /** * Mobile detection type. * * @deprecated since version 2.6.9 */ const DETECTION_TYPE_MOBILE = 'mobile'; /** * Extended detection type. * * @deprecated since version 2.6.9 */ const DETECTION_TYPE_EXTENDED = 'extended'; /** * A frequently used regular expression to extract version #s. * * @deprecated since version 2.6.9 */ const VER = '([\w._\+]+)'; /** * Top-level device. */ const MOBILE_GRADE_A = 'A'; /** * Mid-level device. */ const MOBILE_GRADE_B = 'B'; /** * Low-level device. */ const MOBILE_GRADE_C = 'C'; /** * Stores the version number of the current release. */ const VERSION = '2.8.5'; /** * A type for the version() method indicating a string return value. */ const VERSION_TYPE_STRING = 'text'; /** * A type for the version() method indicating a float return value. */ const VERSION_TYPE_FLOAT = 'float'; /** * The User-Agent HTTP header is stored in here. * @var string */ protected $userAgent = null; /** * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE. * @var array */ protected $httpHeaders = array(); /** * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED. * * @deprecated since version 2.6.9 * * @var string */ protected $detectionType = self::DETECTION_TYPE_MOBILE; /** * HTTP headers that trigger the 'isMobile' detection * to be true. * * @var array */ protected static $mobileHeaders = array( 'HTTP_ACCEPT' => array('matches' => array( // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/ 'application/x-obml2d', // BlackBerry devices. 'application/vnd.rim.html', 'text/vnd.wap.wml', 'application/vnd.wap.xhtml+xml' )), 'HTTP_X_WAP_PROFILE' => null, ); /** * List of mobile devices (phones). * * @var array */ protected static $phoneDevices = array( 'iPhone' => '\biPhone\b|\biPod\b', // |\biTunes ); /** * List of tablet devices. * * @var array */ protected static $tabletDevices = array( 'iPad' => 'iPad|iPad.*Mobile' ); /** * List of mobile Operating Systems. * * @var array */ protected static $operatingSystems = array( 'AndroidOS' => 'Android', ); /** * List of mobile User Agents. * * @var array */ protected static $browsers = array( // @reference: https://developers.google.com/chrome/mobile/docs/user-agent 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?', ); /** * Utilities. * * @var array */ protected static $utilities = array( // Experimental. When a mobile device wants to switch to 'Desktop Mode'. // http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/ // https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011 'DesktopMode' => 'WPDesktop', 'TV' => 'SonyDTV|HbbTV', // experimental 'WebKit' => '(webkit)[ /]([\w.]+)', 'Bot' => 'Googlebot|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|facebookexternalhit', 'MobileBot' => 'Googlebot-Mobile|YahooSeeker/M1A1-R2D2', // @todo: Include JXD consoles. 'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\b', 'Watch' => 'SM-V700', ); /** * All possible HTTP headers that represent the * User-Agent string. * * @var array */ protected static $uaHttpHeaders = array( // The default User-Agent string. 'HTTP_USER_AGENT', // Header can occur on devices using Opera Mini. 'HTTP_X_OPERAMINI_PHONE_UA', // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/ 'HTTP_X_DEVICE_USER_AGENT', 'HTTP_X_ORIGINAL_USER_AGENT', 'HTTP_X_SKYFIRE_PHONE', 'HTTP_X_BOLT_PHONE_UA', 'HTTP_DEVICE_STOCK_UA', 'HTTP_X_UCBROWSER_DEVICE_UA' ); /** * The individual segments that could exist in a User-Agent string. VER refers to the regular * expression defined in the constant self::VER. * * @var array */ protected static $properties = array( 'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'), ); /** * Construct an instance of this class. * * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored. * If left empty, will use the global _SERVER['HTTP_*'] vars instead. * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT * from the $headers array instead. */ public function __construct( array $headers = null, $userAgent = null ) { $this->setHttpHeaders($headers); $this->setUserAgent($userAgent); } /** * Get the current script version. * This is useful for the demo.php file, * so people can check on what version they are testing * for mobile devices. * * @return string The version number in semantic version format. */ public static function getScriptVersion() { return self::VERSION; } /** * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers. * * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract * the headers. The default null is left for backwards compatibilty. */ public function setHttpHeaders($httpHeaders = null) { //use global _SERVER if $httpHeaders aren't defined if (!is_array($httpHeaders) || !count($httpHeaders)) { $httpHeaders = $_SERVER; } //clear existing headers $this->httpHeaders = array(); //Only save HTTP headers. In PHP land, that means only _SERVER vars that //start with HTTP_. foreach ($httpHeaders as $key => $value) { if (substr($key,0,5) == 'HTTP_') { $this->httpHeaders[$key] = $value; } } } /** * Retrieves the HTTP headers. * * @return array */ public function getHttpHeaders() { return $this->httpHeaders; } /** * Retrieves a particular header. If it doesn't exist, no exception/error is caused. * Simply null is returned. * * @param string $header The name of the header to retrieve. Can be HTTP compliant such as * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the * all-caps, HTTP_ prefixed, underscore seperated awesomeness. * * @return string|null The value of the header. */ public function getHttpHeader($header) { //are we using PHP-flavored headers? if (strpos($header, '_') === false) { $header = str_replace('-', '_', $header); $header = strtoupper($header); } //test the alternate, too $altHeader = 'HTTP_' . $header; //Test both the regular and the HTTP_ prefix if (isset($this->httpHeaders[$header])) { return $this->httpHeaders[$header]; } elseif (isset($this->httpHeaders[$altHeader])) { return $this->httpHeaders[$altHeader]; } return null; } public function getMobileHeaders() { return self::$mobileHeaders; } /** * Get all possible HTTP headers that * can contain the User-Agent string. * * @return array List of HTTP headers. */ public function getUaHttpHeaders() { return self::$uaHttpHeaders; } /** * Set the User-Agent to be used. * * @param string $userAgent The user agent string to set. * * @return string|null */ public function setUserAgent($userAgent = null) { if (!empty($userAgent)) { return $this->userAgent = $userAgent; } else { $this->userAgent = null; foreach ($this->getUaHttpHeaders() as $altHeader) { if (!empty($this->httpHeaders[$altHeader])) { // @todo: should use getHttpHeader(), but it would be slow. (Serban) $this->userAgent .= $this->httpHeaders[$altHeader] . " "; } } return $this->userAgent = (!empty($this->userAgent) ? trim($this->userAgent) : null); } } /** * Retrieve the User-Agent. * * @return string|null The user agent if it's set. */ public function getUserAgent() { return $this->userAgent; } /** * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set. * * @deprecated since version 2.6.9 * * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default * parameter is null which will default to self::DETECTION_TYPE_MOBILE. */ public function setDetectionType($type = null) { if ($type === null) { $type = self::DETECTION_TYPE_MOBILE; } if ($type != self::DETECTION_TYPE_MOBILE && $type != self::DETECTION_TYPE_EXTENDED) { return; } $this->detectionType = $type; } /** * Retrieve the list of known phone devices. * * @return array List of phone devices. */ public static function getPhoneDevices() { return self::$phoneDevices; } /** * Retrieve the list of known tablet devices. * * @return array List of tablet devices. */ public static function getTabletDevices() { return self::$tabletDevices; } /** * Alias for getBrowsers() method. * * @return array List of user agents. */ public static function getUserAgents() { return self::getBrowsers(); } /** * Retrieve the list of known browsers. Specifically, the user agents. * * @return array List of browsers / user agents. */ public static function getBrowsers() { return self::$browsers; } /** * Retrieve the list of known utilities. * * @return array List of utilities. */ public static function getUtilities() { return self::$utilities; } /** * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*(). * * @deprecated since version 2.6.9 * * @return array All the rules (but not extended). */ public static function getMobileDetectionRules() { static $rules; if (!$rules) { $rules = array_merge( self::$phoneDevices, self::$tabletDevices, self::$operatingSystems, self::$browsers ); } return $rules; } /** * Method gets the mobile detection rules + utilities. * The reason this is separate is because utilities rules * don't necessary imply mobile. This method is used inside * the new $detect->is('stuff') method. * * @deprecated since version 2.6.9 * * @return array All the rules + extended. */ public function getMobileDetectionRulesExtended() { static $rules; if (!$rules) { // Merge all rules together. $rules = array_merge( self::$phoneDevices, self::$tabletDevices, self::$operatingSystems, self::$browsers, self::$utilities ); } return $rules; } /** * Retrieve the current set of rules. * * @deprecated since version 2.6.9 * * @return array */ public function getRules() { if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) { return self::getMobileDetectionRulesExtended(); } else { return self::getMobileDetectionRules(); } } /** * Retrieve the list of mobile operating systems. * * @return array The list of mobile operating systems. */ public static function getOperatingSystems() { return self::$operatingSystems; } /** * Check the HTTP headers for signs of mobile. * This is the fastest mobile check possible; it's used * inside isMobile() method. * * @return bool */ public function checkHttpHeadersForMobile() { foreach ($this->getMobileHeaders() as $mobileHeader => $matchType) { if ( isset($this->httpHeaders[$mobileHeader]) ) { if ( is_array($matchType['matches']) ) { foreach ($matchType['matches'] as $_match) { if ( strpos($this->httpHeaders[$mobileHeader], $_match) !== false ) { return true; } } return false; } else { return true; } } } return false; } /** * Magic overloading method. * * @method boolean is[...]() * @param string $name * @param array $arguments * @return mixed * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is' */ public function __call($name, $arguments) { //make sure the name starts with 'is', otherwise if (substr($name, 0, 2) != 'is') { throw new BadMethodCallException("No such method exists: $name"); } $this->setDetectionType(self::DETECTION_TYPE_MOBILE); $key = substr($name, 2); return $this->matchUAAgainstKey($key); } /** * Find a detection rule that matches the current User-agent. * * @param null $userAgent deprecated * @return boolean */ protected function matchDetectionRulesAgainstUA($userAgent = null) { // Begin general search. foreach ($this->getRules() as $_regex) { if (empty($_regex)) { continue; } if ($this->match($_regex, $userAgent)) { return true; } } return false; } /** * Search for a certain key in the rules array. * If the key is found the try to match the corresponding * regex agains the User-Agent. * * @param string $key * @param null $userAgent deprecated * @return mixed */ protected function matchUAAgainstKey($key, $userAgent = null) { // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc. $key = strtolower($key); //change the keys to lower case $_rules = array_change_key_case($this->getRules()); if (array_key_exists($key, $_rules)) { if (empty($_rules[$key])) { return null; } return $this->match($_rules[$key], $userAgent); } return false; } /** * Check if the device is mobile. * Returns true if any type of mobile device detected, including special ones * @param null $userAgent deprecated * @param null $httpHeaders deprecated * @return bool */ public function isMobile($userAgent = null, $httpHeaders = null) { if ($httpHeaders) { $this->setHttpHeaders($httpHeaders); } if ($userAgent) { $this->setUserAgent($userAgent); } $this->setDetectionType(self::DETECTION_TYPE_MOBILE); if ($this->checkHttpHeadersForMobile()) { return true; } else { return $this->matchDetectionRulesAgainstUA(); } } /** * Check if the device is a tablet. * Return true if any type of tablet device is detected. * * @param string $userAgent deprecated * @param array $httpHeaders deprecated * @return bool */ public function isTablet($userAgent = null, $httpHeaders = null) { $this->setDetectionType(self::DETECTION_TYPE_MOBILE); foreach (self::$tabletDevices as $_regex) { if ($this->match($_regex, $userAgent)) { return true; } } return false; } /** * This method checks for a certain property in the * userAgent. * @todo: The httpHeaders part is not yet used. * * @param string $key * @param string $userAgent deprecated * @param string $httpHeaders deprecated * @return bool|int|null */ public function is($key, $userAgent = null, $httpHeaders = null) { // Set the UA and HTTP headers only if needed (eg. batch mode). if ($httpHeaders) { $this->setHttpHeaders($httpHeaders); } if ($userAgent) { $this->setUserAgent($userAgent); } $this->setDetectionType(self::DETECTION_TYPE_EXTENDED); return $this->matchUAAgainstKey($key); } /** * Some detection rules are relative (not standard), * because of the diversity of devices, vendors and * their conventions in representing the User-Agent or * the HTTP headers. * * This method will be used to check custom regexes against * the User-Agent string. * * @param $regex * @param string $userAgent * @return bool * * @todo: search in the HTTP headers too. */ public function match($regex, $userAgent = null) { // Escape the special character which is the delimiter. $regex = str_replace('/', '\/', $regex); return (bool) preg_match('/'.$regex.'/is', (!empty($userAgent) ? $userAgent : $this->userAgent)); } /** * Get the properties array. * * @return array */ public static function getProperties() { return self::$properties; } /** * Prepare the version number. * * @todo Remove the error supression from str_replace() call. * * @param string $ver The string version, like "2.6.21.2152"; * * @return float */ public function prepareVersionNo($ver) { $ver = str_replace(array('_', ' ', '/'), '.', $ver); $arrVer = explode('.', $ver, 2); if (isset($arrVer[1])) { $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions. } return (float) implode('.', $arrVer); } /** * Check the version of the given property in the User-Agent. * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31) * * @param string $propertyName The name of the property. See self::getProperties() array * keys for all possible properties. * @param string $type Either self::VERSION_TYPE_STRING to get a string value or * self::VERSION_TYPE_FLOAT indicating a float value. This parameter * is optional and defaults to self::VERSION_TYPE_STRING. Passing an * invalid parameter will default to the this type as well. * * @return string|float The version of the property we are trying to extract. */ public function version($propertyName, $type = self::VERSION_TYPE_STRING) { if (empty($propertyName)) { return false; } //set the $type to the default if we don't recognize the type if ($type != self::VERSION_TYPE_STRING && $type != self::VERSION_TYPE_FLOAT) { $type = self::VERSION_TYPE_STRING; } $properties = self::getProperties(); // Check if the property exists in the properties array. if (array_key_exists($propertyName, $properties)) { // Prepare the pattern to be matched. // Make sure we always deal with an array (string is converted). $properties[$propertyName] = (array) $properties[$propertyName]; foreach ($properties[$propertyName] as $propertyMatchString) { $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString); // Escape the special character which is the delimiter. $propertyPattern = str_replace('/', '\/', $propertyPattern); // Identify and extract the version. preg_match('/'.$propertyPattern.'/is', $this->userAgent, $match); if (!empty($match[1])) { $version = ( $type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1] ); return $version; } } } return false; } /** * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants. * * @return string One of the self::MOBILE_GRADE_* constants. */ public function mobileGrade() { $isMobile = $this->isMobile(); if ( // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1) $this->isIOS() && $this->version('iPad', self::VERSION_TYPE_FLOAT)>=4.3 || $this->isIOS() && $this->version('iPhone', self::VERSION_TYPE_FLOAT)>=3.1 ){ return self::MOBILE_GRADE_A; } if ( $this->isIOS() && $this->version('iPad', self::VERSION_TYPE_FLOAT)<4.3 ){ return self::MOBILE_GRADE_B; } if ( // Blackberry 4.x - Tested on the Curve 8330 $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<5.0 || // Windows Mobile - Tested on the HTC Leo (WinMo 5.2) $this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', self::VERSION_TYPE_FLOAT)<=5.2 ){ return self::MOBILE_GRADE_C; } //All older smartphone platforms and featurephones - Any device that doesn't support media queries //will receive the basic, C grade experience. return self::MOBILE_GRADE_C; } }

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.60.0120.00318.29
8.3.50.0080.01521.08
8.3.40.0000.01518.57
8.3.30.0030.01119.07
8.3.20.0080.00020.48
8.3.10.0050.00323.53
8.3.00.0040.00419.13
8.2.180.0200.00018.31
8.2.170.0060.00922.96
8.2.160.0040.01120.66
8.2.150.0000.00824.18
8.2.140.0040.00424.66
8.2.130.0040.00426.16
8.2.120.0070.00322.10
8.2.110.0030.00620.55
8.2.100.0090.00317.84
8.2.90.0000.00918.97
8.2.80.0000.00917.97
8.2.70.0050.00517.63
8.2.60.0080.00318.04
8.2.50.0030.00618.07
8.2.40.0060.00319.51
8.2.30.0000.00817.95
8.2.20.0000.00817.78
8.2.10.0040.00418.03
8.2.00.0040.00417.71
8.1.280.0120.00925.92
8.1.270.0030.00622.18
8.1.260.0040.00426.35
8.1.250.0080.00028.09
8.1.240.0060.00323.79
8.1.230.0120.00023.70
8.1.220.0000.00817.79
8.1.210.0040.00418.77
8.1.200.0030.00717.35
8.1.190.0030.00517.23
8.1.180.0000.00818.10
8.1.170.0060.00618.71
8.1.160.0060.00322.00
8.1.150.0000.00818.86
8.1.140.0090.00017.45
8.1.130.0050.00217.80
8.1.120.0000.00717.49
8.1.110.0030.00617.46
8.1.100.0000.00817.51
8.1.90.0040.00417.48
8.1.80.0040.00417.44
8.1.70.0000.00717.40
8.1.60.0040.00417.56
8.1.50.0000.00817.54
8.1.40.0060.00317.53
8.1.30.0080.00017.60
8.1.20.0000.00817.64
8.1.10.0000.00817.47
8.1.00.0000.00817.45
8.0.300.0040.00418.77
8.0.290.0040.00416.63
8.0.280.0070.00018.45
8.0.270.0030.00317.20
8.0.260.0030.00317.25
8.0.250.0000.00816.99
8.0.240.0030.00316.98
8.0.230.0030.00516.93
8.0.220.0000.00716.86
8.0.210.0030.00316.78
8.0.200.0000.00716.96
8.0.190.0000.01216.86
8.0.180.0040.00416.91
8.0.170.0060.00316.94
8.0.160.0030.00516.86
8.0.150.0030.00616.68
8.0.140.0000.00716.75
8.0.130.0070.00013.39
8.0.120.0050.00316.89
8.0.110.0040.00416.79
8.0.100.0080.00016.74
8.0.90.0030.00516.99
8.0.80.0110.01116.88
8.0.70.0050.00316.75
8.0.60.0000.00816.90
8.0.50.0040.00416.85
8.0.30.0120.00917.01
8.0.20.0110.00917.40
8.0.10.0000.00716.89
8.0.00.0110.00716.83
7.4.330.0020.00215.02
7.4.320.0000.00616.65
7.4.300.0080.00016.52
7.4.290.0000.00716.52
7.4.280.0040.00716.36
7.4.270.0000.00716.46
7.4.260.0030.00416.47
7.4.250.0040.00416.58
7.4.240.0050.00316.52
7.4.230.0050.00216.42
7.4.220.0080.01116.43
7.4.210.0150.00616.61
7.4.200.0000.00816.31
7.4.160.0060.01016.59
7.4.150.0100.01017.40
7.4.140.0130.01017.86
7.4.130.0120.00916.48
7.4.120.0130.00616.52
7.4.110.0140.00316.52
7.4.100.0140.00416.32
7.4.90.0200.00316.46
7.4.80.0090.00919.39
7.4.70.0090.01016.46
7.4.60.0030.01316.57
7.4.50.0000.00816.55
7.4.40.0120.00916.46
7.4.30.0070.01016.44
7.4.00.0110.00415.14
7.3.330.0050.00013.17
7.3.320.0000.00513.32
7.3.310.0030.00316.25
7.3.300.0000.00716.27
7.3.290.0070.00816.27
7.3.280.0080.00916.28
7.3.270.0060.01317.40
7.3.260.0060.01116.57
7.3.250.0140.00516.41
7.3.240.0130.00516.37
7.3.230.0100.00716.39
7.3.210.0030.01316.41
7.3.200.0060.01219.39
7.3.190.0100.00916.26
7.3.180.0110.00616.14
7.3.170.0060.01016.57
7.3.160.0070.01016.60
7.2.330.0110.00616.63
7.2.320.0100.01316.51
7.2.310.0070.01716.69
7.2.300.0120.01016.66
7.2.290.0140.01016.63
7.2.60.0030.01316.54
7.2.00.0030.01019.06
7.1.200.0040.00815.52
7.1.100.0060.00917.88
7.1.70.0040.00416.76
7.1.60.0130.01019.11
7.1.50.0000.01416.92
7.1.00.0070.07322.45
7.0.200.0160.00016.63
7.0.140.0000.07022.00
7.0.100.0130.07720.04
7.0.90.0070.06720.06
7.0.80.0200.03720.09
7.0.70.0230.05020.02
7.0.60.0030.07320.06
7.0.50.0100.06320.28
7.0.40.0000.08020.12
7.0.30.0030.09720.11
7.0.20.0070.07720.05
7.0.10.0230.07320.10
7.0.00.0030.05320.17
5.6.280.0100.06720.92
5.6.250.0100.05320.73
5.6.240.0070.04320.61
5.6.230.0200.07020.61
5.6.220.0130.03020.77
5.6.210.0030.05020.75
5.6.200.0070.04021.04
5.6.190.0170.06021.13
5.6.180.0070.05321.18
5.6.170.0000.09321.05
5.6.160.0170.08721.16
5.6.150.0170.07721.18
5.6.140.0070.06021.05
5.6.130.0070.08721.27
5.6.120.0200.06721.15
5.6.110.0070.04321.02
5.6.100.0070.06721.17
5.6.90.0100.05721.13
5.6.80.0170.07320.52
5.6.70.0130.06720.41
5.6.60.0070.04020.36
5.6.50.0070.04720.50
5.6.40.0100.04020.63
5.6.30.0000.05320.39
5.6.20.0130.05320.36
5.6.10.0070.05320.51
5.6.00.0030.05320.40
5.5.380.0030.04020.46
5.5.370.0070.03720.52
5.5.360.0000.08720.59
5.5.350.0030.04720.57
5.5.340.0030.04020.99
5.5.330.0170.08321.02
5.5.320.0070.08021.02
5.5.310.0130.07721.02
5.5.300.0070.04320.83
5.5.290.0000.07320.96
5.5.280.0100.08720.90
5.5.270.0030.09021.00
5.5.260.0000.09021.01
5.5.250.0170.04720.64
5.5.240.0130.07320.31
5.5.230.0070.08720.36
5.5.220.0030.05020.21
5.5.210.0030.08020.38
5.5.200.0130.04720.31
5.5.190.0100.06320.32
5.5.180.0070.07020.09
5.5.160.0170.06720.25
5.5.150.0100.07320.32
5.5.140.0130.06320.34
5.5.130.0230.06720.22
5.5.120.0100.07320.32
5.5.110.0030.07720.22
5.5.100.0130.06320.18
5.5.90.0030.05020.16
5.5.80.0000.08020.25
5.5.70.0030.05020.11
5.5.60.0030.06320.18
5.5.50.0070.03720.15
5.5.40.0170.06020.18
5.5.30.0070.07720.23
5.5.20.0030.04720.21
5.5.10.0070.06020.14
5.5.00.0230.04020.16
5.4.450.0170.07019.37
5.4.440.0270.05719.21
5.4.430.0030.04719.45
5.4.420.0100.05319.30
5.4.410.0070.07319.26
5.4.400.0030.04018.99
5.4.390.0070.04719.14
5.4.380.0000.06018.88
5.4.370.0030.04719.03
5.4.360.0170.07318.92
5.4.350.0070.07319.16
5.4.340.0030.07018.99
5.4.320.0070.06319.22
5.4.310.0030.04019.28
5.4.300.0070.04318.98
5.4.290.0070.06018.98
5.4.280.0070.04718.92
5.4.270.0030.05019.06
5.4.260.0170.07319.07
5.4.250.0070.04318.91
5.4.240.0030.08319.20
5.4.230.0200.06019.21
5.4.220.0130.05719.08
5.4.210.0070.06718.88
5.4.200.0170.05718.92
5.4.190.0070.07318.93
5.4.180.0070.05719.22
5.4.170.0030.08019.20
5.4.160.0070.07319.06
5.4.150.0100.03719.07
5.4.140.0100.09316.44
5.4.130.0100.04716.41
5.4.120.0030.03316.30
5.4.110.0030.06316.36
5.4.100.0070.07316.41
5.4.90.0030.06016.56
5.4.80.0200.05716.54
5.4.70.0000.05016.42
5.4.60.0070.03016.51
5.4.50.0070.03316.45
5.4.40.0000.05016.55
5.4.30.0070.07316.38
5.4.20.0070.07016.38
5.4.10.0030.04716.32
5.4.00.0070.03015.82

preferences:
47.09 ms | 401 KiB | 5 Q