csscrush_file( string $file [, array [$options](#api--options) ] )
+
+
+***************
+
+## csscrush_tag()
+
+Process CSS file and return an html `link` tag with populated href.
+
+csscrush_tag( string $file [, array [$options](#api--options) [, array $tag\_attributes ]] )
+
+
+***************
+
+## csscrush_inline()
+
+Process CSS file and return CSS as text wrapped in html `style` tags.
+
+csscrush_inline( string $file [, array [$options](#api--options) [, array $tag\_attributes ]] )
+
+
+***************
+
+## csscrush_string()
+
+Compile a raw string of CSS string and return it.
+
+csscrush_string( string $string [, array [$options](#api--options) ] )
+
+
+***************
+
+## csscrush_get()
+
+Retrieve a config setting or option default.
+
+`csscrush_get( string $object_name, string $property )`
+
+### Parameters
+
+ * `$object_name` Name of object you want to inspect: 'config' or 'options'.
+ * `$property`
+
+
+***************
+
+## csscrush_set()
+
+Set a config setting or option default.
+
+`csscrush_set( string $object_name, mixed $settings )`
+
+### Parameters
+
+ * `$object_name` Name of object you want to modify: 'config' or 'options'.
+ * `$settings` Associative array of keys and values to set, or callable which argument is the object specified in `$object_name`.
+
+
+***************
+
+## csscrush_plugin()
+
+Register a plugin.
+
+`csscrush_plugin( string $name, callable $callback )`
+
+
+***************
+
+## csscrush_stat()
+
+Get compilation stats from the most recent compiled file.
+
+`csscrush_stat()`
diff --git a/include/thirdparty/css-crush/docs/api/options.md b/include/thirdparty/css-crush/docs/api/options.md
new file mode 100644
index 0000000..1aa3fb2
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/api/options.md
@@ -0,0 +1,103 @@
+
+
+Option + | Values (default in bold) + | Description + |
---|---|---|
minify + | true | false | Array + | Enable or disable minification. Optionally specify an array of advanced minification parameters. Currently the only advanced option is 'colors', which will compress all color values in any notation. + |
formatter + | block | single-line | padded + | Set the formatting mode. Overrides minify option if both are set. + |
newlines + | use-platform | windows/win | unix + | Set the output style of newlines + |
boilerplate + | true | false | Path + | Prepend a boilerplate to the output file + |
versioning + | true | false + | Append a timestamped querystring to the output filename + |
vars + | Array + | An associative array of CSS variables to be applied at runtime. These will override variables declared globally or in the CSS. + |
cache + | true | false + | Turn caching on or off. + |
output_dir + | Path + | Specify an output directory for compiled files. Defaults to the same directory as the host file. + |
output_file + | Output filename + | Specify an output filename (suffix is added). + |
asset_dir + | Path + | Directory for SVG and image files generated by plugins (defaults to the main file output directory). + |
stat_dump + | false | true | Path + | Save compile stats and variables to a file in json format. + |
vendor_target + | "all" | "moz", "webkit", ... | Array + | Limit aliasing to a specific vendor, or an array of vendors. + |
rewrite_import_urls + | true | false | "absolute" + | Rewrite relative URLs inside inlined imported files. + |
import_paths + | Array + | Additional paths to search when resolving relative import URLs. + |
plugins + | Array + | An array of plugin names to enable. + |
source_map + | true | false + | Output a source map (compliant with the Source Map v3 proposal). + |
context + | Path + | Context for importing resources from relative urls (Only applies to `csscrush_string()` and command line utility). + |
doc_root + | Path + | Specify an alternative server document root for situations where the CSS is being served behind an alias or url rewritten path. + |
@fragment
directive – work in a similar way to [mixins](#core--mixins), except that they work at block level:
+
+```crush
+@fragment input-placeholder {
+ #(1)::-webkit-input-placeholder { color: #(0); }
+ #(1):-moz-placeholder { color: #(0); }
+ #(1)::placeholder { color: #(0); }
+ #(1).placeholder-state { color: #(0); }
+}
+
+@fragment input-placeholder(#777, textarea);
+```
+
+```css
+textarea::-webkit-input-placeholder { color: #777; }
+textarea:-moz-placeholder { color: #777; }
+textarea::placeholder { color: #777; }
+textarea.placeholder-state { color: #777; }
+```
diff --git a/include/thirdparty/css-crush/docs/core/functions/a-adjust.md b/include/thirdparty/css-crush/docs/core/functions/a-adjust.md
new file mode 100644
index 0000000..59d2c93
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/a-adjust.md
@@ -0,0 +1,26 @@
+
+
+Manipulate the opacity (alpha channel) of a color value.
+
+a-adjust( *color*, *offset* )
+
+## Parameters
+
+* *`color`* Any valid CSS color value
+* *`offset`* The percentage to offset the color opacity
+
+## Returns
+
+The modified color value
+
+
+## Examples
+
+```css
+/* Reduce color opacity by 10% */
+color: a-adjust( rgb(50,50,0) -10 );
+```
diff --git a/include/thirdparty/css-crush/docs/core/functions/data-uri.md b/include/thirdparty/css-crush/docs/core/functions/data-uri.md
new file mode 100644
index 0000000..32b0459
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/data-uri.md
@@ -0,0 +1,33 @@
+
+
+Create a data-uri.
+
+data-uri( *url* )
+
+## Parameters
+
+* *`url`* URL of an asset
+
+`url` cannot be external, and must not be written with an http protocol prefix.
+
+The following file extensions are supported: jpg, jpeg, gif, png, svg, svgz, ttf, woff
+
+
+## Returns
+
+The created data-uri as a string inside a CSS url().
+
+
+## Examples
+
+```crush
+background: silver data-uri(../images/stripe.png);
+```
+
+```css
+background: silver url(data:h-adjust( *color*, *offset* )
+
+## Parameters
+
+* *`color`* Any valid CSS color value
+* *`offset`* The percentage to offset the color hue (percent mark optional)
+
+## Returns
+
+The modified color value.
+
+## Examples
+
+```css
+color: h-adjust( deepskyblue -10 );
+```
diff --git a/include/thirdparty/css-crush/docs/core/functions/hsl-adjust.md b/include/thirdparty/css-crush/docs/core/functions/hsl-adjust.md
new file mode 100644
index 0000000..bdee0fd
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/hsl-adjust.md
@@ -0,0 +1,27 @@
+
+
+Manipulate the hue, saturation and lightness of a color value
+
+hsl-adjust( *color*, *hue-offset*, *saturation-offset*, *lightness-offset* )
+
+## Parameters
+
+* *`color`* Any valid CSS color value
+* *`hue-offset`* The percentage to offset the color hue
+* *`saturation-offset`* The percentage to offset the color saturation
+* *`lightness-offset`* The percentage to offset the color lightness
+
+## Returns
+
+The modified color value
+
+## Examples
+
+```css
+/* Lighten and increase saturation */
+color: hsl-adjust( red 0 5 5 );
+```
diff --git a/include/thirdparty/css-crush/docs/core/functions/hsla-adjust.md b/include/thirdparty/css-crush/docs/core/functions/hsla-adjust.md
new file mode 100644
index 0000000..cc05b4b
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/hsla-adjust.md
@@ -0,0 +1,27 @@
+
+
+Manipulate the hue, saturation, lightness and opacity of a color value.
+
+hsla-adjust( *color*, *hue-offset*, *saturation-offset*, *lightness-offset*, *alpha-offset* )
+
+## Parameters
+
+* *`color`* Any valid CSS color value
+* *`hue-offset`* The percentage to offset the color hue
+* *`saturation-offset`* The percentage to offset the color saturation
+* *`lightness-offset`* The percentage to offset the color lightness
+* *`alpha-offset`* The percentage to offset the color opacity
+
+## Returns
+
+The modified color value.
+
+## Examples
+
+```css
+color: hsla-adjust( #f00 0 5 5 -10 );
+```
\ No newline at end of file
diff --git a/include/thirdparty/css-crush/docs/core/functions/l-adjust.md b/include/thirdparty/css-crush/docs/core/functions/l-adjust.md
new file mode 100644
index 0000000..28ac701
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/l-adjust.md
@@ -0,0 +1,24 @@
+
+
+Adjust the lightness of a color value.
+
+l-adjust( *color*, *offset* )
+
+## Parameters
+
+* *`color`* Any valid CSS color value
+* *`offset`* The percentage to offset the color hue (percent mark optional)
+
+## Returns
+
+The modified color value.
+
+## Examples
+
+```css
+color: l-adjust( deepskyblue 10 );
+```
diff --git a/include/thirdparty/css-crush/docs/core/functions/math.md b/include/thirdparty/css-crush/docs/core/functions/math.md
new file mode 100644
index 0000000..2d65b40
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/math.md
@@ -0,0 +1,19 @@
+
+
+Evaluate a raw mathematical expression.
+
+math( *expression* [, *unit*] )
+
+## Examples
+
+```crush
+font-size: math( 12 / 16, em );
+```
+
+```css
+font-size: 0.75em;
+```
diff --git a/include/thirdparty/css-crush/docs/core/functions/query.md b/include/thirdparty/css-crush/docs/core/functions/query.md
new file mode 100644
index 0000000..c9d5240
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/query.md
@@ -0,0 +1,54 @@
+
+
+Copy a value from another rule.
+
+query( *target* [, *property-name* = default] [, *fallback*] )
+
+## Parameters
+
+* *`target`* A rule selector, an abstract rule name or context keyword: `previous`, `next` (also `parent` and `top` within nested structures)
+* *`property-name`* The CSS property name to copy, or just `default` to pass over. Defaults to the calling property
+* *`fallback`* A CSS value to use if the target property does not exist
+
+
+## Returns
+
+The referenced property value, or the fallback if it has not been set.
+
+
+## Examples
+
+
+```css
+.foo {
+ width: 40em;
+ height: 100em;
+}
+
+.bar {
+ width: query( .foo ); /* 40em */
+ margin-top: query( .foo, height ); /* 100em */
+ margin-bottom: query( .foo, default, 3em ); /* 3em */
+}
+```
+
+Using context keywords:
+
+```css
+.foo {
+ width: 40em;
+ .bar {
+ width: 30em;
+ .baz: {
+ width: query( parent ); /* 30em */
+ .qux {
+ width: query( top ); /* 40em */
+ }
+ }
+ }
+}
+```
diff --git a/include/thirdparty/css-crush/docs/core/functions/s-adjust.md b/include/thirdparty/css-crush/docs/core/functions/s-adjust.md
new file mode 100644
index 0000000..8d2cce1
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/s-adjust.md
@@ -0,0 +1,25 @@
+
+
+Adjust the saturation of a color value.
+
+s-adjust( *color*, *offset* )
+
+## Parameters
+
+* *`color`* Any valid CSS color value
+* *`offset`* The percentage to offset the color hue (percent mark optional)
+
+## Returns
+
+The modified color value.
+
+## Examples
+
+```css
+/* Desaturate */
+color: s-adjust( deepskyblue -100 );
+```
diff --git a/include/thirdparty/css-crush/docs/core/functions/this.md b/include/thirdparty/css-crush/docs/core/functions/this.md
new file mode 100644
index 0000000..12029b6
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/functions/this.md
@@ -0,0 +1,39 @@
+
+
+Reference another property value from the same containing block.
+
+Restricted to referencing properties that don't already reference other properties.
+
+this( *property-name*, *fallback* )
+
+## Parameters
+
+* *`property-name`* Property name
+* *`fallback`* A CSS value
+
+## Returns
+
+The referenced property value, or the fallback if it has not been set.
+
+## Examples
+
+```css
+.foo {
+ width: this( height );
+ height: 100em;
+}
+```
+
+********
+
+```css
+/* The following both fail because they create circular references. */
+.bar {
+ height: this( width );
+ width: this( height );
+}
+```
diff --git a/include/thirdparty/css-crush/docs/core/inheritance.md b/include/thirdparty/css-crush/docs/core/inheritance.md
new file mode 100644
index 0000000..4473813
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/inheritance.md
@@ -0,0 +1,127 @@
+
+
+By using the `@extend` directive and passing it a named ruleset or selector from any other rule you can share styles more effectively across a stylesheet.
+
+[Abstract rules](#core--abstract) can be used if you just need to extend a generic set of declarations.
+
+```crush
+.negative-text {
+ overflow: hidden;
+ text-indent: -9999px;
+}
+
+.sidebar-headline {
+ @extend .negative-text;
+ background: url( headline.png ) no-repeat;
+}
+```
+
+```css
+.negative-text,
+.sidebar-headline {
+ overflow: hidden;
+ text-indent: -9999px;
+}
+
+.sidebar-headline {
+ background: url( headline.png ) no-repeat;
+}
+```
+
+Inheritance is recursive:
+
+```crush
+.one { color: pink; }
+.two { @extend .one; }
+.three { @extend .two; }
+.four { @extend .three; }
+```
+
+```css
+.one, .two, .three, .four { color: pink; }
+```
+
+## Referencing by name
+
+If you want to reference a rule without being concerned about later changes to the identifying selector use the `@name` directive:
+
+```crush
+.foo123 {
+ @name foo;
+ text-decoration: underline;
+}
+
+.bar {
+ @include foo;
+}
+.baz {
+ @extend foo;
+}
+```
+
+
+## Extending with pseudo classes/elements
+
+`@extend` arguments can adopt pseudo classes/elements by appending an exclamation mark:
+
+```crush
+.link-base {
+ color: #bada55;
+ text-decoration: underline;
+}
+.link-base:hover,
+.link-base:focus {
+ text-decoration: none;
+}
+
+.link-footer {
+ @extend .link-base, .link-base:hover!, .link-base:focus!;
+ color: blue;
+}
+```
+
+```css
+.link-base,
+.link-footer {
+ color: #bada55;
+ text-decoration: underline;
+}
+
+.link-base:hover,
+.link-base:focus,
+.link-footer:hover,
+.link-footer:focus {
+ text-decoration: none;
+}
+
+.link-footer {
+ color: blue;
+}
+```
+
+The same outcome can also be achieved with an [Abstract rule](#core--abstract) wrapper to simplify repeated use:
+
+```crush
+.link-base {
+ color: #bada55;
+ text-decoration: underline;
+}
+.link-base:hover,
+.link-base:focus {
+ text-decoration: none;
+}
+
+@abstract link-base {
+ @extend .link-base, .link-base:hover!, .link-base:focus!;
+}
+
+.link-footer {
+ @extend link-base;
+ color: blue;
+}
+```
+
diff --git a/include/thirdparty/css-crush/docs/core/loop.md b/include/thirdparty/css-crush/docs/core/loop.md
new file mode 100644
index 0000000..66ae6f7
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/loop.md
@@ -0,0 +1,41 @@
+
+
+For...in loops with lists and generator functions.
+
+```crush
+@for fruit in apple, orange, pear {
+ .#(fruit) {
+ background-image: url("images/#(fruit).jpg");
+ }
+}
+```
+
+```css
+.apple { background-image: url(images/apple.jpg); }
+.orange { background-image: url(images/orange.jpg); }
+.pear { background-image: url(images/pear.jpg); }
+```
+
+```crush
+@for base in range(2, 24) {
+ @for i in range(1, #(base)) {
+ .grid-#(i)-of-#(base) {
+ width: math(#(i) / #(base) * 100, %);
+ }
+ }
+}
+```
+
+```css
+.grid-1-of-2 { width: 50%; }
+.grid-2-of-2 { width: 100%; }
+/*
+ Intermediate steps ommited.
+*/
+.grid-23-of-24 { width: 95.83333%; }
+.grid-24-of-24 { width: 100%; }
+```
diff --git a/include/thirdparty/css-crush/docs/core/mixins.md b/include/thirdparty/css-crush/docs/core/mixins.md
new file mode 100644
index 0000000..1348ff8
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/mixins.md
@@ -0,0 +1,95 @@
+
+
+Mixins make reusing small snippets of CSS much simpler. You define them with the `@mixin` directive.
+
+Positional arguments via the argument function `#()` extend the capability of mixins for repurposing in different contexts.
+
+```crush
+@mixin display-font {
+ font-family: "Arial Black", sans-serif;
+ font-size: #(0);
+ letter-spacing: #(1);
+}
+
+/* Another mixin with default arguments */
+@mixin blue-theme {
+ color: #(0 navy);
+ background-image: url("images/#(1 cross-hatch).png");
+}
+
+/* Applying the mixins */
+.foo {
+ @include display-font(100%, .1em), blue-theme;
+}
+```
+
+```css
+.foo {
+ font-family: "Arial Black", sans-serif;
+ font-size: 100%;
+ letter-spacing: .1em;
+ color: navy;
+ background-image: url("images/cross-hatch.png");
+}
+```
+
+## Skipping arguments
+
+Mixin arguments can be skipped by using the **default** keyword:
+
+```crush
+@mixin display-font {
+ font-size: #(0 100%);
+ letter-spacing: #(1);
+}
+
+/* Applying the mixin skipping the first argument so the
+ default value is used instead */
+#foo {
+ @include display-font(default, .3em);
+}
+```
+
+Sometimes you may need to use the same positional argument more than once. In this case the default value only needs to be specified once:
+
+```crush
+@mixin square {
+ width: #(0 10px);
+ height: #(0);
+}
+
+.foo {
+ @include square;
+}
+```
+
+```css
+#foo {
+ width: 10px;
+ height: 10px;
+}
+```
+
+
+## Mixing-in from other sources
+
+Normal rules and [abstract rules](#core--abstract) can also be used as static mixins without arguments:
+
+```crush
+@abstract negative-text {
+ text-indent: -9999px;
+ overflow: hidden;
+}
+
+#main-content .theme-border {
+ border: 1px solid maroon;
+}
+
+.foo {
+ @include negative-text, #main-content .theme-border;
+}
+```
diff --git a/include/thirdparty/css-crush/docs/core/nesting.md b/include/thirdparty/css-crush/docs/core/nesting.md
new file mode 100644
index 0000000..999be4f
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/nesting.md
@@ -0,0 +1,49 @@
+
+
+Rules can be nested to avoid repetitive typing when scoping to a common parent selector.
+
+```crush
+.homepage {
+ color: #333;
+ background: white;
+ .content {
+ p {
+ font-size: 110%;
+ }
+ }
+}
+```
+
+```css
+.homepage {
+ color: #333;
+ background: white;
+}
+.homepage .content p {
+ font-size: 110%;
+}
+```
+
+## Parent referencing
+
+You can use the parent reference symbol `&` for placing the parent selector explicitly.
+
+```crush
+.homepage {
+ .no-js & {
+ p {
+ font-size: 110%;
+ }
+ }
+}
+```
+
+```css
+.no-js .homepage p {
+ font-size: 110%;
+}
+```
diff --git a/include/thirdparty/css-crush/docs/core/selector-aliases.md b/include/thirdparty/css-crush/docs/core/selector-aliases.md
new file mode 100644
index 0000000..ea9296d
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/selector-aliases.md
@@ -0,0 +1,80 @@
+
+
+Selector aliases can be useful for grouping together common selector chains for reuse.
+
+They're defined with the `@selector` directive, and can be used anywhere you might use a pseudo class.
+
+
+```crush
+@selector heading :any(h1, h2, h3, h4, h5, h6);
+@selector radio input[type="radio"];
+@selector hocus :any(:hover, :focus);
+
+/* Selector aliases with arguments */
+@selector class-prefix :any([class^="#(0)"], [class*=" #(0)"]);
+@selector col :class-prefix(-col);
+
+.sidebar :heading {
+ color: honeydew;
+}
+
+:radio {
+ margin-right: 4px;
+}
+
+:col {
+ float: left;
+}
+
+p a:hocus {
+ text-decoration: none;
+}
+```
+
+```css
+.sidebar h1, .sidebar h2,
+.sidebar h3, .sidebar h4,
+.sidebar h5, .sidebar h6 {
+ color: honeydew;
+}
+
+input[type="radio"] {
+ margin-right: 4px;
+}
+
+[class^="col-"],
+[class*=" col-"] {
+ border: 1px solid rgba(0,0,0,.5);
+}
+
+p a:hover,
+p a:focus {
+ text-decoration: none;
+}
+```
+
+## Selector splatting
+
+Selector splats are a special kind of selector alias that expand using passed arguments.
+
+```crush
+@selector-splat input input[type="#(text)"];
+
+form :input(time, text, url, email, number) {
+ border: 1px solid;
+}
+```
+
+```css
+form input[type="time"],
+form input[type="text"],
+form input[type="url"],
+form input[type="email"],
+form input[type="number"] {
+ border: 1px solid;
+}
+```
diff --git a/include/thirdparty/css-crush/docs/core/selector-grouping.md b/include/thirdparty/css-crush/docs/core/selector-grouping.md
new file mode 100644
index 0000000..0cafa1f
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/selector-grouping.md
@@ -0,0 +1,22 @@
+
+
+Selector grouping with the `:any` pseudo class (modelled after CSS4 :matches) simplifies the creation of complex selector chains.
+
+```crush
+:any( .sidebar, .block ) a:any( :hover, :focus ) {
+ color: lemonchiffon;
+}
+```
+
+```css
+.block a:hover,
+.block a:focus,
+.sidebar a:hover,
+.sidebar a:focus {
+ color: lemonchiffon;
+}
+```
diff --git a/include/thirdparty/css-crush/docs/core/variables.md b/include/thirdparty/css-crush/docs/core/variables.md
new file mode 100644
index 0000000..117f53f
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/core/variables.md
@@ -0,0 +1,62 @@
+
+
+Declare variables in your CSS with a `@set` directive and use them with the `$()` function.
+
+Variables can also be injected at runtime with the [vars option](#api--options).
+
+
+```crush
+/* Defining variables */
+@set {
+ dark: #333;
+ light: #F4F2E2;
+ smaller-screen: screen and (max-width: 800px);
+}
+
+/* Using variables */
+@media $(smaller-screen) {
+ ul, p {
+ color: $(dark);
+ /* Using a fallback value with an undefined variable */
+ background-color: $(accent-color, #ff0);
+ }
+}
+```
+
+*******
+
+```css
+/* Interpolation */
+.username::before {
+ content: "$(greeting)";
+}
+```
+
+## Conditionals
+
+Sections of CSS can be included and excluded on the basis of variable existence with the `@ifset` directive:
+
+```crush
+@set foo #f00;
+@set bar true;
+
+@ifset foo {
+ p {
+ color: $(foo);
+ }
+}
+
+p {
+ font-size: 12px;
+ @ifset not foo {
+ line-height: 1.5;
+ }
+ @ifset bar(true) {
+ margin-bottom: 5px;
+ }
+}
+```
diff --git a/include/thirdparty/css-crush/docs/getting-started/js.md b/include/thirdparty/css-crush/docs/getting-started/js.md
new file mode 100644
index 0000000..605727f
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/getting-started/js.md
@@ -0,0 +1,26 @@
+
+
+This preprocessor is written in PHP, so as prerequisite you will need to have PHP installed on your system to use the JS api.
+
+```shell
+npm install csscrush
+```
+
+All methods can take the standard options (camelCase) as the second argument.
+
+```php
+const csscrush = require('csscrush');
+
+// Compile. Returns promise.
+csscrush.file('./styles.css', {sourceMap: true});
+
+// Compile string of CSS. Returns promise.
+csscrush.string('* {box-sizing: border-box;}');
+
+// Compile and watch file. Returns event emitter (triggers 'data' on compile).
+csscrush.watch('./styles.css');
+```
diff --git a/include/thirdparty/css-crush/docs/getting-started/php.md b/include/thirdparty/css-crush/docs/getting-started/php.md
new file mode 100644
index 0000000..1c6f836
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/getting-started/php.md
@@ -0,0 +1,17 @@
+
+
+If you're using [Composer](http://getcomposer.org) you can use Crush in your project with the following line in your terminal:
+
+```shell
+composer require css-crush/css-crush
+```
+
+If you're not using Composer yet just download the library ([zip](http://github.com/peteboere/css-crush/zipball/master) or [tar](http://github.com/peteboere/css-crush/tarball/master)) into a convenient location and require the bootstrap file:
+
+```php
+
+```
diff --git a/include/thirdparty/css-crush/docs/plugins/aria.md b/include/thirdparty/css-crush/docs/plugins/aria.md
new file mode 100644
index 0000000..c00608d
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/plugins/aria.md
@@ -0,0 +1,21 @@
+
+Pseudo classes for working with ARIA roles, states and properties.
+
+ * [ARIA roles spec](http://www.w3.org/TR/wai-aria/roles)
+ * [ARIA states and properties spec](http://www.w3.org/TR/wai-aria/states_and_properties)
+
+````crush
+:role(tablist) {...}
+:aria-expanded {...}
+:aria-expanded(false) {...}
+:aria-label {...}
+:aria-label(foobarbaz) {...}
+````
+
+````css
+[role="tablist"] {...}
+[aria-expanded="true"] {...}
+[aria-expanded="false"] {...}
+[aria-label] {...}
+[aria-label="foobarbaz"] {...}
+````
diff --git a/include/thirdparty/css-crush/docs/plugins/canvas.md b/include/thirdparty/css-crush/docs/plugins/canvas.md
new file mode 100644
index 0000000..df6994d
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/plugins/canvas.md
@@ -0,0 +1,55 @@
+
+Bitmap image generator.
+
+Requires the GD image library bundled with PHP.
+
+```crush
+/* Create square semi-opaque png. */
+@canvas foo {
+ width: 50;
+ height: 50;
+ fill: rgba(255, 0, 0, .5);
+}
+
+body {
+ background: white canvas(foo);
+}
+```
+
+*****
+
+```crush
+/* White to transparent east facing gradient with 10px
+ margin and background fill. */
+@canvas horz-gradient {
+ width: #(0);
+ height: 150;
+ fill: canvas-linear-gradient(to right, #(1 white), #(2 rgba(255,255,255,0)));
+ background-fill: powderblue;
+ margin: 10;
+}
+
+/* Rectangle 300x150. */
+body {
+ background: canvas(horz-gradient, 300);
+}
+/* Flipped gradient, using canvas-data() to generate a data URI. */
+.bar {
+ background: canvas-data(horz-gradient, 100, rgba(255,255,255,0), white);
+}
+```
+
+*****
+
+```crush
+/* Google logo resized to 400px width and given a sepia effect. */
+@canvas sepia {
+ src: url(http://www.google.com/images/logo.png);
+ width: 400;
+ canvas-filter: greyscale() colorize(45, 45, 0);
+}
+
+.bar {
+ background: canvas(sepia);
+}
+```
diff --git a/include/thirdparty/css-crush/docs/plugins/ease.md b/include/thirdparty/css-crush/docs/plugins/ease.md
new file mode 100644
index 0000000..37ce5f9
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/plugins/ease.md
@@ -0,0 +1,37 @@
+
+Expanded easing keywords for transitions.
+
+* ease-in-out-back
+* ease-in-out-circ
+* ease-in-out-expo
+* ease-in-out-sine
+* ease-in-out-quint
+* ease-in-out-quart
+* ease-in-out-cubic
+* ease-in-out-quad
+* ease-out-back
+* ease-out-circ
+* ease-out-expo
+* ease-out-sine
+* ease-out-quint
+* ease-out-quart
+* ease-out-cubic
+* ease-out-quad
+* ease-in-back
+* ease-in-circ
+* ease-in-expo
+* ease-in-sine
+* ease-in-quint
+* ease-in-quart
+* ease-in-cubic
+* ease-in-quad
+
+See [easing demos](http://easings.net) for live examples.
+
+```crush
+transition: .2s ease-in-quad;
+```
+
+```css
+transition: .2s cubic-bezier(.550,.085,.680,.530);
+```
diff --git a/include/thirdparty/css-crush/docs/plugins/forms.md b/include/thirdparty/css-crush/docs/plugins/forms.md
new file mode 100644
index 0000000..3f4fcbc
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/plugins/forms.md
@@ -0,0 +1,16 @@
+
+Pseudo classes for working with forms.
+
+```crush
+:input(date, search, email) {...}
+:checkbox {...}
+:radio {...}
+:text {...}
+```
+
+```css
+input[type="date"], input[type="search"], input[type="email"] {...}
+input[type="checkbox"] {...}
+input[type="radio"] {...}
+input[type="text"] {...}
+```
diff --git a/include/thirdparty/css-crush/docs/plugins/hocus-pocus.md b/include/thirdparty/css-crush/docs/plugins/hocus-pocus.md
new file mode 100644
index 0000000..b8f3efa
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/plugins/hocus-pocus.md
@@ -0,0 +1,12 @@
+
+Composite :hover/:focus/:active pseudo classes.
+
+```crush
+a:hocus { color: red; }
+a:pocus { color: red; }
+```
+
+```css
+a:hover, a:focus { color: red; }
+a:hover, a:focus, a:active { color: red; }
+```
diff --git a/include/thirdparty/css-crush/docs/plugins/property-sorter.md b/include/thirdparty/css-crush/docs/plugins/property-sorter.md
new file mode 100644
index 0000000..cd17817
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/plugins/property-sorter.md
@@ -0,0 +1,21 @@
+
+Property sorting.
+
+Examples use the predefined property sorting table. To define a custom sorting order pass an array to `csscrush_set_property_sort_order()`
+
+
+```crush
+color: red;
+background: #000;
+opacity: .5;
+display: block;
+position: absolute;
+```
+
+```css
+position: absolute;
+display: block;
+opacity: .5;
+color: red;
+background: #000;
+```
diff --git a/include/thirdparty/css-crush/docs/plugins/svg-gradients.md b/include/thirdparty/css-crush/docs/plugins/svg-gradients.md
new file mode 100644
index 0000000..66ff410
--- /dev/null
+++ b/include/thirdparty/css-crush/docs/plugins/svg-gradients.md
@@ -0,0 +1,48 @@
+
+Functions for creating SVG gradients with a CSS gradient like syntax.
+
+Primarily useful for supporting Internet Explorer 9.
+
+## svg-linear-gradent()
+
+Syntax is the same as [linear-gradient()](http://dev.w3.org/csswg/css3-images/#linear-gradient)
+
+```syntax
+svg-linear-gradent( [ ' . htmlspecialchars($item) . ''; + } + echo implode('
' . htmlspecialchars($code) . ''; + // echo $test; + + // Either write to a file. + if ($fn_name === 'svg' && $process->ioContext === 'file') { + + $flattened_svg = implode("\n", $svg); + + // Create fingerprint for the created file. + $fingerprint = substr(md5($flattened_svg), 0, 7); + $generated_filename = "svg-$name-$fingerprint.svg"; + + if (! empty($process->options->asset_dir)) { + $generated_filepath = $process->options->asset_dir . '/' . $generated_filename; + $generated_url = Util::getLinkBetweenPaths( + $process->output->dir, $process->options->asset_dir) . $generated_filename; + } + else { + $generated_filepath = $process->output->dir . '/' . $generated_filename; + $generated_url = $generated_filename; + } + + Util::filePutContents($generated_filepath, $flattened_svg, __METHOD__); + + $url = new Url($generated_url); + $url->noRewrite = true; + } + // Or create data uri. + else { + $url = new Url('data:image/svg+xml;base64,' . base64_encode(implode('', $svg))); + } + + // Cache the output URL. + $label = $process->tokens->add($url); + $process->misc->svg_cache[$cache_key] = $label; + + return $label; +} + + +/* + Circle callback. +*/ +function svg_circle($element) { + + // Ensure required attributes have defaults set. + $element->data += [ + 'diameter' => 50, + ]; + + list($margin_top, $margin_right, $margin_bottom, $margin_left) = $element->data['margin']; + + $element->attrs['r'] = + $radius = svg_ifset($element->attrs['r'], $element->data['diameter'] / 2); + + $diameter = $radius * 2; + + $element->attrs['cx'] = svg_ifset($element->attrs['cx'], $margin_left + $radius); + $element->attrs['cy'] = svg_ifset($element->attrs['cy'], $margin_top + $radius); + + $element->svg_attrs['width'] = $margin_left + $diameter + $margin_right; + $element->svg_attrs['height'] = $margin_top + $diameter + $margin_bottom; +} + +/* + Rect callback. +*/ +function svg_rect($element) { + + $element->data += [ + 'width' => 50, + 'height' => 50, + ]; + + list($margin_top, $margin_right, $margin_bottom, $margin_left) = $element->data['margin']; + + $element->attrs['x'] = $margin_left; + $element->attrs['y'] = $margin_top; + $element->attrs['width'] = $element->data['width']; + $element->attrs['height'] = $element->data['height']; + + if (isset($element->data['corner-radius'])) { + $args = svg_parselist($element->data['corner-radius']); + $element->attrs['rx'] = isset($args[0]) ? $args[0] : 0; + $element->attrs['ry'] = isset($args[1]) ? $args[1] : $args[0]; + } + + $element->svg_attrs['width'] = $margin_left + $element->data['width'] + $margin_right; + $element->svg_attrs['height'] = $margin_top + $element->data['height'] + $margin_bottom; +} + +/* + Ellipse callback. +*/ +function svg_ellipse($element) { + + $element->data += [ + 'diameter' => '100 50', + ]; + + if (! isset($element->attrs['rx']) && ! isset($element->attrs['ry'])) { + $diameter = svg_parselist($element->data['diameter']); + $element->attrs['rx'] = $diameter[0] / 2; + $element->attrs['ry'] = isset($diameter[1]) ? $diameter[1] / 2 : $diameter[0] / 2; + } + + list($margin_top, $margin_right, $margin_bottom, $margin_left) = $element->data['margin']; + + $element->attrs['cx'] = $margin_left + $element->attrs['rx']; + $element->attrs['cy'] = $margin_top + $element->attrs['ry']; + + $element->svg_attrs['width'] = $margin_left + ($element->attrs['rx'] * 2) + $margin_right; + $element->svg_attrs['height'] = $margin_top + ($element->attrs['ry'] * 2) + $margin_bottom; +} + +/* + Path callback. +*/ +function svg_path($element) { + + // Ensure minimum required attributes have defaults set. + $element->data += [ + 'd' => 'M 10,10 l 10,0 l 0,10 l 10,0 l 0,10', + ]; + + // Unclosed paths have implicit fill. + $element->styles += [ + 'fill' => 'none', + ]; +} + +/* + Polyline callback. +*/ +function svg_polyline($element) { + + // Ensure required attributes have defaults set. + $element->data += [ + 'points' => '20,20 40,20 40,40 60,40 60,60', + ]; + + // Polylines have implicit fill. + $element->styles += [ + 'fill' => 'none', + ]; +} + +/* + Line callback. +*/ +function svg_line($element) { + + // Set a default stroke. + $element->styles += [ + 'stroke' => '#000', + ]; + + $element->attrs += [ + 'x1' => 0, + 'x2' => 0, + 'y1' => 0, + 'y2' => 0, + ]; +} + +/* + Polygon callback. +*/ +function svg_polygon($element) { + + if (! isset($element->attrs['points'])) { + + // Switch to path element. + $element->tag = 'path'; + + $element->data += [ + 'sides' => 3, + 'diameter' => 100, + ]; + + list($margin_top, $margin_right, $margin_bottom, $margin_left) = $element->data['margin']; + + $diameter = svg_parselist($element->data['diameter']); + $diameter = $diameter[0]; + $radius = $diameter / 2; + + $cx = $radius + $margin_left; + $cy = $radius + $margin_top; + $sides = $element->data['sides']; + + $element->attrs['d'] = svg_starpath($cx, $cy, $sides, $radius); + + $element->svg_attrs['width'] = $diameter + $margin_left + $margin_right; + $element->svg_attrs['height'] = $diameter + $margin_top + $margin_bottom; + } +} + +/* + Star callback. +*/ +function svg_star($element) { + + // Minimum required attributes have defaults. + $element->data += [ + 'star-points' => 4, + 'diameter' => '50 30', + 'twist' => 0, + ]; + + list($margin_top, $margin_right, $margin_bottom, $margin_left) = $element->data['margin']; + + $diameter = svg_parselist($element->data['diameter']); + if (! isset($diameter[1])) { + $diameter[1] = ($diameter[0] / 2); + } + $outer_r = $diameter[0] / 2; + $inner_r = $diameter[1] / 2; + + $cx = $outer_r + $margin_left; + $cy = $outer_r + $margin_top; + $points = $element->data['star-points']; + $twist = $element->data['twist'] * 10; + + $element->attrs['d'] = svg_starpath($cx, $cy, $points, $outer_r, $inner_r, $twist); + + $element->svg_attrs['width'] = $margin_left + ($outer_r * 2) + $margin_left; + $element->svg_attrs['height'] = $margin_top + ($outer_r * 2) + $margin_bottom; +} + +/* + Text callback. + Warning: Very limited for svg-as-image situations. +*/ +function svg_text($element) { + + // Minimum required attributes have defaults. + $element->data += [ + 'x' => 0, + 'y' => 0, + 'width' => 100, + 'height' => 100, + 'text' => '', + ]; + + $text = Crush::$process->tokens->restore($element->data['text'], 's', true); + + // Remove open and close quotes. + $text = substr($text, 1, strlen($text) - 2); + + // Convert CSS unicode sequences to XML unicode. + $text = preg_replace('~\\\\([[:xdigit:]]{2,6})~', '$1;', $text); + + // Remove excape slashes and encode meta entities. + $text = htmlentities(stripslashes($text), ENT_QUOTES, 'UTF-8', false); + $element->data['text'] = $text; + + $element->svg_attrs['width'] = $element->data['width']; + $element->svg_attrs['height'] = $element->data['height']; +} + + + +/* + Star/polygon path builder. + + Adapted from http://svg-whiz.com/svg/StarMaker.svg by Doug Schepers. +*/ +function svg_starpath($cx, $cy, $points, $outer_r, $inner_r = null, $twist = 0, $orient = 'point') { + + $d = []; + + // Enforce minimum number of points. + $points = max(3, $points); + + for ($s = 0; $points >= $s; $s++) { + + // Outer angle. + $outer_angle = 2.0 * M_PI * ($s / $points); + + if ($orient === 'point') { + $outer_angle -= (M_PI / 2); + } + elseif ($orient === 'edge') { + $outer_angle = ($outer_angle + (M_PI / $points)) - (M_PI / 2); + } + + // Outer point based on outer angle. + $x = ( $outer_r * cos($outer_angle) ) + $cx; + $y = ( $outer_r * sin($outer_angle) ) + $cy; + + if ($points != $s) { + $d[] = "$x $y"; + } + + // If star shape is required need inner angles too. + if ($inner_r != null && $points != $s) { + + $inner_angle = (2 * M_PI * ($s / $points)) + (M_PI / $points); + + if ($orient === 'point') { + $inner_angle -= (M_PI / 2); + } + $inner_angle += $twist; + + $ix = ( $inner_r * cos($inner_angle) ) + $cx; + $iy = ( $inner_r * sin($inner_angle) ) + $cy; + + $d[] = "$ix $iy"; + } + } + + return 'M' . implode('L', $d) . 'Z'; +} + +function svg_apply_filters($element) { + + if (isset($element->data['drop-shadow'])) { + + $parts = svg_parselist($element->data['drop-shadow'], false); + + list($ds_x, $ds_y, $ds_strength, $ds_color) = $parts += [ + 2, // x offset. + 2, // y offset. + 2, // strength. + 'black', // color. + ]; + + // Opacity. + $drop_shadow_opacity = null; + if ($color_components = Color::colorSplit($ds_color)) { + list($ds_color, $drop_shadow_opacity) = $color_components; + } + + $filter = '