3v4l.org

run code in 300+ PHP versions simultaneously
<?php namespace TYPO3\Flow\Mvc\Controller; /* * * This script belongs to the TYPO3 Flow framework. * * * * It is free software; you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License, either version 3 * * of the License, or (at your option) any later version. * * * * The TYPO3 project - inspiring people to share! * * */ use TYPO3\Flow\Annotations as Flow; /** * An HTTP based multi-action controller. * * The action specified in the given ActionRequest is dispatched to a method in * the concrete controller whose name ends with "*Action". If no matching action * method is found, the action specified in $errorMethodName is invoked. * * This controller also takes care of mapping arguments found in the ActionRequest * to the corresponding method arguments of the action method. It also invokes * validation for these arguments by invoking the Property Mapper. * * By defining media types in $supportedMediaTypes, content negotiation based on * the browser's Accept header and additional routing configuration is used to * determine the output format the controller should return. * * Depending on the action being called, a fitting view - by default a Fluid template * view - will be selected. By specifying patterns, custom view classes or an alternative * controller / action to template path mapping can be defined. * * @Flow\Scope("singleton") * @api */ class ActionController extends AbstractController { /** * @Flow\Inject * @var \TYPO3\Flow\Object\ObjectManagerInterface */ protected $objectManager; /** * @Flow\Inject * @var \TYPO3\Flow\Reflection\ReflectionService */ protected $reflectionService; /** * @Flow\Inject * @var \TYPO3\Flow\Mvc\Controller\MvcPropertyMappingConfigurationService */ protected $mvcPropertyMappingConfigurationService; /** * The current view, as resolved by resolveView() * * @var \TYPO3\Flow\Mvc\View\ViewInterface * @api */ protected $view = NULL; /** * Pattern after which the view object name is built if no format-specific * view could be resolved. * * @var string * @api */ protected $viewObjectNamePattern = '@package\View\@controller\@action@format'; /** * A list of formats and object names of the views which should render them. * * Example: * * array('html' => 'MyCompany\MyApp\MyHtmlView', 'json' => 'MyCompany\... * * @var array */ protected $viewFormatToObjectNameMap = array(); /** * The default view object to use if none of the resolved views can render * a response for the current request. * * @var string * @api */ protected $defaultViewObjectName = 'TYPO3\Fluid\View\TemplateView'; /** * Name of the action method * * @var string */ protected $actionMethodName; /** * Name of the special error action method which is called in case of errors * * @var string * @api */ protected $errorMethodName = 'errorAction'; /** * @var array */ protected $settings; /** * @param array $settings * @return void */ public function injectSettings(array $settings) { $this->settings = $settings; } /** * Handles a request. The result output is returned by altering the given response. * * @param \TYPO3\Flow\Mvc\RequestInterface $request The request object * @param \TYPO3\Flow\Mvc\ResponseInterface $response The response, modified by this handler * @return void * @throws \TYPO3\Flow\Mvc\Exception\UnsupportedRequestTypeException * @api */ public function processRequest(\TYPO3\Flow\Mvc\RequestInterface $request, \TYPO3\Flow\Mvc\ResponseInterface $response) { $this->initializeController($request, $response); $this->actionMethodName = $this->resolveActionMethodName(); $this->initializeActionMethodArguments(); $this->initializeActionMethodValidators(); $this->mvcPropertyMappingConfigurationService->initializePropertyMappingConfigurationFromRequest($this->request, $this->arguments); $this->initializeAction(); $actionInitializationMethodName = 'initialize' . ucfirst($this->actionMethodName); if (method_exists($this, $actionInitializationMethodName)) { call_user_func(array($this, $actionInitializationMethodName)); } $this->mapRequestArgumentsToControllerArguments(); $this->view = $this->resolveView(); if ($this->view !== NULL) { $this->view->assign('settings', $this->settings); $this->initializeView($this->view); } $this->callActionMethod(); } /** * Resolves and checks the current action method name * * @return string Method name of the current action * @throws \TYPO3\Flow\Mvc\Exception\NoSuchActionException */ protected function resolveActionMethodName() { $actionMethodName = $this->request->getControllerActionName() . 'Action'; if (!is_callable(array($this, $actionMethodName))) { throw new \TYPO3\Flow\Mvc\Exception\NoSuchActionException('An action "' . $actionMethodName . '" does not exist in controller "' . get_class($this) . '".', 1186669086); } return $actionMethodName; } /** * Implementation of the arguments initialization in the action controller: * Automatically registers arguments of the current action * * Don't override this method - use initializeAction() instead. * * @return void * @throws \TYPO3\Flow\Mvc\Exception\InvalidArgumentTypeException * @see initializeArguments() */ protected function initializeActionMethodArguments() { $actionMethodParameters = static::getActionMethodParameters($this->objectManager); if (isset($actionMethodParameters[$this->actionMethodName])) { $methodParameters = $actionMethodParameters[$this->actionMethodName]; } else { $methodParameters = array(); } $this->arguments->removeAll(); foreach ($methodParameters as $parameterName => $parameterInfo) { $dataType = NULL; if (isset($parameterInfo['type'])) { $dataType = $parameterInfo['type']; } elseif ($parameterInfo['array']) { $dataType = 'array'; } if ($dataType === NULL) throw new \TYPO3\Flow\Mvc\Exception\InvalidArgumentTypeException('The argument type for parameter $' . $parameterName . ' of method ' . get_class($this) . '->' . $this->actionMethodName . '() could not be detected.' , 1253175643); $defaultValue = (isset($parameterInfo['defaultValue']) ? $parameterInfo['defaultValue'] : NULL); $this->arguments->addNewArgument($parameterName, $dataType, ($parameterInfo['optional'] === FALSE), $defaultValue); } } /** * Returns a map of action method names and their parameters. * * @param \TYPO3\Flow\Object\ObjectManagerInterface $objectManager * @return array Array of method parameters by action name * @Flow\CompileStatic */ static public function getActionMethodParameters($objectManager) { $reflectionService = $objectManager->get('TYPO3\Flow\Reflection\ReflectionService'); $result = array(); $className = get_called_class(); $methodNames = get_class_methods($className); foreach ($methodNames as $methodName) { if (strlen($methodName) > 6 && strpos($methodName, 'Action', strlen($methodName) - 6) !== FALSE) { $result[$methodName] = $reflectionService->getMethodParameters($className, $methodName); } } return $result; } /** * Adds the needed validators to the Arguments: * * - Validators checking the data type from the @param annotation * - Custom validators specified with validate annotations. * - Model-based validators (validate annotations in the model) * - Custom model validator classes * * @return void */ protected function initializeActionMethodValidators() { $validateGroupAnnotations = static::getActionValidationGroups($this->objectManager); if (isset($validateGroupAnnotations[$this->actionMethodName])) { $validationGroups = $validateGroupAnnotations[$this->actionMethodName]; } else { $validationGroups = array('Default', 'Controller'); } $actionMethodParameters = static::getActionMethodParameters($this->objectManager); if (isset($actionMethodParameters[$this->actionMethodName])) { $methodParameters = $actionMethodParameters[$this->actionMethodName]; } else { $methodParameters = array(); } $actionValidateAnnotations = static::getActionValidateAnnotationData($this->objectManager); if (isset($actionValidateAnnotations[$this->actionMethodName])) { $validateAnnotations = $actionValidateAnnotations[$this->actionMethodName]; } else { $validateAnnotations = array(); } $parameterValidators = $this->validatorResolver->buildMethodArgumentsValidatorConjunctions(get_class($this), $this->actionMethodName, $methodParameters, $validateAnnotations); foreach ($this->arguments as $argument) { $validator = $parameterValidators[$argument->getName()]; $baseValidatorConjunction = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType(), $validationGroups); if (count($baseValidatorConjunction) > 0) { $validator->addValidator($baseValidatorConjunction); } $argument->setValidator($validator); } } /** * Returns a map of action method names and their validation groups. * * @param \TYPO3\Flow\Object\ObjectManagerInterface $objectManager * @return array Array of validation groups by action method name * @Flow\CompileStatic */ static public function getActionValidationGroups($objectManager) { $reflectionService = $objectManager->get('TYPO3\Flow\Reflection\ReflectionService'); $result = array(); $className = get_called_class(); $methodNames = get_class_methods($className); foreach ($methodNames as $methodName) { if (strlen($methodName) > 6 && strpos($methodName, 'Action', strlen($methodName) - 6) !== FALSE) { $validationGroupsAnnotation = $reflectionService->getMethodAnnotation($className, $methodName, 'TYPO3\Flow\Annotations\ValidationGroups'); if ($validationGroupsAnnotation !== NULL) { $result[$methodName] = $validationGroupsAnnotation->validationGroups; } } } return $result; } /** * Returns a map of action method names and their validation parameters. * * @param \TYPO3\Flow\Object\ObjectManagerInterface $objectManager * @return array Array of validate annotation parameters by action method name * @Flow\CompileStatic */ static public function getActionValidateAnnotationData($objectManager) { $reflectionService = $objectManager->get('TYPO3\Flow\Reflection\ReflectionService'); $result = array(); $className = get_called_class(); $methodNames = get_class_methods($className); foreach ($methodNames as $methodName) { if (strlen($methodName) > 6 && strpos($methodName, 'Action', strlen($methodName) - 6) !== FALSE) { $validateAnnotations = $reflectionService->getMethodAnnotations($className, $methodName, 'TYPO3\Flow\Annotations\Validate'); $result[$methodName] = array_map(function($validateAnnotation) { return array( 'type' => $validateAnnotation->type, 'options' => $validateAnnotation->options, 'argumentName' => $validateAnnotation->argumentName, ); }, $validateAnnotations); } } return $result; } /** * Initializes the controller before invoking an action method. * * Override this method to solve tasks which all actions have in * common. * * @return void * @api */ protected function initializeAction() { } /** * Calls the specified action method and passes the arguments. * * If the action returns a string, it is appended to the content in the * response object. If the action doesn't return anything and a valid * view exists, the view is rendered automatically. * * @return void */ protected function callActionMethod() { $preparedArguments = array(); foreach ($this->arguments as $argument) { $preparedArguments[] = $argument->getValue(); } $validationResult = $this->arguments->getValidationResults(); if (!$validationResult->hasErrors()) { $actionResult = call_user_func_array(array($this, $this->actionMethodName), $preparedArguments); } else { $actionIgnoredArguments = static::getActionIgnoredValidationArguments($this->objectManager); if (isset($actionIgnoredArguments[$this->actionMethodName])) { $ignoredArguments = $actionIgnoredArguments[$this->actionMethodName]; } else { $ignoredArguments = array(); } // if there exists more errors than in ignoreValidationAnnotations_=> call error method // else => call action method $shouldCallActionMethod = TRUE; foreach ($validationResult->getSubResults() as $argumentName => $subValidationResult) { if (!$subValidationResult->hasErrors()) continue; if (array_search($argumentName, $ignoredArguments) !== FALSE) { continue; } $shouldCallActionMethod = FALSE; } if ($shouldCallActionMethod) { $actionResult = call_user_func_array(array($this, $this->actionMethodName), $preparedArguments); } else { $actionResult = call_user_func(array($this, $this->errorMethodName)); } } if ($actionResult === NULL && $this->view instanceof \TYPO3\Flow\Mvc\View\ViewInterface) { $this->response->appendContent($this->view->render()); } elseif (is_string($actionResult) && strlen($actionResult) > 0) { $this->response->appendContent($actionResult); } elseif (is_object($actionResult) && method_exists($actionResult, '__toString')) { $this->response->appendContent((string)$actionResult); } } /** * @param \TYPO3\Flow\Object\ObjectManagerInterface $objectManager * @return array Array of arguments ignored for validation by action method name * @Flow\CompileStatic */ static public function getActionIgnoredValidationArguments($objectManager) { $reflectionService = $objectManager->get('TYPO3\Flow\Reflection\ReflectionService'); $result = array(); $className = get_called_class(); $methodNames = get_class_methods($className); foreach ($methodNames as $methodName) { if (strlen($methodName) > 6 && strpos($methodName, 'Action', strlen($methodName) - 6) !== FALSE) { $ignoreValidationAnnotations = $reflectionService->getMethodAnnotations($className, $methodName, 'TYPO3\Flow\Annotations\IgnoreValidation'); $ignoredArguments = array_map(function($annotation) { return $annotation->argumentName; }, $ignoreValidationAnnotations); if ($ignoredArguments !== array()) { $result[$methodName] = $ignoredArguments; } } } return $result; } /** * Prepares a view for the current action and stores it in $this->view. * By default, this method tries to locate a view with a name matching * the current action. * * @return \TYPO3\Flow\Mvc\View\ViewInterface the resolved view * @api * @throws \TYPO3\Flow\Mvc\Exception\ViewNotFoundException if no view can be resolved */ protected function resolveView() { $viewObjectName = $this->resolveViewObjectName(); if ($viewObjectName !== FALSE) { $view = $this->objectManager->get($viewObjectName); } elseif ($this->defaultViewObjectName != '') { $view = $this->objectManager->get($this->defaultViewObjectName); } if (!isset($view)) { throw new \TYPO3\Flow\Mvc\Exception\ViewNotFoundException(sprintf('Could not resolve view for action "%s" in controller "%s"', $this->request->getControllerActionName(), get_class($this)), 1355153185); } if (!$view instanceof \TYPO3\Flow\Mvc\View\ViewInterface) { throw new \TYPO3\Flow\Mvc\Exception\ViewNotFoundException(sprintf('View has to be of type ViewInterface, got "%s" in action "%s" of controller "%s"', get_class($view), $this->request->getControllerActionName(), get_class($this)), 1355153188); } $view->setControllerContext($this->controllerContext); return $view; } /** * Determines the fully qualified view object name. * * @return mixed The fully qualified view object name or FALSE if no matching view could be found. * @api */ protected function resolveViewObjectName() { $possibleViewObjectName = $this->viewObjectNamePattern; $packageKey = $this->request->getControllerPackageKey(); $subpackageKey = $this->request->getControllerSubpackageKey(); $format = $this->request->getFormat(); if ($subpackageKey !== NULL && $subpackageKey !== '') { $packageKey.= '\\' . $subpackageKey; } $possibleViewObjectName = str_replace('@package', str_replace('.', '\\', $packageKey), $possibleViewObjectName); $possibleViewObjectName = str_replace('@controller', $this->request->getControllerName(), $possibleViewObjectName); $possibleViewObjectName = str_replace('@action', $this->request->getControllerActionName(), $possibleViewObjectName); $viewObjectName = $this->objectManager->getCaseSensitiveObjectName(strtolower(str_replace('@format', $format, $possibleViewObjectName))); if ($viewObjectName === FALSE) { $viewObjectName = $this->objectManager->getCaseSensitiveObjectName(strtolower(str_replace('@format', '', $possibleViewObjectName))); } if ($viewObjectName === FALSE && isset($this->viewFormatToObjectNameMap[$format])) { $viewObjectName = $this->viewFormatToObjectNameMap[$format]; } return $viewObjectName; } /** * Initializes the view before invoking an action method. * * Override this method to solve assign variables common for all actions * or prepare the view in another way before the action is called. * * @param \TYPO3\Flow\Mvc\View\ViewInterface $view The view to be initialized * @return void * @api */ protected function initializeView(\TYPO3\Flow\Mvc\View\ViewInterface $view) { } /** * A special action which is called if the originally intended action could * not be called, for example if the arguments were not valid. * * The default implementation sets a flash message, request errors and forwards back * to the originating action. This is suitable for most actions dealing with form input. * * @return string * @api */ protected function errorAction() { $errorFlashMessage = $this->getErrorFlashMessage(); if ($errorFlashMessage !== FALSE) { $this->flashMessageContainer->addMessage($errorFlashMessage); } $referringRequest = $this->request->getReferringRequest(); if ($referringRequest !== NULL) { $subPackageKey = $referringRequest->getControllerSubpackageKey(); if ($subPackageKey !== NULL) { rtrim($packageAndSubpackageKey = $referringRequest->getControllerPackageKey() . '\\' . $referringRequest->getControllerSubpackageKey(), '\\'); } else { $packageAndSubpackageKey = $referringRequest->getControllerPackageKey(); } $argumentsForNextController = $referringRequest->getArguments(); $argumentsForNextController['__submittedArguments'] = $this->request->getArguments(); $argumentsForNextController['__submittedArgumentValidationResults'] = $this->arguments->getValidationResults(); $this->forward($referringRequest->getControllerActionName(), $referringRequest->getControllerName(), $packageAndSubpackageKey, $argumentsForNextController); } $message = 'An error occurred while trying to call ' . get_class($this) . '->' . $this->actionMethodName . '().' . PHP_EOL; foreach ($this->arguments->getValidationResults()->getFlattenedErrors() as $propertyPath => $errors) { foreach ($errors as $error) { $message .= 'Error for ' . $propertyPath . ': ' . $error->render() . PHP_EOL; } } return $message; } /** * A template method for displaying custom error flash messages, or to * display no flash message at all on errors. Override this to customize * the flash message in your action controller. * * @return \TYPO3\Flow\Error\Message The flash message or FALSE if no flash message should be set * @api */ protected function getErrorFlashMessage() { return new \TYPO3\Flow\Error\Error('An error occurred while trying to call %1$s->%2$s()', NULL, array(get_class($this), $this->actionMethodName)); } }

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.0110.00718.32
8.3.50.0090.00921.15
8.3.40.0090.01218.99
8.3.30.0160.00318.70
8.3.20.0040.00419.08
8.3.10.0050.00321.05
8.3.00.0000.00922.07
8.2.180.0180.00416.75
8.2.170.0080.00822.96
8.2.160.0090.00620.52
8.2.150.0030.00524.18
8.2.140.0030.00524.66
8.2.130.0050.00326.16
8.2.120.0080.00019.65
8.2.110.0060.00320.38
8.2.100.0060.00617.89
8.2.90.0060.00319.39
8.2.80.0060.00317.97
8.2.70.0000.00817.88
8.2.60.0040.00418.05
8.2.50.0030.00618.07
8.2.40.0030.00518.24
8.2.30.0030.00521.23
8.2.20.0050.00317.97
8.2.10.0040.00417.93
8.2.00.0040.00417.86
8.1.280.0110.01125.92
8.1.270.0060.00323.99
8.1.260.0080.00026.35
8.1.250.0030.00628.09
8.1.240.0040.00722.38
8.1.230.0060.00621.20
8.1.220.0000.00818.77
8.1.210.0100.00019.15
8.1.200.0050.00517.38
8.1.190.0050.00317.65
8.1.180.0090.00018.10
8.1.170.0080.00018.91
8.1.160.0060.00319.00
8.1.150.0050.00318.77
8.1.140.0080.00017.57
8.1.130.0000.00718.01
8.1.120.0000.00717.55
8.1.110.0060.00317.59
8.1.100.0000.00817.62
8.1.90.0000.00817.46
8.1.80.0040.00417.48
8.1.70.0000.00817.45
8.1.60.0090.00017.68
8.1.50.0040.00417.58
8.1.40.0000.01017.63
8.1.30.0030.00517.76
8.1.20.0000.00917.80
8.1.10.0000.00817.61
8.1.00.0030.00517.63
8.0.300.0030.00620.08
8.0.290.0060.00317.43
8.0.280.0000.00718.63
8.0.270.0000.00717.45
8.0.260.0040.00417.07
8.0.250.0000.00717.22
8.0.240.0060.00317.09
8.0.230.0000.00717.09
8.0.220.0000.00717.17
8.0.210.0040.00417.04
8.0.200.0070.00017.14
8.0.190.0050.00317.22
8.0.180.0040.00417.20
8.0.170.0000.01017.16
8.0.160.0050.00217.16
8.0.150.0000.00717.13
8.0.140.0070.00017.17
8.0.130.0070.00013.58
8.0.120.0040.00417.08
8.0.110.0000.00816.99
8.0.100.0030.00616.94
8.0.90.0050.00317.17
8.0.80.0110.00717.16
8.0.70.0050.00317.05
8.0.60.0040.00417.02
8.0.50.0050.00317.18
8.0.30.0130.00717.35
8.0.20.0050.01417.40
8.0.10.0040.00417.21
8.0.00.0070.01716.75
7.4.330.0030.00314.59
7.4.320.0000.00716.64
7.4.300.0030.00316.68
7.4.290.0090.00016.65
7.4.280.0070.00016.67
7.4.270.0040.00416.69
7.4.260.0030.00313.40
7.4.250.0080.00016.59
7.4.240.0000.00816.55
7.4.230.0040.00416.71
7.4.220.0160.01016.73
7.4.210.0080.01016.77
7.4.200.0030.00516.84
7.4.190.0040.00416.63
7.4.160.0110.00716.69
7.4.150.0120.00617.40
7.4.140.0070.01217.86
7.4.130.0110.00716.82
7.4.120.0070.01116.69
7.4.110.0110.00716.76
7.4.100.0120.01216.66
7.4.90.0120.00616.83
7.4.80.0090.00919.39
7.4.70.0120.00616.66
7.4.60.0060.01216.51
7.4.50.0030.00616.73
7.4.40.0060.01222.52
7.4.30.0140.01416.79
7.4.00.0040.01215.07
7.3.330.0070.00013.31
7.3.320.0050.00013.37
7.3.310.0050.00216.29
7.3.300.0000.00716.38
7.3.290.0080.00816.50
7.3.280.0070.00916.51
7.3.270.0170.00617.40
7.3.260.0120.01018.24
7.3.250.0080.01016.68
7.3.240.0120.00616.59
7.3.230.0110.00616.63
7.3.210.0090.00916.67
7.3.200.0090.00919.39
7.3.190.0130.01016.46
7.3.180.0130.00316.46
7.3.170.0060.01116.50
7.3.160.0130.00316.65
7.3.120.0000.01614.93
7.3.10.0070.00916.04
7.3.00.0170.00316.33
7.2.330.0160.00316.54
7.2.320.0130.01016.44
7.2.310.0110.00816.80
7.2.300.0060.01216.45
7.2.290.0120.00916.46
7.2.130.0130.00516.16
7.2.120.0330.00916.62
7.2.110.0140.00616.82
7.2.100.0080.01416.07
7.2.90.0150.00916.59
7.2.80.0130.00716.52
7.2.70.0170.00916.50
7.2.60.0210.00716.74
7.2.50.0180.00416.48
7.2.40.0110.00816.26
7.2.30.0170.00016.17
7.2.20.0100.00716.47
7.2.10.0290.01316.64
7.2.00.0060.01117.74
7.1.250.0060.00615.71
7.1.200.0040.00815.60
7.1.100.0000.01118.00
7.1.70.0030.00716.55
7.1.60.0100.01019.40
7.1.50.0200.00716.48
7.1.00.0070.05722.31
7.0.200.0050.00516.59
7.0.140.0070.07322.14
7.0.100.0130.04020.16
7.0.90.0070.04020.04
7.0.80.0030.06020.05
7.0.70.0030.04320.15
7.0.60.0070.05720.26
7.0.50.0130.04320.47
7.0.40.0030.05720.16
7.0.30.0100.03720.05
7.0.20.0030.04020.12
7.0.10.0070.04720.15
7.0.00.0000.04720.05
5.6.280.0030.07721.03
5.6.250.0070.04720.64
5.6.240.0130.05020.86
5.6.230.0100.03720.81
5.6.220.0100.03320.75
5.6.210.0030.07720.88
5.6.200.0100.03321.14
5.6.190.0000.04721.07
5.6.180.0030.07021.07
5.6.170.0070.04321.15
5.6.160.0070.04021.12
5.6.150.0100.03721.26
5.6.140.0100.04021.07
5.6.130.0070.06321.18
5.6.120.0000.04721.14
5.6.110.0000.04721.16
5.6.100.0100.04021.05
5.6.90.0000.06021.23
5.6.80.0030.04020.60
5.6.70.0070.08020.62
5.6.60.0130.07020.57
5.6.50.0000.04020.52
5.6.40.0100.07020.54
5.6.30.0170.04720.50
5.6.20.0070.07720.49
5.6.10.0070.07720.57
5.6.00.0100.05320.47
5.5.380.0000.04720.45
5.5.370.0000.06720.67
5.5.360.0070.05720.61
5.5.350.0100.06020.59
5.5.340.0070.06320.97
5.5.330.0030.04021.00
5.5.320.0070.04320.94
5.5.310.0070.07020.77
5.5.300.0070.07320.95
5.5.290.0070.04020.99
5.5.280.0030.05320.91
5.5.270.0000.04321.01
5.5.260.0030.04021.02
5.5.250.0070.04020.77
5.5.240.0070.04320.43
5.5.230.0100.08020.26
5.5.220.0070.07720.24
5.5.210.0030.08320.24
5.5.200.0100.06320.41
5.5.190.0100.08020.36
5.5.180.0070.07720.31
5.5.160.0100.06320.34
5.5.150.0000.07320.33
5.5.140.0130.06320.30
5.5.130.0030.08020.39
5.5.120.0100.07720.36
5.5.110.0130.06720.28
5.5.100.0100.07320.20
5.5.90.0130.05320.24
5.5.80.0100.07320.28
5.5.70.0000.06720.18
5.5.60.0030.07720.20
5.5.50.0130.06720.14
5.5.40.0100.07720.23
5.5.30.0100.07320.19
5.5.20.0100.07720.09
5.5.10.0070.06720.16
5.5.00.0030.08020.10
5.4.450.0100.03319.57
5.4.440.0000.04319.32
5.4.430.0100.03719.45
5.4.420.0030.03719.57
5.4.410.0000.05719.37
5.4.400.0030.08719.18
5.4.390.0030.07719.19
5.4.380.0070.06319.11
5.4.370.0070.07318.95
5.4.360.0130.07019.10
5.4.350.0070.07019.27
5.4.340.0030.03719.14
5.4.320.0100.06019.08
5.4.310.0100.03019.08
5.4.300.0070.07319.14
5.4.290.0000.08319.24
5.4.280.0000.04019.08
5.4.270.0000.07019.09
5.4.260.0000.04719.09
5.4.250.0000.07319.12
5.4.240.0030.07719.17
5.4.230.0170.07019.08
5.4.220.0100.07019.01
5.4.210.0130.07019.09
5.4.200.0070.07319.08
5.4.190.0030.07719.08
5.4.180.0200.06319.07
5.4.170.0100.08019.07
5.4.160.0070.04319.16
5.4.150.0130.07319.25
5.4.140.0200.06316.55
5.4.130.0070.07016.43
5.4.120.0030.07316.44
5.4.110.0000.06316.60
5.4.100.0100.07716.55
5.4.90.0030.07316.54
5.4.80.0070.04016.42
5.4.70.0070.07316.56
5.4.60.0100.07016.41
5.4.50.0170.06316.52
5.4.40.0030.05016.42
5.4.30.0030.04316.50
5.4.20.0100.07016.45
5.4.10.0000.07316.50
5.4.00.0030.07016.05
5.3.290.0030.06714.96
5.3.280.0100.03314.77
5.3.270.0070.07314.73
5.3.260.0100.07314.84
5.3.250.0000.06314.76
5.3.240.0030.08714.71
5.3.230.0170.06014.80
5.3.220.0070.05014.86
5.3.210.0030.08314.69
5.3.200.0030.07014.76
5.3.190.0030.06014.84
5.3.180.0000.08014.71
5.3.170.0070.06314.83
5.3.160.0000.05014.77
5.3.150.0070.07714.81
5.3.140.0030.08014.76
5.3.130.0030.07314.82
5.3.120.0100.07714.71
5.3.110.0030.07314.66
5.3.100.0130.06314.23
5.3.90.0030.07714.17
5.3.80.0170.06014.11
5.3.70.0070.04314.18
5.3.60.0100.06314.06
5.3.50.0030.08014.11
5.3.40.0070.05714.09
5.3.30.0070.07713.98
5.3.20.0000.05313.81
5.3.10.0030.06313.94
5.3.00.0100.06313.78

preferences:
44.66 ms | 401 KiB | 5 Q