@ 2014-08-23T23:56:27Z <?php
namespace schlaus\schimile;
/**
*
* Schimile is a validation class
*
*/
class schimile {
private static $_ruleset = array();
private static $_errorHandler = null;
private static $_latestErrors = null;
private static $_currentInstance;
private $_currentIndex = 0;
private $_optional = array();
private $_nextIndex = 0;
private $_inputType;
private $_not;
private $_queue = array();
private $_queueIndex = 0;
private $_errors = array();
private $_haltOnError = false;
private $_currentValue;
private $_currentValidatorAccepts = array("boolean", "integer", "double", "string", "array", "object");
public function __construct($inputType, $index)
{
$this->_inputType = $inputType;
$this->_updateIndex($index);
}
private function _accept()
{
$shortForms = array(
"arr" => "array",
"str" => "string",
"bool" => "boolean",
"obj" => "object",
"int" => "integer",
"float" => "double"
);
$accepted = func_get_args();
if (empty($accepted)) $accepted = array("bool", "int", "float", "str", "arr", "obj");
if (count($accepted) == 1 && is_string($accepted)) {
$accepted = preg_split('/(, |,|\|)/', $accepted, -1, PREG_SPLIT_NO_EMPTY);
} elseif (is_array($accepted[0])) {
$accepted = $accepted[0];
}
foreach ($accepted as &$val) {
if (array_key_exists($val, $shortForms)) $val = $shortForms[$val];
}
$this->_currentValidatorAccepts = $accepted;
}
private function _isValidType($var, $accepted)
{
return in_array(gettype($var), $accepted);
}
private function _pushToQueue($validator, $nonNegatedMessage, $negatedMessage, $params = array())
{
$message = ($this->_not) ? $negatedMessage : $nonNegatedMessage;
$this->_queue[$this->_queueIndex][] = array(
"validator" => $validator,
"message" => $message,
"negate" => $this->_not,
"inputType" => $this->_inputType,
"accepts" => $this->_currentValidatorAccepts,
"useIndex" => $this->_currentIndex,
"params" => $params
);
$this->_accept();
}
private function _reset()
{
$this->_currentIndex = 0;
$this->_nextIndex = 0;
$this->_queue = array();
$this->_queueIndex = 0;
$this->_errors = array();
}
public static function assert($ruleset, $input)
{
if (is_object($ruleset)) {
$instance = $ruleset;
} elseif (is_string($ruleset) && array_key_exists($ruleset, self::$_ruleset)) {
$instance = clone self::$_ruleset[$ruleset];
} else {
throw new InvalidArgumentException("Invalid argument provided for schimile::loadRuleset() (Ruleset object or name expected)");
}
return $instance->execute($input);
}
public static function getErrors()
{
return self::$_latestErrors;
}
private function _handleErrors()
{
self::$_latestErrors = $this->_errors;
return false;
}
private function _pushError($item, $message)
{
$this->_errors[$item][] = $message;
}
public function execute($input)
{
foreach ($this->_queue as $index => $testArrays) {
foreach ($testArrays as $testNr => $testBlock) {
switch ($testBlock['inputType']) {
case "input":
$value = &$input;
break;
case "val":
if (is_object($input)) {
$value =& $input->$testBlock['useIndex'];
} else {
$value =& $input[$testBlock['useIndex']];
}
break;
case "key":
$value = key($input);
break;
}
$matcher = !$testBlock['negate'];
array_unshift($testBlock['params'], $value);
if ($this->_isValidType($value, $testBlock['accepts'])) {
try {
$result = call_user_func_array($testBlock['validator'], $testBlock['params']);
if (!is_bool($result)) {
$value = $result;
$result = true;
}
} catch (ValidationFailException $e) {
$this->_haltOnError = true;
$result = null;
}
} else {
throw new InvalidInputTypeException($testBlock['accepts'], $value);
}
if ($result === $matcher) {
//pass
} else {
//fail
$this->_pushError($this->_currentIndex, $testBlock['message']);
if ($this->_haltOnError) {
break 2;
}
}
}
}
if (!empty($this->_errors)) {
if (is_null(self::$_errorHandler)) return $this->_handleErrors();
else return self::$_errorHandler($this->_errors);
}
return true;
}
private function _composite($params)
{
$not = $this->_not;
foreach ($params as $test) {
if (isset($test['negate']) && $test['negate']) {
$this->isNot();
} else {
$this->is();
}
$params = (empty($test['params'])) ? array() : $test['params'];
call_user_func_array(array($this, $test['test']), $params);
}
$this->_not = $not;
return $this;
}
public static function registerErrorHandler($fn)
{
if (is_callable($fn)) {
self::$_errorHandler = $fn;
} else {
throw new InvalidArgumentException("Invalid argument provided for schimile::registerErrorHandler() (Callable expetcer, "
. gettype($fn) . " received).");
}
}
/**
* Gets the currently loaded ruleset
* @return Array
*/
public static function getRuleset()
{
return self::$_ruleset;
}
public static function loadRuleset($ruleset)
{
if (is_object($ruleset)) {
self::$_ruleset[] = $ruleset;
end(self::$_ruleset[]);
return key(self::$_ruleset[]);
} elseif (is_array($ruleset)) {
self::$_ruleset = array_merge(self::$_ruleset, $ruleset);
} else {
throw new InvalidArgumentException("Invalid argument provided for schimile::loadRuleset() (Array or Object expected, "
. gettype($ruleset) . " received).");
}
}
private static function _init($type, $index = false)
{
$self = __CLASS__;
$self::$_currentInstance = new $self($type, $index);
}
private function _nextItem($type, $index = false)
{
$this->_inputType = $type;
$this->_queueIndex++;
$this->_updateIndex($index);
}
private function _updateIndex($index)
{
if ($index === false) {
$this->_currentIndex = $this->_nextIndex++;
} else {
$this->_currentIndex = $index;
}
}
public static function input()
{
self::_init("input");
return self::$_currentInstance;
}
public static function val($index = false)
{
self::_init("val", $index);
return self::$_currentInstance;
}
public function next($index = false)
{
$this->_updateIndex($index);
return $this;
}
public function arr()
{
$this->_pushToQueue(function($input) {
return is_array($input);
}, "{{name}} must be an array", "{{name}} can't be an array");
return $this;
}
public function top()
{
$this->_inputType = "input";
$this->_updateIndex(0);
return $this;
}
public function validPer($ruleset)
{
$this->_pushToQueue(function($input, $ruleset) {
$self = __CLASS__;
return $self::assert($ruleset, $input);
}, "null", "null", array($ruleset));
return $this;
}
public function is()
{
$this->_not = false;
return $this;
}
public function isNot()
{
$this->_not = true;
return $this;
}
public function noneOf()
{
$rulesets = func_get_args();
$this->_pushToQueue(function($input, $rulesets) {
$self = __CLASS__;
$status = false;
foreach ($rulesets as $ruleset) {
$status = ($status || $self::assert($ruleset, $input));
}
return !$status;
}, "null", "null", array($rulesets));
return $this;
}
public function allOf()
{
$rulesets = func_get_args();
$this->_pushToQueue(function($input, $rulesets) {
$self = __CLASS__;
$status = true;
foreach ($rulesets as $ruleset) {
$status = ($status && $self::assert($ruleset, $input));
}
return $status;
}, "null", "null", array($rulesets));
return $this;
}
public function oneOf()
{
$rulesets = func_get_args();
$this->_pushToQueue(function($input, $rulesets) {
$self = __CLASS__;
$status = false;
foreach ($rulesets as $ruleset) {
$status = ($status || $self::assert($ruleset, $input));
}
return $status;
}, "null", "null", array($rulesets));
return $this;
}
public function haltOnFail()
{
$this->_haltOnError = true;
return $this;
}
public function continueOnFail()
{
$this->_haltOnError = false;
return $this;
}
public function required()
{
if ($key = array_search($this->_currentIndex, $this->_optional) !== false) {
unset($this->_optional[$key]);
}
return $this;
}
public function optional()
{
$this->_optional[] = $this->_currentIndex;
return $this;
}
public function string()
{
//$this->_accept("string", $strict);
$this->_pushToQueue(function($input) {
return is_string($input);
}, "{{name}} must be a string", "{{name}} can't be a string");
return $this;
}
public function int()
{
$this->_pushToQueue(function($input) {
return is_int($input);
}, "{{name}} must be an integer", "{{name}} can't be an integer");
return $this;
}
public function atStart($param)
{
$this->_pushToQueue(function($input, $param) {
return strpos($input, $param) === 0;
}, "{{name}} must start with $param", "{{name}} can't start with $param", array($param));
return $this;
}
public function atEnd($param)
{
$this->_pushToQueue(function($input, $param) {
return substr($haystack, -strlen($needle)) === $needle;
}, "{{name}} must end with $param", "{{name}} can't end with $param", array($param));
return $this;
}
public function contains($param)
{
$this->_pushToQueue(function($input, $param) {
return strpos($input, $param) !== false;
}, "{{name}} must start with $param", "{{name}} can't start with $param", array($param));
return $this;
}
public function like($type, $keepType = true)
{
$this->_pushToQueue(function($input, $type) {
switch($type) {
case "float":
case "double":
$pattern = '/^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/';
break;
case "int":
case "integer":
$pattern = '/^[-+]?[0-9]+$/';
break;
default:
throw new InvalidInputTypeException("Invalid comparison type provided for schimile->like() operator");
break;
}
if (preg_match($pattern, $input)) {
if ($keepType) return true;
if ($type === "float") return (float) $input;
return (int) $input;
} else {
if ($keepType) return false;
throw new ValidationFailException();
}
}, "{{name}} must be a valid $type", "{{name}} can't be a $type", array($type));
return $this;
}
public function likeRegex($pattern)
{
$this->_pushToQueue(function($input, $pattern) {
return (bool) preg_match($pattern, $input);
}, "{{name}} must match regex $pattern", "{{name}} can't match regex $pattern", array($pattern));
return $this;
}
public function numeric()
{
$this->_pushToQueue(function($input) {
return is_numeric($input);
}, "{{name}} must be numeric", "{{name}} can't be numeric");
return $this;
}
public function alnum()
{
$this->_pushToQueue(function($input) {
return ctype_alnum($input);
}, "{{name}} must consist of only letters and numbers", "{{name}} can't consist of just letters or numbers");
return $this;
}
public function charList($characters)
{
$this->_pushToQueue(function($input, $characters) {
$incl = array();
$pattern = preg_replace_callback('/([a-z]\-[a-z])|([0-9]\-[0-9])|([A-Z]\-[A-Z])/', function($matches) use (&$incl) {
$incl = array_merge($incl, $matches);
return "";
}, $characters);
$pattern = preg_quote($pattern);
$pattern = $pattern . implode("", array_unique($incl));
$pattern = '/^['.$pattern.']+$/';
return (bool) preg_match($pattern, $input);
}, "{{name}} can only contain the characters $characters", "{{name}} can't consist entirely of the characters $characters", array($characters));
return $this;
}
public function lengthBetween($min = 0, $max = null)
{
$this->_pushToQueue(function($input, $min, $max) {
$resultmin = false;
$resultmax = false;
if (strlen($input) >= $min) $resultmin = true;
if ($max === null || strlen($input) <= $max) $resultmax = true;
return $resultmin && $resultmax;
}, "{{name}} must be between $min and $max characters", "{{name}} can't be between $min and $max characters", array($min, $max));
return $this;
}
public function email()
{
$this->_pushToQueue(function($input) {
return (bool) preg_match('/^.+@.+\..+$/', $input);
}, "{{name}} must be a valid e-mail address", "{{name}} can't be an e-mail address");
return $this;
}
public function equalTo($comparison, $strict = true)
{
$this->_pushToQueue(function($input, $comparison, $strict) {
if ($strict) {
return $input === $comparison;
} else {
return $input == $comparison;
}
}, "{{name}} must be equal to $comparison", "{{name}} can't be $comparison", array($comparison, $strict));
return $this;
}
public function entropyMin($value)
{
$this->_pushToQueue(function($input, $value) {
$h=0;
$size = strlen($string);
foreach (count_chars($string, 1) as $v) {
$p = $v/$size;
$h -= $p*log($p)/log(2);
}
return $h >= $value;
}, "{{name}} must be equal to $comparison", "{{name}} can't be $comparison", array($value));
return $this;
}
}
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
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).
Version System time (s) User time (s) Memory (MiB) 8.3.6 0.011 0.004 16.50 8.3.5 0.009 0.011 22.77 8.3.4 0.004 0.011 18.79 8.3.3 0.015 0.006 19.13 8.3.2 0.004 0.004 20.39 8.3.1 0.009 0.000 23.70 8.3.0 0.000 0.008 17.59 8.2.18 0.019 0.003 16.50 8.2.17 0.009 0.006 22.96 8.2.16 0.007 0.007 20.70 8.2.15 0.004 0.004 24.18 8.2.14 0.005 0.003 24.66 8.2.13 0.010 0.010 26.16 8.2.12 0.006 0.003 20.89 8.2.11 0.010 0.000 22.26 8.2.10 0.000 0.012 19.51 8.2.9 0.006 0.003 19.22 8.2.8 0.003 0.006 17.97 8.2.7 0.006 0.003 17.63 8.2.6 0.008 0.000 17.92 8.2.5 0.006 0.003 18.07 8.2.4 0.003 0.005 18.22 8.2.3 0.004 0.004 18.07 8.2.2 0.000 0.008 17.67 8.2.1 0.003 0.006 18.01 8.2.0 0.003 0.006 17.63 8.1.28 0.007 0.007 25.92 8.1.27 0.006 0.003 23.96 8.1.26 0.000 0.008 26.35 8.1.25 0.000 0.008 28.09 8.1.24 0.006 0.003 23.96 8.1.23 0.007 0.007 19.26 8.1.22 0.004 0.004 17.79 8.1.21 0.004 0.004 18.77 8.1.20 0.004 0.008 17.48 8.1.19 0.000 0.008 17.25 8.1.18 0.004 0.004 18.10 8.1.17 0.003 0.006 18.62 8.1.16 0.006 0.003 22.13 8.1.15 0.000 0.008 18.84 8.1.14 0.006 0.003 17.55 8.1.13 0.004 0.004 17.98 8.1.12 0.004 0.004 17.63 8.1.11 0.000 0.010 17.43 8.1.10 0.003 0.006 17.46 8.1.9 0.003 0.005 17.54 8.1.8 0.003 0.005 17.48 8.1.7 0.003 0.005 17.50 8.1.6 0.000 0.009 17.59 8.1.5 0.006 0.003 17.56 8.1.4 0.004 0.004 17.63 8.1.3 0.003 0.006 17.61 8.1.2 0.000 0.008 17.71 8.1.1 0.006 0.003 17.52 8.1.0 0.005 0.003 17.56 8.0.30 0.006 0.003 18.77 8.0.29 0.000 0.008 16.75 8.0.28 0.000 0.007 18.43 8.0.27 0.005 0.003 17.33 8.0.26 0.000 0.007 17.34 8.0.25 0.005 0.002 17.05 8.0.24 0.009 0.000 17.08 8.0.23 0.004 0.004 16.87 8.0.22 0.004 0.004 16.93 8.0.21 0.000 0.007 17.02 8.0.20 0.003 0.003 17.04 8.0.19 0.003 0.007 16.91 8.0.18 0.009 0.000 16.89 8.0.17 0.003 0.006 16.97 8.0.16 0.000 0.011 16.97 8.0.15 0.003 0.006 17.03 8.0.14 0.005 0.003 16.86 8.0.13 0.000 0.006 13.41 8.0.12 0.006 0.003 16.97 8.0.11 0.004 0.004 16.89 8.0.10 0.004 0.004 16.98 8.0.9 0.003 0.005 16.86 8.0.8 0.004 0.017 16.93 8.0.7 0.003 0.005 17.03 8.0.6 0.000 0.008 16.92 8.0.5 0.004 0.004 16.88 8.0.3 0.012 0.008 17.09 8.0.2 0.011 0.010 17.40 8.0.1 0.003 0.006 16.95 8.0.0 0.011 0.008 16.81 7.4.33 0.005 0.000 15.00 7.4.32 0.006 0.000 16.68 7.4.30 0.007 0.000 16.62 7.4.29 0.007 0.000 16.48 7.4.28 0.003 0.005 16.62 7.4.27 0.002 0.005 16.58 7.4.26 0.004 0.004 16.56 7.4.25 0.000 0.007 16.55 7.4.24 0.000 0.007 16.55 7.4.23 0.004 0.004 16.68 7.4.22 0.006 0.016 16.69 7.4.21 0.007 0.013 16.77 7.4.20 0.004 0.004 16.68 7.4.16 0.011 0.006 16.39 7.4.15 0.003 0.017 17.40 7.4.14 0.014 0.009 17.86 7.4.13 0.009 0.011 16.56 7.4.12 0.010 0.014 16.75 7.4.11 0.015 0.003 16.57 7.4.10 0.013 0.006 16.64 7.4.9 0.014 0.004 16.41 7.4.8 0.013 0.013 19.39 7.4.7 0.011 0.007 16.48 7.4.6 0.006 0.012 16.72 7.4.5 0.005 0.000 16.67 7.4.4 0.014 0.003 16.64 7.4.3 0.011 0.007 16.54 7.4.1 0.008 0.011 14.93 7.4.0 0.012 0.007 15.08 7.3.33 0.003 0.003 13.34 7.3.32 0.000 0.006 13.30 7.3.31 0.004 0.004 16.13 7.3.30 0.000 0.007 16.36 7.3.29 0.013 0.003 16.43 7.3.28 0.006 0.011 16.41 7.3.27 0.014 0.011 17.40 7.3.26 0.007 0.010 16.62 7.3.25 0.011 0.010 16.58 7.3.24 0.010 0.007 16.43 7.3.23 0.007 0.011 16.46 7.3.21 0.015 0.003 16.35 7.3.20 0.003 0.015 19.39 7.3.19 0.009 0.010 16.38 7.3.18 0.011 0.005 16.41 7.3.17 0.012 0.006 16.42 7.3.16 0.007 0.010 16.55 7.3.13 0.012 0.009 14.92 7.3.12 0.003 0.017 14.97 7.3.11 0.010 0.006 14.73 7.3.10 0.009 0.006 14.90 7.3.9 0.007 0.007 15.14 7.3.8 0.008 0.004 14.59 7.3.7 0.007 0.007 15.02 7.3.6 0.008 0.005 14.53 7.3.5 0.003 0.009 14.52 7.3.4 0.000 0.013 14.82 7.3.3 0.004 0.008 14.93 7.3.2 0.014 0.000 16.50 7.3.1 0.000 0.012 16.54 7.3.0 0.008 0.008 16.19 7.2.33 0.010 0.010 16.71 7.2.32 0.011 0.011 16.61 7.2.31 0.009 0.009 16.52 7.2.30 0.006 0.016 16.51 7.2.29 0.009 0.009 16.76 7.2.26 0.006 0.013 14.98 7.2.25 0.006 0.012 14.93 7.2.24 0.003 0.013 14.93 7.2.23 0.012 0.006 15.07 7.2.22 0.012 0.006 14.98 7.2.21 0.003 0.014 14.97 7.2.20 0.004 0.011 14.92 7.2.19 0.000 0.009 15.20 7.2.18 0.006 0.006 14.61 7.2.17 0.006 0.006 15.09 7.2.16 0.003 0.007 14.80 7.2.15 0.009 0.003 16.67 7.2.14 0.000 0.015 16.78 7.2.13 0.004 0.011 16.93 7.2.12 0.000 0.015 16.39 7.2.11 0.011 0.007 16.59 7.2.10 0.007 0.010 16.65 7.2.9 0.006 0.010 16.36 7.2.8 0.004 0.008 16.46 7.2.7 0.012 0.003 16.80 7.2.6 0.000 0.019 16.83 7.2.5 0.000 0.012 16.84 7.2.4 0.000 0.012 16.82 7.2.3 0.010 0.007 16.49 7.2.2 0.013 0.000 16.55 7.2.1 0.007 0.010 16.53 7.2.0 0.024 0.007 17.80 7.1.33 0.000 0.009 15.21 7.1.32 0.003 0.010 15.53 7.1.31 0.003 0.010 15.46 7.1.30 0.000 0.011 15.34 7.1.29 0.000 0.014 15.66 7.1.28 0.007 0.003 15.61 7.1.27 0.003 0.009 15.52 7.1.26 0.003 0.010 15.59 7.1.25 0.004 0.014 15.59 7.1.24 0.006 0.006 15.77 7.1.23 0.003 0.006 15.57 7.1.22 0.003 0.015 15.63 7.1.21 0.009 0.009 15.54 7.1.20 0.012 0.000 15.58 7.1.19 0.003 0.010 15.38 7.1.18 0.004 0.008 15.36 7.1.17 0.004 0.008 15.52 7.1.16 0.004 0.008 15.60 7.1.15 0.004 0.004 15.37 7.1.14 0.004 0.011 15.41 7.1.13 0.000 0.009 15.43 7.1.12 0.000 0.009 15.51 7.1.11 0.003 0.010 15.78 7.1.10 0.002 0.012 16.57 7.1.9 0.000 0.014 15.36 7.1.8 0.006 0.006 15.45 7.1.7 0.003 0.009 16.28 7.1.6 0.002 0.010 16.33 7.1.5 0.010 0.015 25.15 7.1.4 0.007 0.007 15.59 7.1.3 0.006 0.006 15.67 7.1.2 0.003 0.013 15.66 7.1.1 0.007 0.010 15.39 7.1.0 0.002 0.044 18.78 7.0.33 0.003 0.013 15.21 7.0.32 0.009 0.006 15.13 7.0.31 0.003 0.010 15.01 7.0.30 0.000 0.009 15.24 7.0.29 0.000 0.008 15.17 7.0.28 0.006 0.006 15.04 7.0.27 0.003 0.006 15.28 7.0.26 0.004 0.008 15.03 7.0.25 0.003 0.009 15.21 7.0.24 0.010 0.003 15.38 7.0.23 0.004 0.011 15.18 7.0.22 0.004 0.008 15.40 7.0.21 0.007 0.004 15.22 7.0.20 0.003 0.008 15.84 7.0.19 0.007 0.004 15.15 7.0.18 0.011 0.003 15.23 7.0.17 0.007 0.003 15.43 7.0.16 0.003 0.007 15.25 7.0.15 0.007 0.010 15.04 7.0.14 0.002 0.044 18.72 7.0.13 0.007 0.007 15.29 7.0.12 0.000 0.016 15.21 7.0.11 0.007 0.007 15.16 7.0.10 0.020 0.047 17.68 7.0.9 0.029 0.046 17.59 7.0.8 0.027 0.045 17.77 7.0.7 0.031 0.040 17.64 7.0.6 0.022 0.043 17.60 7.0.5 0.028 0.043 17.99 7.0.4 0.005 0.045 16.78 7.0.3 0.010 0.040 16.72 7.0.2 0.003 0.046 16.62 7.0.1 0.012 0.033 16.75 7.0.0 0.011 0.041 16.65 5.6.40 0.007 0.007 14.39 5.6.39 0.000 0.016 14.51 5.6.38 0.010 0.010 14.20 5.6.37 0.009 0.009 14.38 5.6.36 0.010 0.003 14.38 5.6.35 0.000 0.012 14.39 5.6.34 0.006 0.008 14.46 5.6.33 0.000 0.013 14.14 5.6.32 0.003 0.013 14.27 5.6.31 0.010 0.007 14.17 5.6.30 0.003 0.009 14.23 5.6.29 0.000 0.016 14.09 5.6.28 0.005 0.043 17.61 5.6.27 0.009 0.003 14.38 5.6.26 0.013 0.003 14.05 5.6.25 0.012 0.040 17.49 5.6.24 0.006 0.032 17.42 5.6.23 0.010 0.043 17.44 5.6.22 0.008 0.042 17.53 5.6.21 0.006 0.043 17.49 5.6.20 0.009 0.039 17.64 5.6.19 0.007 0.043 17.78 5.6.18 0.013 0.038 17.84 5.6.17 0.009 0.039 17.72 5.6.16 0.013 0.033 17.61 5.6.15 0.002 0.049 17.62 5.6.14 0.012 0.038 17.84 5.6.13 0.013 0.027 17.68 5.6.12 0.006 0.045 17.69 5.6.11 0.013 0.041 17.77 5.6.10 0.006 0.045 17.60 5.6.9 0.003 0.045 17.76 5.6.8 0.006 0.041 17.44 5.6.7 0.008 0.041 17.46 5.6.6 0.005 0.037 17.24 5.6.5 0.009 0.045 17.16 5.6.4 0.005 0.043 17.40 5.6.3 0.005 0.044 17.44 5.6.2 0.007 0.038 17.24 5.6.1 0.003 0.029 17.44 5.6.0 0.007 0.041 17.49 5.5.38 0.018 0.038 17.42 5.5.37 0.008 0.043 17.35 5.5.36 0.007 0.045 17.38 5.5.35 0.007 0.043 17.32 5.5.34 0.007 0.043 17.72 5.5.33 0.013 0.043 17.70 5.5.32 0.010 0.042 17.53 5.5.31 0.005 0.044 17.65 5.5.30 0.010 0.047 17.43 5.5.29 0.009 0.047 17.66 5.5.28 0.008 0.029 17.63 5.5.27 0.011 0.028 17.55 5.5.26 0.005 0.048 17.56 5.5.25 0.007 0.045 17.42 5.5.24 0.014 0.037 17.30 5.5.23 0.007 0.026 17.17 5.5.22 0.006 0.038 17.29 5.5.21 0.008 0.043 17.37 5.5.20 0.007 0.043 17.13 5.5.19 0.007 0.043 17.15 5.5.18 0.005 0.038 17.34 5.5.17 0.000 0.009 13.96 5.5.16 0.005 0.043 17.28 5.5.15 0.002 0.049 17.13 5.5.14 0.007 0.042 17.10 5.5.13 0.011 0.042 17.34 5.5.12 0.010 0.040 17.28 5.5.11 0.011 0.035 17.30 5.5.10 0.010 0.040 17.12 5.5.9 0.008 0.039 17.21 5.5.8 0.006 0.044 17.12 5.5.7 0.006 0.041 17.18 5.5.6 0.006 0.040 17.05 5.5.5 0.005 0.038 17.21 5.5.4 0.007 0.044 17.13 5.5.3 0.008 0.039 16.97 5.5.2 0.007 0.042 17.21 5.5.1 0.008 0.043 17.16 5.5.0 0.003 0.046 16.91 5.4.45 0.009 0.040 15.30 5.4.44 0.002 0.024 15.16 5.4.43 0.002 0.038 15.11 5.4.42 0.003 0.038 15.31 5.4.41 0.000 0.033 14.99 5.4.40 0.004 0.046 15.10 5.4.39 0.007 0.046 14.93 5.4.38 0.002 0.045 14.83 5.4.37 0.006 0.040 14.89 5.4.36 0.006 0.031 15.00 5.4.35 0.009 0.023 14.90 5.4.34 0.006 0.046 14.86 5.4.33 0.003 0.007 10.91 5.4.32 0.003 0.030 14.90 5.4.31 0.004 0.041 15.14 5.4.30 0.005 0.040 15.07 5.4.29 0.007 0.026 14.91 5.4.28 0.008 0.040 15.10 5.4.27 0.007 0.025 14.90 5.4.26 0.002 0.044 15.08 5.4.25 0.005 0.043 14.88 5.4.24 0.003 0.040 14.90 5.4.23 0.003 0.042 15.08 5.4.22 0.014 0.035 14.94 5.4.21 0.003 0.041 15.08 5.4.20 0.003 0.041 14.87 5.4.19 0.002 0.040 14.95 5.4.18 0.004 0.045 14.99 5.4.17 0.006 0.029 15.10 5.4.16 0.000 0.043 14.91 5.4.15 0.005 0.037 14.89 5.4.14 0.005 0.040 13.66 5.4.13 0.008 0.023 13.83 5.4.12 0.005 0.042 13.69 5.4.11 0.009 0.039 13.75 5.4.10 0.007 0.026 13.68 5.4.9 0.002 0.045 13.73 5.4.8 0.004 0.039 13.65 5.4.7 0.003 0.022 13.75 5.4.6 0.007 0.018 13.63 5.4.5 0.005 0.023 13.79 5.4.4 0.010 0.035 13.76 5.4.3 0.005 0.041 13.67 5.4.2 0.003 0.044 13.71 5.4.1 0.009 0.036 13.71 5.4.0 0.005 0.041 13.42
preferences:dark mode live preview
118.88 ms | 401 KiB | 5 Q