'); define('X', "\x1A"); function n($s) { return str_replace(["\r\n", "\r"], "\n", $s); } function t($a, $b) { if ($a && strpos($a, $b) === 0 && substr($a, -strlen($b)) === $b) { return substr(substr($a, strlen($b)), 0, -strlen($b)); } return $a; } function fn_minify($pattern, $input) { return preg_split('#(' . implode('|', $pattern) . ')#', $input, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); } function fn_minify_css($input, $comment = 2, $quote = 2) { if (!is_string($input) || !$input = n(trim($input))) return $input; $output = $prev = ""; foreach (fn_minify([MINIFY_COMMENT_CSS, MINIFY_STRING], $input) as $part) { if (trim($part) === "") continue; if ($comment !== 1 && strpos($part, '/*') === 0 && substr($part, -2) === '*/') { if ( $comment === 2 && ( // Detect special comment(s) from the third character. It should be a `!` or `*` → `/*! keep */` or `/** keep */` strpos('*!', $part[2]) !== false || // Detect license comment(s) from the content. It should contains character(s) like `@license` stripos($part, '@licence') !== false || // noun stripos($part, '@license') !== false || // verb stripos($part, '@preserve') !== false ) ) { $output .= $part; } continue; } if ($part[0] === '"' && substr($part, -1) === '"' || $part[0] === "'" && substr($part, -1) === "'") { // Remove quote(s) where possible … $q = $part[0]; if ( $quote !== 1 && ( // substr($prev, -4) === 'url(' && preg_match('#\burl\($#', $prev) || // substr($prev, -1) === '=' && preg_match('#^' . $q . '[a-zA-Z_][\w-]*?' . $q . '$#', $part) ) ) { $part = t($part, $q); // trim quote(s) } $output .= $part; } else { $output .= fn_minify_css_union($part); } $prev = $part; } return trim($output); } function fn_minify_css_union($input) { if (stripos($input, 'calc(') !== false) { // Keep important white–space(s) in `calc()` $input = preg_replace_callback('#\b(calc\()\s*(.*?)\s*\)#i', function ($m) { return $m[1] . preg_replace('#\s+#', X, $m[2]) . ')'; }, $input); } $input = preg_replace([ // Fix case for `#foo[bar="baz"]`, `#foo*` and `#foo:first-child` [^1] '#(?<=[\w])\s+(\*|\[|:[\w-]+)#', // Fix case for `[bar="baz"].foo`, `*.foo`, `:nth-child(2).foo` and `@media(foo: bar)and(baz: qux)` [^2] '#([*\]\)])\s+(?=[\w\#.])#', '#\b\s+\(#', '#\)\s+\b#', // Minify HEX color code … [^3] '#\#([a-f\d])\1([a-f\d])\2([a-f\d])\3\b#i', // Remove white–space(s) around punctuation(s) [^4] '#\s*([~!@*\(\)+=\{\}\[\]:;,>\/])\s*#', // Replace zero unit(s) with `0` [^5] '#\b(?