summaryrefslogtreecommitdiffstats
path: root/library/vendor/dompdf/vendor/sabberworm
diff options
context:
space:
mode:
Diffstat (limited to 'library/vendor/dompdf/vendor/sabberworm')
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/CHANGELOG.md241
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/LICENSE21
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/README.md632
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/composer.json69
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/AtRuleBlockList.php83
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/CSSBlockList.php143
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/CSSList.php479
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/Document.php172
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/KeyFrame.php104
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Comment/Comment.php71
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Comment/Commentable.php25
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/OutputFormat.php334
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/OutputFormatter.php231
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parser.php60
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/OutputException.php18
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/ParserState.php516
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/SourceException.php32
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/UnexpectedEOFException.php12
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/UnexpectedTokenException.php51
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/AtRule.php34
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/CSSNamespace.php154
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Charset.php129
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Import.php137
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/KeyframeSelector.php23
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Selector.php138
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Renderable.php21
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Rule/Rule.php392
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/AtRuleSet.php73
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/DeclarationBlock.php831
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/RuleSet.php326
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Settings.php89
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CSSFunction.php73
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CSSString.php105
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CalcFunction.php89
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CalcRuleValueList.php24
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Color.php166
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/LineName.php65
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/PrimitiveValue.php14
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/RuleValueList.php15
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Size.php209
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/URL.php82
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Value.php198
-rw-r--r--library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/ValueList.php100
43 files changed, 6781 insertions, 0 deletions
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/CHANGELOG.md b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/CHANGELOG.md
new file mode 100644
index 0000000..a23fd0e
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/CHANGELOG.md
@@ -0,0 +1,241 @@
+# Revision History
+
+## 8.4.0
+
+### Features
+
+* Support for PHP 8.x
+* PHPDoc annotations
+* Allow usage of CSS variables inside color functions (by parsing them as regular functions)
+* Use PSR-12 code style
+* *No deprecations*
+
+### Bugfixes
+
+* Improved handling of whitespace in `calc()`
+* Fix parsing units whose prefix is also a valid unit, like `vmin`
+* Allow passing an object to `CSSList#replace`
+* Fix PHP 7.3 warnings
+* Correctly parse keyframes with `%`
+* Don’t convert large numbers to scientific notation
+* Allow a file to end after an `@import`
+* Preserve case of CSS variables as specced
+* Allow identifiers to use escapes the same way as strings
+* No longer use `eval` for the comparison in `getSelectorsBySpecificity`, in case it gets passed untrusted input (CVE-2020-13756). Also fixed in 8.3.1, 8.2.1, 8.1.1, 8.0.1, 7.0.4, 6.0.2, 5.2.1, 5.1.3, 5.0.9, 4.0.1, 3.0.1, 2.0.1, 1.0.1.
+* Prevent an infinite loop when parsing invalid grid line names
+* Remove invalid unit `vm`
+* Retain rule order after expanding shorthands
+
+### Backwards-incompatible changes
+
+* PHP ≥ 5.6 is now required
+* HHVM compatibility target dropped
+
+## 8.3.0 (2019-02-22)
+
+* Refactor parsing logic to mostly reside in the class files whose data structure is to be parsed (this should eventually allow us to unit-test specific parts of the parsing logic individually).
+* Fix error in parsing `calc` expessions when the first operand is a negative number, thanks to @raxbg.
+* Support parsing CSS4 colors in hex notation with alpha values, thanks to @raxbg.
+* Swallow more errors in lenient mode, thanks to @raxbg.
+* Allow specifying arbitrary strings to output before and after declaration blocks, thanks to @westonruter.
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 8.2.0 (2018-07-13)
+
+* Support parsing `calc()`, thanks to @raxbg.
+* Support parsing grid-lines, again thanks to @raxbg.
+* Support parsing legacy IE filters (`progid:`) in lenient mode, thanks to @FMCorz
+* Performance improvements parsing large files, again thanks to @FMCorz
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 8.1.0 (2016-07-19)
+
+* Comments are no longer silently ignored but stored with the object with which they appear (no render support, though). Thanks to @FMCorz.
+* The IE hacks using `\0` and `\9` can now be parsed (and rendered) in lenient mode. Thanks (again) to @FMCorz.
+* Media queries with or without spaces before the query are parsed. Still no *real* parsing support, though. Sorry…
+* PHPUnit is now listed as a dev-dependency in composer.json.
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 8.0.0 (2016-06-30)
+
+* Store source CSS line numbers in tokens and parsing exceptions.
+* *No deprecations*
+
+### Backwards-incompatible changes
+
+* Unrecoverable parser errors throw an exception of type `Sabberworm\CSS\Parsing\SourceException` instead of `\Exception`.
+
+## 7.0.3 (2016-04-27)
+
+* Fixed parsing empty CSS when multibyte is off
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 7.0.2 (2016-02-11)
+
+* 150 time performance boost thanks to @[ossinkine](https://github.com/ossinkine)
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 7.0.1 (2015-12-25)
+
+* No more suppressed `E_NOTICE`
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 7.0.0 (2015-08-24)
+
+* Compatibility with PHP 7. Well timed, eh?
+* *No deprecations*
+
+### Backwards-incompatible changes
+
+* The `Sabberworm\CSS\Value\String` class has been renamed to `Sabberworm\CSS\Value\CSSString`.
+
+## 6.0.1 (2015-08-24)
+
+* Remove some declarations in interfaces incompatible with PHP 5.3 (< 5.3.9)
+* *No deprecations*
+
+## 6.0.0 (2014-07-03)
+
+* Format output using Sabberworm\CSS\OutputFormat
+* *No backwards-incompatible changes*
+
+### Deprecations
+
+* The parse() method replaces __toString with an optional argument (instance of the OutputFormat class)
+
+## 5.2.0 (2014-06-30)
+
+* Support removing a selector from a declaration block using `$oBlock->removeSelector($mSelector)`
+* Introduce a specialized exception (Sabberworm\CSS\Parsing\OuputException) for exceptions during output rendering
+
+* *No deprecations*
+
+#### Backwards-incompatible changes
+
+* Outputting a declaration block that has no selectors throws an OuputException instead of outputting an invalid ` {…}` into the CSS document.
+
+## 5.1.2 (2013-10-30)
+
+* Remove the use of consumeUntil in comment parsing. This makes it possible to parse comments such as `/** Perfectly valid **/`
+* Add fr relative size unit
+* Fix some issues with HHVM
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.1.1 (2013-10-28)
+
+* Updated CHANGELOG.md to reflect changes since 5.0.4
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.1.0 (2013-10-24)
+
+* Performance enhancements by Michael M Slusarz
+* More rescue entry points for lenient parsing (unexpected tokens between declaration blocks and unclosed comments)
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.8 (2013-08-15)
+
+* Make default settings’ multibyte parsing option dependent on whether or not the mbstring extension is actually installed.
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.7 (2013-08-04)
+
+* Fix broken decimal point output optimization
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.6 (2013-05-31)
+
+* Fix broken unit test
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.5 (2013-04-17)
+
+* Initial support for lenient parsing (setting this parser option will catch some exceptions internally and recover the parser’s state as neatly as possible).
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.4 (2013-03-21)
+
+* Don’t output floats with locale-aware separator chars
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.3 (2013-03-21)
+
+* More size units recognized
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.2 (2013-03-21)
+
+* CHANGELOG.md file added to distribution
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.1 (2013-03-20)
+
+* Internal cleanup
+* *No backwards-incompatible changes*
+* *No deprecations*
+
+## 5.0.0 (2013-03-20)
+
+* Correctly parse all known CSS 3 units (including Hz and kHz).
+* Output RGB colors in short (#aaa or #ababab) notation
+* Be case-insensitive when parsing identifiers.
+* *No deprecations*
+
+### Backwards-incompatible changes
+
+* `Sabberworm\CSS\Value\Color`’s `__toString` method overrides `CSSList`’s to maybe return something other than `type(value, …)` (see above).
+
+## 4.0.0 (2013-03-19)
+
+* Support for more @-rules
+* Generic interface `Sabberworm\CSS\Property\AtRule`, implemented by all @-rule classes
+* *No deprecations*
+
+### Backwards-incompatible changes
+
+* `Sabberworm\CSS\RuleSet\AtRule` renamed to `Sabberworm\CSS\RuleSet\AtRuleSet`
+* `Sabberworm\CSS\CSSList\MediaQuery` renamed to `Sabberworm\CSS\RuleSet\CSSList\AtRuleBlockList` with differing semantics and API (which also works for other block-list-based @-rules like `@supports`).
+
+## 3.0.0 (2013-03-06)
+
+* Support for lenient parsing (on by default)
+* *No deprecations*
+
+### Backwards-incompatible changes
+
+* All properties (like whether or not to use `mb_`-functions, which default charset to use and – new – whether or not to be forgiving when parsing) are now encapsulated in an instance of `Sabberworm\CSS\Settings` which can be passed as the second argument to `Sabberworm\CSS\Parser->__construct()`.
+* Specifying a charset as the second argument to `Sabberworm\CSS\Parser->__construct()` is no longer supported. Use `Sabberworm\CSS\Settings::create()->withDefaultCharset('some-charset')` instead.
+* Setting `Sabberworm\CSS\Parser->bUseMbFunctions` has no effect. Use `Sabberworm\CSS\Settings::create()->withMultibyteSupport(true/false)` instead.
+* `Sabberworm\CSS\Parser->parse()` may throw a `Sabberworm\CSS\Parsing\UnexpectedTokenException` when in strict parsing mode.
+
+## 2.0.0 (2013-01-29)
+
+* Allow multiple rules of the same type per rule set
+
+### Backwards-incompatible changes
+
+* `Sabberworm\CSS\RuleSet->getRules()` returns an index-based array instead of an associative array. Use `Sabberworm\CSS\RuleSet->getRulesAssoc()` (which eliminates duplicate rules and lets the later rule of the same name win).
+* `Sabberworm\CSS\RuleSet->removeRule()` works as it did before except when passed an instance of `Sabberworm\CSS\Rule\Rule`, in which case it would only remove the exact rule given instead of all the rules of the same type. To get the old behaviour, use `Sabberworm\CSS\RuleSet->removeRule($oRule->getRule()`;
+
+## 1.0
+
+Initial release of a stable public API.
+
+## 0.9
+
+Last version not to use PSR-0 project organization semantics.
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/LICENSE b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/LICENSE
new file mode 100644
index 0000000..686a4e3
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2011 Raphael Schweikert, https://www.sabberworm.com/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/README.md b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/README.md
new file mode 100644
index 0000000..66fb1c6
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/README.md
@@ -0,0 +1,632 @@
+# PHP CSS Parser
+
+[![Build Status](https://github.com/sabberworm/PHP-CSS-Parser/workflows/CI/badge.svg?branch=master)](https://github.com/sabberworm/PHP-CSS-Parser/actions/)
+
+A Parser for CSS Files written in PHP. Allows extraction of CSS files into a data structure, manipulation of said structure and output as (optimized) CSS.
+
+## Usage
+
+### Installation using Composer
+
+```bash
+composer require sabberworm/php-css-parser
+```
+
+### Extraction
+
+To use the CSS Parser, create a new instance. The constructor takes the following form:
+
+```php
+new \Sabberworm\CSS\Parser($css);
+```
+
+To read a file, for example, you’d do the following:
+
+```php
+$parser = new \Sabberworm\CSS\Parser(file_get_contents('somefile.css'));
+$cssDocument = $parser->parse();
+```
+
+The resulting CSS document structure can be manipulated prior to being output.
+
+### Options
+
+#### Charset
+
+The charset option is used only if no `@charset` declaration is found in the CSS file. UTF-8 is the default, so you won’t have to create a settings object at all if you don’t intend to change that.
+
+```php
+$settings = \Sabberworm\CSS\Settings::create()
+ ->withDefaultCharset('windows-1252');
+$parser = new \Sabberworm\CSS\Parser($css, $settings);
+```
+
+#### Strict parsing
+
+To have the parser choke on invalid rules, supply a thusly configured `\Sabberworm\CSS\Settings` object:
+
+```php
+$parser = new \Sabberworm\CSS\Parser(
+ file_get_contents('somefile.css'),
+ \Sabberworm\CSS\Settings::create()->beStrict()
+);
+```
+
+#### Disable multibyte functions
+
+To achieve faster parsing, you can choose to have PHP-CSS-Parser use regular string functions instead of `mb_*` functions. This should work fine in most cases, even for UTF-8 files, as all the multibyte characters are in string literals. Still it’s not recommended using this with input you have no control over as it’s not thoroughly covered by test cases.
+
+```php
+$settings = \Sabberworm\CSS\Settings::create()->withMultibyteSupport(false);
+$parser = new \Sabberworm\CSS\Parser($css, $settings);
+```
+
+### Manipulation
+
+The resulting data structure consists mainly of five basic types: `CSSList`, `RuleSet`, `Rule`, `Selector` and `Value`. There are two additional types used: `Import` and `Charset`, which you won’t use often.
+
+#### CSSList
+
+`CSSList` represents a generic CSS container, most likely containing declaration blocks (rule sets with a selector), but it may also contain at-rules, charset declarations, etc. `CSSList` has the following concrete subtypes:
+
+* `Document` – representing the root of a CSS file.
+* `MediaQuery` – represents a subsection of a `CSSList` that only applies to an output device matching the contained media query.
+
+To access the items stored in a `CSSList` – like the document you got back when calling `$parser->parse()` –, use `getContents()`, then iterate over that collection and use instanceof to check whether you’re dealing with another `CSSList`, a `RuleSet`, a `Import` or a `Charset`.
+
+To append a new item (selector, media query, etc.) to an existing `CSSList`, construct it using the constructor for this class and use the `append($oItem)` method.
+
+#### RuleSet
+
+`RuleSet` is a container for individual rules. The most common form of a rule set is one constrained by a selector. The following concrete subtypes exist:
+
+* `AtRuleSet` – for generic at-rules which do not match the ones specifically mentioned like `@import`, `@charset` or `@media`. A common example for this is `@font-face`.
+* `DeclarationBlock` – a `RuleSet` constrained by a `Selector`; contains an array of selector objects (comma-separated in the CSS) as well as the rules to be applied to the matching elements.
+
+Note: A `CSSList` can contain other `CSSList`s (and `Import`s as well as a `Charset`), while a `RuleSet` can only contain `Rule`s.
+
+If you want to manipulate a `RuleSet`, use the methods `addRule(Rule $rule)`, `getRules()` and `removeRule($rule)` (which accepts either a `Rule` instance or a rule name; optionally suffixed by a dash to remove all related rules).
+
+#### Rule
+
+`Rule`s just have a key (the rule) and a value. These values are all instances of a `Value`.
+
+#### Value
+
+`Value` is an abstract class that only defines the `render` method. The concrete subclasses for atomic value types are:
+
+* `Size` – consists of a numeric `size` value and a unit.
+* `Color` – colors can be input in the form #rrggbb, #rgb or schema(val1, val2, …) but are always stored as an array of ('s' => val1, 'c' => val2, 'h' => val3, …) and output in the second form.
+* `CSSString` – this is just a wrapper for quoted strings to distinguish them from keywords; always output with double quotes.
+* `URL` – URLs in CSS; always output in URL("") notation.
+
+There is another abstract subclass of `Value`, `ValueList`. A `ValueList` represents a lists of `Value`s, separated by some separation character (mostly `,`, whitespace, or `/`). There are two types of `ValueList`s:
+
+* `RuleValueList` – The default type, used to represent all multi-valued rules like `font: bold 12px/3 Helvetica, Verdana, sans-serif;` (where the value would be a whitespace-separated list of the primitive value `bold`, a slash-separated list and a comma-separated list).
+* `CSSFunction` – A special kind of value that also contains a function name and where the values are the function’s arguments. Also handles equals-sign-separated argument lists like `filter: alpha(opacity=90);`.
+
+#### Convenience methods
+
+There are a few convenience methods on Document to ease finding, manipulating and deleting rules:
+
+* `getAllDeclarationBlocks()` – does what it says; no matter how deeply nested your selectors are. Aliased as `getAllSelectors()`.
+* `getAllRuleSets()` – does what it says; no matter how deeply nested your rule sets are.
+* `getAllValues()` – finds all `Value` objects inside `Rule`s.
+
+## To-Do
+
+* More convenience methods (like `selectorsWithElement($sId/Class/TagName)`, `attributesOfType($type)`, `removeAttributesOfType($type)`)
+* Real multibyte support. Currently, only multibyte charsets whose first 255 code points take up only one byte and are identical with ASCII are supported (yes, UTF-8 fits this description).
+* Named color support (using `Color` instead of an anonymous string literal)
+
+## Use cases
+
+### Use `Parser` to prepend an ID to all selectors
+
+```php
+$myId = "#my_id";
+$parser = new \Sabberworm\CSS\Parser($css);
+$cssDocument = $parser->parse();
+foreach ($cssDocument->getAllDeclarationBlocks() as $block) {
+ foreach ($block->getSelectors() as $selector) {
+ // Loop over all selector parts (the comma-separated strings in a
+ // selector) and prepend the ID.
+ $selector->setSelector($myId.' '.$selector->getSelector());
+ }
+}
+```
+
+### Shrink all absolute sizes to half
+
+```php
+$parser = new \Sabberworm\CSS\Parser($css);
+$cssDocument = $parser->parse();
+foreach ($cssDocument->getAllValues() as $value) {
+ if ($value instanceof CSSSize && !$value->isRelative()) {
+ $value->setSize($value->getSize() / 2);
+ }
+}
+```
+
+### Remove unwanted rules
+
+```php
+$parser = new \Sabberworm\CSS\Parser($css);
+$cssDocument = $parser->parse();
+foreach($cssDocument->getAllRuleSets() as $oRuleSet) {
+ // Note that the added dash will make this remove all rules starting with
+ // `font-` (like `font-size`, `font-weight`, etc.) as well as a potential
+ // `font-rule`.
+ $oRuleSet->removeRule('font-');
+ $oRuleSet->removeRule('cursor');
+}
+```
+
+### Output
+
+To output the entire CSS document into a variable, just use `->render()`:
+
+```php
+$parser = new \Sabberworm\CSS\Parser(file_get_contents('somefile.css'));
+$cssDocument = $parser->parse();
+print $cssDocument->render();
+```
+
+If you want to format the output, pass an instance of type `\Sabberworm\CSS\OutputFormat`:
+
+```php
+$format = \Sabberworm\CSS\OutputFormat::create()
+ ->indentWithSpaces(4)->setSpaceBetweenRules("\n");
+print $cssDocument->render($format);
+```
+
+Or use one of the predefined formats:
+
+```php
+print $cssDocument->render(Sabberworm\CSS\OutputFormat::createPretty());
+print $cssDocument->render(Sabberworm\CSS\OutputFormat::createCompact());
+```
+
+To see what you can do with output formatting, look at the tests in `tests/OutputFormatTest.php`.
+
+## Examples
+
+### Example 1 (At-Rules)
+
+#### Input
+
+```css
+@charset "utf-8";
+
+@font-face {
+ font-family: "CrassRoots";
+ src: url("../media/cr.ttf");
+}
+
+html, body {
+ font-size: 1.6em;
+}
+
+@keyframes mymove {
+ from { top: 0px; }
+ to { top: 200px; }
+}
+
+```
+
+#### Structure (`var_dump()`)
+
+```php
+class Sabberworm\CSS\CSSList\Document#4 (2) {
+ protected $aContents =>
+ array(4) {
+ [0] =>
+ class Sabberworm\CSS\Property\Charset#6 (2) {
+ private $sCharset =>
+ class Sabberworm\CSS\Value\CSSString#5 (2) {
+ private $sString =>
+ string(5) "utf-8"
+ protected $iLineNo =>
+ int(1)
+ }
+ protected $iLineNo =>
+ int(1)
+ }
+ [1] =>
+ class Sabberworm\CSS\RuleSet\AtRuleSet#7 (4) {
+ private $sType =>
+ string(9) "font-face"
+ private $sArgs =>
+ string(0) ""
+ private $aRules =>
+ array(2) {
+ 'font-family' =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Rule\Rule#8 (4) {
+ private $sRule =>
+ string(11) "font-family"
+ private $mValue =>
+ class Sabberworm\CSS\Value\CSSString#9 (2) {
+ private $sString =>
+ string(10) "CrassRoots"
+ protected $iLineNo =>
+ int(4)
+ }
+ private $bIsImportant =>
+ bool(false)
+ protected $iLineNo =>
+ int(4)
+ }
+ }
+ 'src' =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Rule\Rule#10 (4) {
+ private $sRule =>
+ string(3) "src"
+ private $mValue =>
+ class Sabberworm\CSS\Value\URL#11 (2) {
+ private $oURL =>
+ class Sabberworm\CSS\Value\CSSString#12 (2) {
+ private $sString =>
+ string(15) "../media/cr.ttf"
+ protected $iLineNo =>
+ int(5)
+ }
+ protected $iLineNo =>
+ int(5)
+ }
+ private $bIsImportant =>
+ bool(false)
+ protected $iLineNo =>
+ int(5)
+ }
+ }
+ }
+ protected $iLineNo =>
+ int(3)
+ }
+ [2] =>
+ class Sabberworm\CSS\RuleSet\DeclarationBlock#13 (3) {
+ private $aSelectors =>
+ array(2) {
+ [0] =>
+ class Sabberworm\CSS\Property\Selector#14 (2) {
+ private $sSelector =>
+ string(4) "html"
+ private $iSpecificity =>
+ NULL
+ }
+ [1] =>
+ class Sabberworm\CSS\Property\Selector#15 (2) {
+ private $sSelector =>
+ string(4) "body"
+ private $iSpecificity =>
+ NULL
+ }
+ }
+ private $aRules =>
+ array(1) {
+ 'font-size' =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Rule\Rule#16 (4) {
+ private $sRule =>
+ string(9) "font-size"
+ private $mValue =>
+ class Sabberworm\CSS\Value\Size#17 (4) {
+ private $fSize =>
+ double(1.6)
+ private $sUnit =>
+ string(2) "em"
+ private $bIsColorComponent =>
+ bool(false)
+ protected $iLineNo =>
+ int(9)
+ }
+ private $bIsImportant =>
+ bool(false)
+ protected $iLineNo =>
+ int(9)
+ }
+ }
+ }
+ protected $iLineNo =>
+ int(8)
+ }
+ [3] =>
+ class Sabberworm\CSS\CSSList\KeyFrame#18 (4) {
+ private $vendorKeyFrame =>
+ string(9) "keyframes"
+ private $animationName =>
+ string(6) "mymove"
+ protected $aContents =>
+ array(2) {
+ [0] =>
+ class Sabberworm\CSS\RuleSet\DeclarationBlock#19 (3) {
+ private $aSelectors =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Property\Selector#20 (2) {
+ private $sSelector =>
+ string(4) "from"
+ private $iSpecificity =>
+ NULL
+ }
+ }
+ private $aRules =>
+ array(1) {
+ 'top' =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Rule\Rule#21 (4) {
+ private $sRule =>
+ string(3) "top"
+ private $mValue =>
+ class Sabberworm\CSS\Value\Size#22 (4) {
+ private $fSize =>
+ double(0)
+ private $sUnit =>
+ string(2) "px"
+ private $bIsColorComponent =>
+ bool(false)
+ protected $iLineNo =>
+ int(13)
+ }
+ private $bIsImportant =>
+ bool(false)
+ protected $iLineNo =>
+ int(13)
+ }
+ }
+ }
+ protected $iLineNo =>
+ int(13)
+ }
+ [1] =>
+ class Sabberworm\CSS\RuleSet\DeclarationBlock#23 (3) {
+ private $aSelectors =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Property\Selector#24 (2) {
+ private $sSelector =>
+ string(2) "to"
+ private $iSpecificity =>
+ NULL
+ }
+ }
+ private $aRules =>
+ array(1) {
+ 'top' =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Rule\Rule#25 (4) {
+ private $sRule =>
+ string(3) "top"
+ private $mValue =>
+ class Sabberworm\CSS\Value\Size#26 (4) {
+ private $fSize =>
+ double(200)
+ private $sUnit =>
+ string(2) "px"
+ private $bIsColorComponent =>
+ bool(false)
+ protected $iLineNo =>
+ int(14)
+ }
+ private $bIsImportant =>
+ bool(false)
+ protected $iLineNo =>
+ int(14)
+ }
+ }
+ }
+ protected $iLineNo =>
+ int(14)
+ }
+ }
+ protected $iLineNo =>
+ int(12)
+ }
+ }
+ protected $iLineNo =>
+ int(1)
+}
+
+```
+
+#### Output (`render()`)
+
+```css
+@charset "utf-8";
+@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}
+html, body {font-size: 1.6em;}
+@keyframes mymove {from {top: 0px;} to {top: 200px;}}
+```
+
+### Example 2 (Values)
+
+#### Input
+
+```css
+#header {
+ margin: 10px 2em 1cm 2%;
+ font-family: Verdana, Helvetica, "Gill Sans", sans-serif;
+ color: red !important;
+}
+
+```
+
+#### Structure (`var_dump()`)
+
+```php
+class Sabberworm\CSS\CSSList\Document#4 (2) {
+ protected $aContents =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\RuleSet\DeclarationBlock#5 (3) {
+ private $aSelectors =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Property\Selector#6 (2) {
+ private $sSelector =>
+ string(7) "#header"
+ private $iSpecificity =>
+ NULL
+ }
+ }
+ private $aRules =>
+ array(3) {
+ 'margin' =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Rule\Rule#7 (4) {
+ private $sRule =>
+ string(6) "margin"
+ private $mValue =>
+ class Sabberworm\CSS\Value\RuleValueList#12 (3) {
+ protected $aComponents =>
+ array(4) {
+ [0] =>
+ class Sabberworm\CSS\Value\Size#8 (4) {
+ private $fSize =>
+ double(10)
+ private $sUnit =>
+ string(2) "px"
+ private $bIsColorComponent =>
+ bool(false)
+ protected $iLineNo =>
+ int(2)
+ }
+ [1] =>
+ class Sabberworm\CSS\Value\Size#9 (4) {
+ private $fSize =>
+ double(2)
+ private $sUnit =>
+ string(2) "em"
+ private $bIsColorComponent =>
+ bool(false)
+ protected $iLineNo =>
+ int(2)
+ }
+ [2] =>
+ class Sabberworm\CSS\Value\Size#10 (4) {
+ private $fSize =>
+ double(1)
+ private $sUnit =>
+ string(2) "cm"
+ private $bIsColorComponent =>
+ bool(false)
+ protected $iLineNo =>
+ int(2)
+ }
+ [3] =>
+ class Sabberworm\CSS\Value\Size#11 (4) {
+ private $fSize =>
+ double(2)
+ private $sUnit =>
+ string(1) "%"
+ private $bIsColorComponent =>
+ bool(false)
+ protected $iLineNo =>
+ int(2)
+ }
+ }
+ protected $sSeparator =>
+ string(1) " "
+ protected $iLineNo =>
+ int(2)
+ }
+ private $bIsImportant =>
+ bool(false)
+ protected $iLineNo =>
+ int(2)
+ }
+ }
+ 'font-family' =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Rule\Rule#13 (4) {
+ private $sRule =>
+ string(11) "font-family"
+ private $mValue =>
+ class Sabberworm\CSS\Value\RuleValueList#15 (3) {
+ protected $aComponents =>
+ array(4) {
+ [0] =>
+ string(7) "Verdana"
+ [1] =>
+ string(9) "Helvetica"
+ [2] =>
+ class Sabberworm\CSS\Value\CSSString#14 (2) {
+ private $sString =>
+ string(9) "Gill Sans"
+ protected $iLineNo =>
+ int(3)
+ }
+ [3] =>
+ string(10) "sans-serif"
+ }
+ protected $sSeparator =>
+ string(1) ","
+ protected $iLineNo =>
+ int(3)
+ }
+ private $bIsImportant =>
+ bool(false)
+ protected $iLineNo =>
+ int(3)
+ }
+ }
+ 'color' =>
+ array(1) {
+ [0] =>
+ class Sabberworm\CSS\Rule\Rule#16 (4) {
+ private $sRule =>
+ string(5) "color"
+ private $mValue =>
+ string(3) "red"
+ private $bIsImportant =>
+ bool(true)
+ protected $iLineNo =>
+ int(4)
+ }
+ }
+ }
+ protected $iLineNo =>
+ int(1)
+ }
+ }
+ protected $iLineNo =>
+ int(1)
+}
+
+```
+
+#### Output (`render()`)
+
+```css
+#header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans",sans-serif;color: red !important;}
+```
+
+## Contributors/Thanks to
+
+* [oliverklee](https://github.com/oliverklee) for lots of refactorings, code modernizations and CI integrations
+* [raxbg](https://github.com/raxbg) for contributions to parse `calc`, grid lines, and various bugfixes.
+* [westonruter](https://github.com/westonruter) for bugfixes and improvements.
+* [FMCorz](https://github.com/FMCorz) for many patches and suggestions, for being able to parse comments and IE hacks (in lenient mode).
+* [Lullabot](https://github.com/Lullabot) for a patch that allows to know the line number for each parsed token.
+* [ju1ius](https://github.com/ju1ius) for the specificity parsing code and the ability to expand/compact shorthand properties.
+* [ossinkine](https://github.com/ossinkine) for a 150 time performance boost.
+* [GaryJones](https://github.com/GaryJones) for lots of input and [https://css-specificity.info/](https://css-specificity.info/).
+* [docteurklein](https://github.com/docteurklein) for output formatting and `CSSList->remove()` inspiration.
+* [nicolopignatelli](https://github.com/nicolopignatelli) for PSR-0 compatibility.
+* [diegoembarcadero](https://github.com/diegoembarcadero) for keyframe at-rule parsing.
+* [goetas](https://github.com/goetas) for @namespace at-rule support.
+* [View full list](https://github.com/sabberworm/PHP-CSS-Parser/contributors)
+
+## Misc
+
+* Legacy Support: The latest pre-PSR-0 version of this project can be checked with the `0.9.0` tag.
+* Running Tests: To run all unit tests for this project, run `composer install` to install phpunit and use `./vendor/bin/phpunit`.
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/composer.json b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/composer.json
new file mode 100644
index 0000000..e192dd5
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/composer.json
@@ -0,0 +1,69 @@
+{
+ "name": "sabberworm/php-css-parser",
+ "type": "library",
+ "description": "Parser for CSS Files written in PHP",
+ "keywords": [
+ "parser",
+ "css",
+ "stylesheet"
+ ],
+ "homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Raphael Schweikert"
+ }
+ ],
+ "require": {
+ "php": ">=5.6.20",
+ "ext-iconv": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.36",
+ "codacy/coverage": "^1.4"
+ },
+ "suggest": {
+ "ext-mbstring": "for parsing UTF-8 CSS"
+ },
+ "autoload": {
+ "psr-4": {
+ "Sabberworm\\CSS\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Sabberworm\\CSS\\Tests\\": "tests/"
+ }
+ },
+ "scripts": {
+ "ci": [
+ "@ci:static"
+ ],
+ "ci:php:fixer": "@php ./.phive/php-cs-fixer.phar --config=config/php-cs-fixer.php fix --dry-run -v --show-progress=dots bin src tests",
+ "ci:php:sniffer": "@php ./.phive/phpcs.phar --standard=config/phpcs.xml bin src tests",
+ "ci:php:stan": "@php ./.phive/phpstan.phar --configuration=config/phpstan.neon",
+ "ci:static": [
+ "@ci:php:fixer",
+ "@ci:php:sniffer",
+ "@ci:php:stan"
+ ],
+ "fix:php": [
+ "@fix:php:fixer",
+ "@fix:php:sniffer"
+ ],
+ "fix:php:fixer": "@php ./.phive/php-cs-fixer.phar --config=config/php-cs-fixer.php fix bin src tests",
+ "fix:php:sniffer": "@php ./.phive/phpcbf.phar --standard=config/phpcs.xml bin src tests",
+ "phpstan:baseline": "@php ./.phive/phpstan.phar --configuration=config/phpstan.neon --generate-baseline=config/phpstan-baseline.neon"
+ },
+ "scripts-descriptions": {
+ "ci": "Runs all dynamic and static code checks (i.e. currently, only the static checks).",
+ "ci:php:fixer": "Checks the code style with PHP CS Fixer.",
+ "ci:php:sniffer": "Checks the code style with PHP_CodeSniffer.",
+ "ci:php:stan": "Checks the types with PHPStan.",
+ "ci:static": "Runs all static code analysis checks for the code.",
+ "fix:php": "Autofixes all autofixable issues in the PHP code.",
+ "fix:php:fixer": "Fixes autofixable issues found by PHP CS Fixer.",
+ "fix:php:sniffer": "Fixes autofixable issues found by PHP_CodeSniffer.",
+ "phpstand:baseline": "Updates the PHPStan baseline file to match the code."
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/AtRuleBlockList.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/AtRuleBlockList.php
new file mode 100644
index 0000000..218adb9
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/AtRuleBlockList.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Sabberworm\CSS\CSSList;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Property\AtRule;
+
+/**
+ * A `BlockList` constructed by an unknown at-rule. `@media` rules are rendered into `AtRuleBlockList` objects.
+ */
+class AtRuleBlockList extends CSSBlockList implements AtRule
+{
+ /**
+ * @var string
+ */
+ private $sType;
+
+ /**
+ * @var string
+ */
+ private $sArgs;
+
+ /**
+ * @param string $sType
+ * @param string $sArgs
+ * @param int $iLineNo
+ */
+ public function __construct($sType, $sArgs = '', $iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ $this->sType = $sType;
+ $this->sArgs = $sArgs;
+ }
+
+ /**
+ * @return string
+ */
+ public function atRuleName()
+ {
+ return $this->sType;
+ }
+
+ /**
+ * @return string
+ */
+ public function atRuleArgs()
+ {
+ return $this->sArgs;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $sArgs = $this->sArgs;
+ if ($sArgs) {
+ $sArgs = ' ' . $sArgs;
+ }
+ $sResult = $oOutputFormat->sBeforeAtRuleBlock;
+ $sResult .= "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{";
+ $sResult .= parent::render($oOutputFormat);
+ $sResult .= '}';
+ $sResult .= $oOutputFormat->sAfterAtRuleBlock;
+ return $sResult;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRootList()
+ {
+ return false;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/CSSBlockList.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/CSSBlockList.php
new file mode 100644
index 0000000..fce7913
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/CSSBlockList.php
@@ -0,0 +1,143 @@
+<?php
+
+namespace Sabberworm\CSS\CSSList;
+
+use Sabberworm\CSS\Property\Selector;
+use Sabberworm\CSS\Rule\Rule;
+use Sabberworm\CSS\RuleSet\DeclarationBlock;
+use Sabberworm\CSS\RuleSet\RuleSet;
+use Sabberworm\CSS\Value\CSSFunction;
+use Sabberworm\CSS\Value\Value;
+use Sabberworm\CSS\Value\ValueList;
+
+/**
+ * A `CSSBlockList` is a `CSSList` whose `DeclarationBlock`s are guaranteed to contain valid declaration blocks or
+ * at-rules.
+ *
+ * Most `CSSList`s conform to this category but some at-rules (such as `@keyframes`) do not.
+ */
+abstract class CSSBlockList extends CSSList
+{
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ }
+
+ /**
+ * @param array<int, DeclarationBlock> $aResult
+ *
+ * @return void
+ */
+ protected function allDeclarationBlocks(array &$aResult)
+ {
+ foreach ($this->aContents as $mContent) {
+ if ($mContent instanceof DeclarationBlock) {
+ $aResult[] = $mContent;
+ } elseif ($mContent instanceof CSSBlockList) {
+ $mContent->allDeclarationBlocks($aResult);
+ }
+ }
+ }
+
+ /**
+ * @param array<int, RuleSet> $aResult
+ *
+ * @return void
+ */
+ protected function allRuleSets(array &$aResult)
+ {
+ foreach ($this->aContents as $mContent) {
+ if ($mContent instanceof RuleSet) {
+ $aResult[] = $mContent;
+ } elseif ($mContent instanceof CSSBlockList) {
+ $mContent->allRuleSets($aResult);
+ }
+ }
+ }
+
+ /**
+ * @param CSSList|Rule|RuleSet|Value $oElement
+ * @param array<int, Value> $aResult
+ * @param string|null $sSearchString
+ * @param bool $bSearchInFunctionArguments
+ *
+ * @return void
+ */
+ protected function allValues($oElement, array &$aResult, $sSearchString = null, $bSearchInFunctionArguments = false)
+ {
+ if ($oElement instanceof CSSBlockList) {
+ foreach ($oElement->getContents() as $oContent) {
+ $this->allValues($oContent, $aResult, $sSearchString, $bSearchInFunctionArguments);
+ }
+ } elseif ($oElement instanceof RuleSet) {
+ foreach ($oElement->getRules($sSearchString) as $oRule) {
+ $this->allValues($oRule, $aResult, $sSearchString, $bSearchInFunctionArguments);
+ }
+ } elseif ($oElement instanceof Rule) {
+ $this->allValues($oElement->getValue(), $aResult, $sSearchString, $bSearchInFunctionArguments);
+ } elseif ($oElement instanceof ValueList) {
+ if ($bSearchInFunctionArguments || !($oElement instanceof CSSFunction)) {
+ foreach ($oElement->getListComponents() as $mComponent) {
+ $this->allValues($mComponent, $aResult, $sSearchString, $bSearchInFunctionArguments);
+ }
+ }
+ } else {
+ // Non-List `Value` or `CSSString` (CSS identifier)
+ $aResult[] = $oElement;
+ }
+ }
+
+ /**
+ * @param array<int, Selector> $aResult
+ * @param string|null $sSpecificitySearch
+ *
+ * @return void
+ */
+ protected function allSelectors(array &$aResult, $sSpecificitySearch = null)
+ {
+ /** @var array<int, DeclarationBlock> $aDeclarationBlocks */
+ $aDeclarationBlocks = [];
+ $this->allDeclarationBlocks($aDeclarationBlocks);
+ foreach ($aDeclarationBlocks as $oBlock) {
+ foreach ($oBlock->getSelectors() as $oSelector) {
+ if ($sSpecificitySearch === null) {
+ $aResult[] = $oSelector;
+ } else {
+ $sComparator = '===';
+ $aSpecificitySearch = explode(' ', $sSpecificitySearch);
+ $iTargetSpecificity = $aSpecificitySearch[0];
+ if (count($aSpecificitySearch) > 1) {
+ $sComparator = $aSpecificitySearch[0];
+ $iTargetSpecificity = $aSpecificitySearch[1];
+ }
+ $iTargetSpecificity = (int)$iTargetSpecificity;
+ $iSelectorSpecificity = $oSelector->getSpecificity();
+ $bMatches = false;
+ switch ($sComparator) {
+ case '<=':
+ $bMatches = $iSelectorSpecificity <= $iTargetSpecificity;
+ break;
+ case '<':
+ $bMatches = $iSelectorSpecificity < $iTargetSpecificity;
+ break;
+ case '>=':
+ $bMatches = $iSelectorSpecificity >= $iTargetSpecificity;
+ break;
+ case '>':
+ $bMatches = $iSelectorSpecificity > $iTargetSpecificity;
+ break;
+ default:
+ $bMatches = $iSelectorSpecificity === $iTargetSpecificity;
+ break;
+ }
+ if ($bMatches) {
+ $aResult[] = $oSelector;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/CSSList.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/CSSList.php
new file mode 100644
index 0000000..946740a
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/CSSList.php
@@ -0,0 +1,479 @@
+<?php
+
+namespace Sabberworm\CSS\CSSList;
+
+use Sabberworm\CSS\Comment\Comment;
+use Sabberworm\CSS\Comment\Commentable;
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\SourceException;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+use Sabberworm\CSS\Property\AtRule;
+use Sabberworm\CSS\Property\Charset;
+use Sabberworm\CSS\Property\CSSNamespace;
+use Sabberworm\CSS\Property\Import;
+use Sabberworm\CSS\Property\Selector;
+use Sabberworm\CSS\Renderable;
+use Sabberworm\CSS\RuleSet\AtRuleSet;
+use Sabberworm\CSS\RuleSet\DeclarationBlock;
+use Sabberworm\CSS\RuleSet\RuleSet;
+use Sabberworm\CSS\Settings;
+use Sabberworm\CSS\Value\CSSString;
+use Sabberworm\CSS\Value\URL;
+use Sabberworm\CSS\Value\Value;
+
+/**
+ * A `CSSList` is the most generic container available. Its contents include `RuleSet` as well as other `CSSList`
+ * objects.
+ *
+ * Also, it may contain `Import` and `Charset` objects stemming from at-rules.
+ */
+abstract class CSSList implements Renderable, Commentable
+{
+ /**
+ * @var array<array-key, Comment>
+ */
+ protected $aComments;
+
+ /**
+ * @var array<int, RuleSet|CSSList|Import|Charset>
+ */
+ protected $aContents;
+
+ /**
+ * @var int
+ */
+ protected $iLineNo;
+
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ $this->aComments = [];
+ $this->aContents = [];
+ $this->iLineNo = $iLineNo;
+ }
+
+ /**
+ * @return void
+ *
+ * @throws UnexpectedTokenException
+ * @throws SourceException
+ */
+ public static function parseList(ParserState $oParserState, CSSList $oList)
+ {
+ $bIsRoot = $oList instanceof Document;
+ if (is_string($oParserState)) {
+ $oParserState = new ParserState($oParserState, Settings::create());
+ }
+ $bLenientParsing = $oParserState->getSettings()->bLenientParsing;
+ while (!$oParserState->isEnd()) {
+ $comments = $oParserState->consumeWhiteSpace();
+ $oListItem = null;
+ if ($bLenientParsing) {
+ try {
+ $oListItem = self::parseListItem($oParserState, $oList);
+ } catch (UnexpectedTokenException $e) {
+ $oListItem = false;
+ }
+ } else {
+ $oListItem = self::parseListItem($oParserState, $oList);
+ }
+ if ($oListItem === null) {
+ // List parsing finished
+ return;
+ }
+ if ($oListItem) {
+ $oListItem->setComments($comments);
+ $oList->append($oListItem);
+ }
+ $oParserState->consumeWhiteSpace();
+ }
+ if (!$bIsRoot && !$bLenientParsing) {
+ throw new SourceException("Unexpected end of document", $oParserState->currentLine());
+ }
+ }
+
+ /**
+ * @return AtRuleBlockList|KeyFrame|Charset|CSSNamespace|Import|AtRuleSet|DeclarationBlock|null|false
+ *
+ * @throws SourceException
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ private static function parseListItem(ParserState $oParserState, CSSList $oList)
+ {
+ $bIsRoot = $oList instanceof Document;
+ if ($oParserState->comes('@')) {
+ $oAtRule = self::parseAtRule($oParserState);
+ if ($oAtRule instanceof Charset) {
+ if (!$bIsRoot) {
+ throw new UnexpectedTokenException(
+ '@charset may only occur in root document',
+ '',
+ 'custom',
+ $oParserState->currentLine()
+ );
+ }
+ if (count($oList->getContents()) > 0) {
+ throw new UnexpectedTokenException(
+ '@charset must be the first parseable token in a document',
+ '',
+ 'custom',
+ $oParserState->currentLine()
+ );
+ }
+ $oParserState->setCharset($oAtRule->getCharset()->getString());
+ }
+ return $oAtRule;
+ } elseif ($oParserState->comes('}')) {
+ if (!$oParserState->getSettings()->bLenientParsing) {
+ throw new UnexpectedTokenException('CSS selector', '}', 'identifier', $oParserState->currentLine());
+ } else {
+ if ($bIsRoot) {
+ if ($oParserState->getSettings()->bLenientParsing) {
+ return DeclarationBlock::parse($oParserState);
+ } else {
+ throw new SourceException("Unopened {", $oParserState->currentLine());
+ }
+ } else {
+ return null;
+ }
+ }
+ } else {
+ return DeclarationBlock::parse($oParserState, $oList);
+ }
+ }
+
+ /**
+ * @param ParserState $oParserState
+ *
+ * @return AtRuleBlockList|KeyFrame|Charset|CSSNamespace|Import|AtRuleSet|null
+ *
+ * @throws SourceException
+ * @throws UnexpectedTokenException
+ * @throws UnexpectedEOFException
+ */
+ private static function parseAtRule(ParserState $oParserState)
+ {
+ $oParserState->consume('@');
+ $sIdentifier = $oParserState->parseIdentifier();
+ $iIdentifierLineNum = $oParserState->currentLine();
+ $oParserState->consumeWhiteSpace();
+ if ($sIdentifier === 'import') {
+ $oLocation = URL::parse($oParserState);
+ $oParserState->consumeWhiteSpace();
+ $sMediaQuery = null;
+ if (!$oParserState->comes(';')) {
+ $sMediaQuery = trim($oParserState->consumeUntil([';', ParserState::EOF]));
+ }
+ $oParserState->consumeUntil([';', ParserState::EOF], true, true);
+ return new Import($oLocation, $sMediaQuery ?: null, $iIdentifierLineNum);
+ } elseif ($sIdentifier === 'charset') {
+ $sCharset = CSSString::parse($oParserState);
+ $oParserState->consumeWhiteSpace();
+ $oParserState->consumeUntil([';', ParserState::EOF], true, true);
+ return new Charset($sCharset, $iIdentifierLineNum);
+ } elseif (self::identifierIs($sIdentifier, 'keyframes')) {
+ $oResult = new KeyFrame($iIdentifierLineNum);
+ $oResult->setVendorKeyFrame($sIdentifier);
+ $oResult->setAnimationName(trim($oParserState->consumeUntil('{', false, true)));
+ CSSList::parseList($oParserState, $oResult);
+ if ($oParserState->comes('}')) {
+ $oParserState->consume('}');
+ }
+ return $oResult;
+ } elseif ($sIdentifier === 'namespace') {
+ $sPrefix = null;
+ $mUrl = Value::parsePrimitiveValue($oParserState);
+ if (!$oParserState->comes(';')) {
+ $sPrefix = $mUrl;
+ $mUrl = Value::parsePrimitiveValue($oParserState);
+ }
+ $oParserState->consumeUntil([';', ParserState::EOF], true, true);
+ if ($sPrefix !== null && !is_string($sPrefix)) {
+ throw new UnexpectedTokenException('Wrong namespace prefix', $sPrefix, 'custom', $iIdentifierLineNum);
+ }
+ if (!($mUrl instanceof CSSString || $mUrl instanceof URL)) {
+ throw new UnexpectedTokenException(
+ 'Wrong namespace url of invalid type',
+ $mUrl,
+ 'custom',
+ $iIdentifierLineNum
+ );
+ }
+ return new CSSNamespace($mUrl, $sPrefix, $iIdentifierLineNum);
+ } else {
+ // Unknown other at rule (font-face or such)
+ $sArgs = trim($oParserState->consumeUntil('{', false, true));
+ if (substr_count($sArgs, "(") != substr_count($sArgs, ")")) {
+ if ($oParserState->getSettings()->bLenientParsing) {
+ return null;
+ } else {
+ throw new SourceException("Unmatched brace count in media query", $oParserState->currentLine());
+ }
+ }
+ $bUseRuleSet = true;
+ foreach (explode('/', AtRule::BLOCK_RULES) as $sBlockRuleName) {
+ if (self::identifierIs($sIdentifier, $sBlockRuleName)) {
+ $bUseRuleSet = false;
+ break;
+ }
+ }
+ if ($bUseRuleSet) {
+ $oAtRule = new AtRuleSet($sIdentifier, $sArgs, $iIdentifierLineNum);
+ RuleSet::parseRuleSet($oParserState, $oAtRule);
+ } else {
+ $oAtRule = new AtRuleBlockList($sIdentifier, $sArgs, $iIdentifierLineNum);
+ CSSList::parseList($oParserState, $oAtRule);
+ if ($oParserState->comes('}')) {
+ $oParserState->consume('}');
+ }
+ }
+ return $oAtRule;
+ }
+ }
+
+ /**
+ * Tests an identifier for a given value. Since identifiers are all keywords, they can be vendor-prefixed.
+ * We need to check for these versions too.
+ *
+ * @param string $sIdentifier
+ * @param string $sMatch
+ *
+ * @return bool
+ */
+ private static function identifierIs($sIdentifier, $sMatch)
+ {
+ return (strcasecmp($sIdentifier, $sMatch) === 0)
+ ?: preg_match("/^(-\\w+-)?$sMatch$/i", $sIdentifier) === 1;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+
+ /**
+ * Prepends an item to the list of contents.
+ *
+ * @param RuleSet|CSSList|Import|Charset $oItem
+ *
+ * @return void
+ */
+ public function prepend($oItem)
+ {
+ array_unshift($this->aContents, $oItem);
+ }
+
+ /**
+ * Appends an item to tje list of contents.
+ *
+ * @param RuleSet|CSSList|Import|Charset $oItem
+ *
+ * @return void
+ */
+ public function append($oItem)
+ {
+ $this->aContents[] = $oItem;
+ }
+
+ /**
+ * Splices the list of contents.
+ *
+ * @param int $iOffset
+ * @param int $iLength
+ * @param array<int, RuleSet|CSSList|Import|Charset> $mReplacement
+ *
+ * @return void
+ */
+ public function splice($iOffset, $iLength = null, $mReplacement = null)
+ {
+ array_splice($this->aContents, $iOffset, $iLength, $mReplacement);
+ }
+
+ /**
+ * Removes an item from the CSS list.
+ *
+ * @param RuleSet|Import|Charset|CSSList $oItemToRemove
+ * May be a RuleSet (most likely a DeclarationBlock), a Import,
+ * a Charset or another CSSList (most likely a MediaQuery)
+ *
+ * @return bool whether the item was removed
+ */
+ public function remove($oItemToRemove)
+ {
+ $iKey = array_search($oItemToRemove, $this->aContents, true);
+ if ($iKey !== false) {
+ unset($this->aContents[$iKey]);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Replaces an item from the CSS list.
+ *
+ * @param RuleSet|Import|Charset|CSSList $oOldItem
+ * May be a `RuleSet` (most likely a `DeclarationBlock`), an `Import`, a `Charset`
+ * or another `CSSList` (most likely a `MediaQuery`)
+ *
+ * @return bool
+ */
+ public function replace($oOldItem, $mNewItem)
+ {
+ $iKey = array_search($oOldItem, $this->aContents, true);
+ if ($iKey !== false) {
+ if (is_array($mNewItem)) {
+ array_splice($this->aContents, $iKey, 1, $mNewItem);
+ } else {
+ array_splice($this->aContents, $iKey, 1, [$mNewItem]);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param array<int, RuleSet|Import|Charset|CSSList> $aContents
+ */
+ public function setContents(array $aContents)
+ {
+ $this->aContents = [];
+ foreach ($aContents as $content) {
+ $this->append($content);
+ }
+ }
+
+ /**
+ * Removes a declaration block from the CSS list if it matches all given selectors.
+ *
+ * @param DeclarationBlock|array<array-key, Selector>|string $mSelector the selectors to match
+ * @param bool $bRemoveAll whether to stop at the first declaration block found or remove all blocks
+ *
+ * @return void
+ */
+ public function removeDeclarationBlockBySelector($mSelector, $bRemoveAll = false)
+ {
+ if ($mSelector instanceof DeclarationBlock) {
+ $mSelector = $mSelector->getSelectors();
+ }
+ if (!is_array($mSelector)) {
+ $mSelector = explode(',', $mSelector);
+ }
+ foreach ($mSelector as $iKey => &$mSel) {
+ if (!($mSel instanceof Selector)) {
+ if (!Selector::isValid($mSel)) {
+ throw new UnexpectedTokenException(
+ "Selector did not match '" . Selector::SELECTOR_VALIDATION_RX . "'.",
+ $mSel,
+ "custom"
+ );
+ }
+ $mSel = new Selector($mSel);
+ }
+ }
+ foreach ($this->aContents as $iKey => $mItem) {
+ if (!($mItem instanceof DeclarationBlock)) {
+ continue;
+ }
+ if ($mItem->getSelectors() == $mSelector) {
+ unset($this->aContents[$iKey]);
+ if (!$bRemoveAll) {
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $sResult = '';
+ $bIsFirst = true;
+ $oNextLevel = $oOutputFormat;
+ if (!$this->isRootList()) {
+ $oNextLevel = $oOutputFormat->nextLevel();
+ }
+ foreach ($this->aContents as $oContent) {
+ $sRendered = $oOutputFormat->safely(function () use ($oNextLevel, $oContent) {
+ return $oContent->render($oNextLevel);
+ });
+ if ($sRendered === null) {
+ continue;
+ }
+ if ($bIsFirst) {
+ $bIsFirst = false;
+ $sResult .= $oNextLevel->spaceBeforeBlocks();
+ } else {
+ $sResult .= $oNextLevel->spaceBetweenBlocks();
+ }
+ $sResult .= $sRendered;
+ }
+
+ if (!$bIsFirst) {
+ // Had some output
+ $sResult .= $oOutputFormat->spaceAfterBlocks();
+ }
+
+ return $sResult;
+ }
+
+ /**
+ * Return true if the list can not be further outdented. Only important when rendering.
+ *
+ * @return bool
+ */
+ abstract public function isRootList();
+
+ /**
+ * @return array<int, RuleSet|Import|Charset|CSSList>
+ */
+ public function getContents()
+ {
+ return $this->aContents;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function addComments(array $aComments)
+ {
+ $this->aComments = array_merge($this->aComments, $aComments);
+ }
+
+ /**
+ * @return array<array-key, Comment>
+ */
+ public function getComments()
+ {
+ return $this->aComments;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function setComments(array $aComments)
+ {
+ $this->aComments = $aComments;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/Document.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/Document.php
new file mode 100644
index 0000000..91ab2c6
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/Document.php
@@ -0,0 +1,172 @@
+<?php
+
+namespace Sabberworm\CSS\CSSList;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\SourceException;
+use Sabberworm\CSS\Property\Selector;
+use Sabberworm\CSS\RuleSet\DeclarationBlock;
+use Sabberworm\CSS\RuleSet\RuleSet;
+use Sabberworm\CSS\Value\Value;
+
+/**
+ * The root `CSSList` of a parsed file. Contains all top-level CSS contents, mostly declaration blocks,
+ * but also any at-rules encountered.
+ */
+class Document extends CSSBlockList
+{
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ }
+
+ /**
+ * @return Document
+ *
+ * @throws SourceException
+ */
+ public static function parse(ParserState $oParserState)
+ {
+ $oDocument = new Document($oParserState->currentLine());
+ CSSList::parseList($oParserState, $oDocument);
+ return $oDocument;
+ }
+
+ /**
+ * Gets all `DeclarationBlock` objects recursively.
+ *
+ * @return array<int, DeclarationBlock>
+ */
+ public function getAllDeclarationBlocks()
+ {
+ /** @var array<int, DeclarationBlock> $aResult */
+ $aResult = [];
+ $this->allDeclarationBlocks($aResult);
+ return $aResult;
+ }
+
+ /**
+ * Gets all `DeclarationBlock` objects recursively.
+ *
+ * @return array<int, DeclarationBlock>
+ *
+ * @deprecated will be removed in version 9.0; use `getAllDeclarationBlocks()` instead
+ */
+ public function getAllSelectors()
+ {
+ return $this->getAllDeclarationBlocks();
+ }
+
+ /**
+ * Returns all `RuleSet` objects found recursively in the tree.
+ *
+ * @return array<int, RuleSet>
+ */
+ public function getAllRuleSets()
+ {
+ /** @var array<int, RuleSet> $aResult */
+ $aResult = [];
+ $this->allRuleSets($aResult);
+ return $aResult;
+ }
+
+ /**
+ * Returns all `Value` objects found recursively in the tree.
+ *
+ * @param CSSList|RuleSet|string $mElement
+ * the `CSSList` or `RuleSet` to start the search from (defaults to the whole document).
+ * If a string is given, it is used as rule name filter.
+ * @param bool $bSearchInFunctionArguments whether to also return Value objects used as Function arguments.
+ *
+ * @return array<int, Value>
+ *
+ * @see RuleSet->getRules()
+ */
+ public function getAllValues($mElement = null, $bSearchInFunctionArguments = false)
+ {
+ $sSearchString = null;
+ if ($mElement === null) {
+ $mElement = $this;
+ } elseif (is_string($mElement)) {
+ $sSearchString = $mElement;
+ $mElement = $this;
+ }
+ /** @var array<int, Value> $aResult */
+ $aResult = [];
+ $this->allValues($mElement, $aResult, $sSearchString, $bSearchInFunctionArguments);
+ return $aResult;
+ }
+
+ /**
+ * Returns all `Selector` objects found recursively in the tree.
+ *
+ * Note that this does not yield the full `DeclarationBlock` that the selector belongs to
+ * (and, currently, there is no way to get to that).
+ *
+ * @param string|null $sSpecificitySearch
+ * An optional filter by specificity.
+ * May contain a comparison operator and a number or just a number (defaults to "==").
+ *
+ * @return array<int, Selector>
+ * @example `getSelectorsBySpecificity('>= 100')`
+ *
+ */
+ public function getSelectorsBySpecificity($sSpecificitySearch = null)
+ {
+ /** @var array<int, Selector> $aResult */
+ $aResult = [];
+ $this->allSelectors($aResult, $sSpecificitySearch);
+ return $aResult;
+ }
+
+ /**
+ * Expands all shorthand properties to their long value.
+ *
+ * @return void
+ */
+ public function expandShorthands()
+ {
+ foreach ($this->getAllDeclarationBlocks() as $oDeclaration) {
+ $oDeclaration->expandShorthands();
+ }
+ }
+
+ /**
+ * Create shorthands properties whenever possible.
+ *
+ * @return void
+ */
+ public function createShorthands()
+ {
+ foreach ($this->getAllDeclarationBlocks() as $oDeclaration) {
+ $oDeclaration->createShorthands();
+ }
+ }
+
+ /**
+ * Overrides `render()` to make format argument optional.
+ *
+ * @param OutputFormat|null $oOutputFormat
+ *
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat = null)
+ {
+ if ($oOutputFormat === null) {
+ $oOutputFormat = new OutputFormat();
+ }
+ return parent::render($oOutputFormat);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRootList()
+ {
+ return true;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/KeyFrame.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/KeyFrame.php
new file mode 100644
index 0000000..d9420e9
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/CSSList/KeyFrame.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace Sabberworm\CSS\CSSList;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Property\AtRule;
+
+class KeyFrame extends CSSList implements AtRule
+{
+ /**
+ * @var string|null
+ */
+ private $vendorKeyFrame;
+
+ /**
+ * @var string|null
+ */
+ private $animationName;
+
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ $this->vendorKeyFrame = null;
+ $this->animationName = null;
+ }
+
+ /**
+ * @param string $vendorKeyFrame
+ */
+ public function setVendorKeyFrame($vendorKeyFrame)
+ {
+ $this->vendorKeyFrame = $vendorKeyFrame;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getVendorKeyFrame()
+ {
+ return $this->vendorKeyFrame;
+ }
+
+ /**
+ * @param string $animationName
+ */
+ public function setAnimationName($animationName)
+ {
+ $this->animationName = $animationName;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getAnimationName()
+ {
+ return $this->animationName;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $sResult = "@{$this->vendorKeyFrame} {$this->animationName}{$oOutputFormat->spaceBeforeOpeningBrace()}{";
+ $sResult .= parent::render($oOutputFormat);
+ $sResult .= '}';
+ return $sResult;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRootList()
+ {
+ return false;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function atRuleName()
+ {
+ return $this->vendorKeyFrame;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function atRuleArgs()
+ {
+ return $this->animationName;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Comment/Comment.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Comment/Comment.php
new file mode 100644
index 0000000..6128d74
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Comment/Comment.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Sabberworm\CSS\Comment;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Renderable;
+
+class Comment implements Renderable
+{
+ /**
+ * @var int
+ */
+ protected $iLineNo;
+
+ /**
+ * @var string
+ */
+ protected $sComment;
+
+ /**
+ * @param string $sComment
+ * @param int $iLineNo
+ */
+ public function __construct($sComment = '', $iLineNo = 0)
+ {
+ $this->sComment = $sComment;
+ $this->iLineNo = $iLineNo;
+ }
+
+ /**
+ * @return string
+ */
+ public function getComment()
+ {
+ return $this->sComment;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+
+ /**
+ * @param string $sComment
+ *
+ * @return void
+ */
+ public function setComment($sComment)
+ {
+ $this->sComment = $sComment;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ return '/*' . $this->sComment . '*/';
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Comment/Commentable.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Comment/Commentable.php
new file mode 100644
index 0000000..5e450bf
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Comment/Commentable.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Sabberworm\CSS\Comment;
+
+interface Commentable
+{
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function addComments(array $aComments);
+
+ /**
+ * @return array<array-key, Comment>
+ */
+ public function getComments();
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function setComments(array $aComments);
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/OutputFormat.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/OutputFormat.php
new file mode 100644
index 0000000..595d306
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/OutputFormat.php
@@ -0,0 +1,334 @@
+<?php
+
+namespace Sabberworm\CSS;
+
+/**
+ * Class OutputFormat
+ *
+ * @method OutputFormat setSemicolonAfterLastRule(bool $bSemicolonAfterLastRule) Set whether semicolons are added after
+ * last rule.
+ */
+class OutputFormat
+{
+ /**
+ * Value format: `"` means double-quote, `'` means single-quote
+ *
+ * @var string
+ */
+ public $sStringQuotingType = '"';
+
+ /**
+ * Output RGB colors in hash notation if possible
+ *
+ * @var string
+ */
+ public $bRGBHashNotation = true;
+
+ /**
+ * Declaration format
+ *
+ * Semicolon after the last rule of a declaration block can be omitted. To do that, set this false.
+ *
+ * @var bool
+ */
+ public $bSemicolonAfterLastRule = true;
+
+ /**
+ * Spacing
+ * Note that these strings are not sanity-checked: the value should only consist of whitespace
+ * Any newline character will be indented according to the current level.
+ * The triples (After, Before, Between) can be set using a wildcard (e.g. `$oFormat->set('Space*Rules', "\n");`)
+ */
+ public $sSpaceAfterRuleName = ' ';
+
+ /**
+ * @var string
+ */
+ public $sSpaceBeforeRules = '';
+
+ /**
+ * @var string
+ */
+ public $sSpaceAfterRules = '';
+
+ /**
+ * @var string
+ */
+ public $sSpaceBetweenRules = '';
+
+ /**
+ * @var string
+ */
+ public $sSpaceBeforeBlocks = '';
+
+ /**
+ * @var string
+ */
+ public $sSpaceAfterBlocks = '';
+
+ /**
+ * @var string
+ */
+ public $sSpaceBetweenBlocks = "\n";
+
+ /**
+ * Content injected in and around at-rule blocks.
+ *
+ * @var string
+ */
+ public $sBeforeAtRuleBlock = '';
+
+ /**
+ * @var string
+ */
+ public $sAfterAtRuleBlock = '';
+
+ /**
+ * This is what’s printed before and after the comma if a declaration block contains multiple selectors.
+ *
+ * @var string
+ */
+ public $sSpaceBeforeSelectorSeparator = '';
+
+ /**
+ * @var string
+ */
+ public $sSpaceAfterSelectorSeparator = ' ';
+
+ /**
+ * This is what’s printed after the comma of value lists
+ *
+ * @var string
+ */
+ public $sSpaceBeforeListArgumentSeparator = '';
+
+ /**
+ * @var string
+ */
+ public $sSpaceAfterListArgumentSeparator = '';
+
+ /**
+ * @var string
+ */
+ public $sSpaceBeforeOpeningBrace = ' ';
+
+ /**
+ * Content injected in and around declaration blocks.
+ *
+ * @var string
+ */
+ public $sBeforeDeclarationBlock = '';
+
+ /**
+ * @var string
+ */
+ public $sAfterDeclarationBlockSelectors = '';
+
+ /**
+ * @var string
+ */
+ public $sAfterDeclarationBlock = '';
+
+ /**
+ * Indentation character(s) per level. Only applicable if newlines are used in any of the spacing settings.
+ *
+ * @var string
+ */
+ public $sIndentation = "\t";
+
+ /**
+ * Output exceptions.
+ *
+ * @var bool
+ */
+ public $bIgnoreExceptions = false;
+
+ /**
+ * @var OutputFormatter|null
+ */
+ private $oFormatter = null;
+
+ /**
+ * @var OutputFormat|null
+ */
+ private $oNextLevelFormat = null;
+
+ /**
+ * @var int
+ */
+ private $iIndentationLevel = 0;
+
+ public function __construct()
+ {
+ }
+
+ /**
+ * @param string $sName
+ *
+ * @return string|null
+ */
+ public function get($sName)
+ {
+ $aVarPrefixes = ['a', 's', 'm', 'b', 'f', 'o', 'c', 'i'];
+ foreach ($aVarPrefixes as $sPrefix) {
+ $sFieldName = $sPrefix . ucfirst($sName);
+ if (isset($this->$sFieldName)) {
+ return $this->$sFieldName;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param array<array-key, string>|string $aNames
+ * @param mixed $mValue
+ *
+ * @return self|false
+ */
+ public function set($aNames, $mValue)
+ {
+ $aVarPrefixes = ['a', 's', 'm', 'b', 'f', 'o', 'c', 'i'];
+ if (is_string($aNames) && strpos($aNames, '*') !== false) {
+ $aNames =
+ [
+ str_replace('*', 'Before', $aNames),
+ str_replace('*', 'Between', $aNames),
+ str_replace('*', 'After', $aNames),
+ ];
+ } elseif (!is_array($aNames)) {
+ $aNames = [$aNames];
+ }
+ foreach ($aVarPrefixes as $sPrefix) {
+ $bDidReplace = false;
+ foreach ($aNames as $sName) {
+ $sFieldName = $sPrefix . ucfirst($sName);
+ if (isset($this->$sFieldName)) {
+ $this->$sFieldName = $mValue;
+ $bDidReplace = true;
+ }
+ }
+ if ($bDidReplace) {
+ return $this;
+ }
+ }
+ // Break the chain so the user knows this option is invalid
+ return false;
+ }
+
+ /**
+ * @param string $sMethodName
+ * @param array<array-key, mixed> $aArguments
+ *
+ * @return mixed
+ *
+ * @throws \Exception
+ */
+ public function __call($sMethodName, array $aArguments)
+ {
+ if (strpos($sMethodName, 'set') === 0) {
+ return $this->set(substr($sMethodName, 3), $aArguments[0]);
+ } elseif (strpos($sMethodName, 'get') === 0) {
+ return $this->get(substr($sMethodName, 3));
+ } elseif (method_exists(OutputFormatter::class, $sMethodName)) {
+ return call_user_func_array([$this->getFormatter(), $sMethodName], $aArguments);
+ } else {
+ throw new \Exception('Unknown OutputFormat method called: ' . $sMethodName);
+ }
+ }
+
+ /**
+ * @param int $iNumber
+ *
+ * @return self
+ */
+ public function indentWithTabs($iNumber = 1)
+ {
+ return $this->setIndentation(str_repeat("\t", $iNumber));
+ }
+
+ /**
+ * @param int $iNumber
+ *
+ * @return self
+ */
+ public function indentWithSpaces($iNumber = 2)
+ {
+ return $this->setIndentation(str_repeat(" ", $iNumber));
+ }
+
+ /**
+ * @return OutputFormat
+ */
+ public function nextLevel()
+ {
+ if ($this->oNextLevelFormat === null) {
+ $this->oNextLevelFormat = clone $this;
+ $this->oNextLevelFormat->iIndentationLevel++;
+ $this->oNextLevelFormat->oFormatter = null;
+ }
+ return $this->oNextLevelFormat;
+ }
+
+ /**
+ * @return void
+ */
+ public function beLenient()
+ {
+ $this->bIgnoreExceptions = true;
+ }
+
+ /**
+ * @return OutputFormatter
+ */
+ public function getFormatter()
+ {
+ if ($this->oFormatter === null) {
+ $this->oFormatter = new OutputFormatter($this);
+ }
+ return $this->oFormatter;
+ }
+
+ /**
+ * @return int
+ */
+ public function level()
+ {
+ return $this->iIndentationLevel;
+ }
+
+ /**
+ * Creates an instance of this class without any particular formatting settings.
+ *
+ * @return self
+ */
+ public static function create()
+ {
+ return new OutputFormat();
+ }
+
+ /**
+ * Creates an instance of this class with a preset for compact formatting.
+ *
+ * @return self
+ */
+ public static function createCompact()
+ {
+ $format = self::create();
+ $format->set('Space*Rules', "")->set('Space*Blocks', "")->setSpaceAfterRuleName('')
+ ->setSpaceBeforeOpeningBrace('')->setSpaceAfterSelectorSeparator('');
+ return $format;
+ }
+
+ /**
+ * Creates an instance of this class with a preset for pretty formatting.
+ *
+ * @return self
+ */
+ public static function createPretty()
+ {
+ $format = self::create();
+ $format->set('Space*Rules', "\n")->set('Space*Blocks', "\n")
+ ->setSpaceBetweenBlocks("\n\n")->set('SpaceAfterListArgumentSeparator', ['default' => '', ',' => ' ']);
+ return $format;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/OutputFormatter.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/OutputFormatter.php
new file mode 100644
index 0000000..535feca
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/OutputFormatter.php
@@ -0,0 +1,231 @@
+<?php
+
+namespace Sabberworm\CSS;
+
+use Sabberworm\CSS\Parsing\OutputException;
+
+class OutputFormatter
+{
+ /**
+ * @var OutputFormat
+ */
+ private $oFormat;
+
+ public function __construct(OutputFormat $oFormat)
+ {
+ $this->oFormat = $oFormat;
+ }
+
+ /**
+ * @param string $sName
+ * @param string|null $sType
+ *
+ * @return string
+ */
+ public function space($sName, $sType = null)
+ {
+ $sSpaceString = $this->oFormat->get("Space$sName");
+ // If $sSpaceString is an array, we have multiple values configured
+ // depending on the type of object the space applies to
+ if (is_array($sSpaceString)) {
+ if ($sType !== null && isset($sSpaceString[$sType])) {
+ $sSpaceString = $sSpaceString[$sType];
+ } else {
+ $sSpaceString = reset($sSpaceString);
+ }
+ }
+ return $this->prepareSpace($sSpaceString);
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceAfterRuleName()
+ {
+ return $this->space('AfterRuleName');
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceBeforeRules()
+ {
+ return $this->space('BeforeRules');
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceAfterRules()
+ {
+ return $this->space('AfterRules');
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceBetweenRules()
+ {
+ return $this->space('BetweenRules');
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceBeforeBlocks()
+ {
+ return $this->space('BeforeBlocks');
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceAfterBlocks()
+ {
+ return $this->space('AfterBlocks');
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceBetweenBlocks()
+ {
+ return $this->space('BetweenBlocks');
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceBeforeSelectorSeparator()
+ {
+ return $this->space('BeforeSelectorSeparator');
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceAfterSelectorSeparator()
+ {
+ return $this->space('AfterSelectorSeparator');
+ }
+
+ /**
+ * @param string $sSeparator
+ *
+ * @return string
+ */
+ public function spaceBeforeListArgumentSeparator($sSeparator)
+ {
+ return $this->space('BeforeListArgumentSeparator', $sSeparator);
+ }
+
+ /**
+ * @param string $sSeparator
+ *
+ * @return string
+ */
+ public function spaceAfterListArgumentSeparator($sSeparator)
+ {
+ return $this->space('AfterListArgumentSeparator', $sSeparator);
+ }
+
+ /**
+ * @return string
+ */
+ public function spaceBeforeOpeningBrace()
+ {
+ return $this->space('BeforeOpeningBrace');
+ }
+
+ /**
+ * Runs the given code, either swallowing or passing exceptions, depending on the `bIgnoreExceptions` setting.
+ *
+ * @param string $cCode the name of the function to call
+ *
+ * @return string|null
+ */
+ public function safely($cCode)
+ {
+ if ($this->oFormat->get('IgnoreExceptions')) {
+ // If output exceptions are ignored, run the code with exception guards
+ try {
+ return $cCode();
+ } catch (OutputException $e) {
+ return null;
+ } // Do nothing
+ } else {
+ // Run the code as-is
+ return $cCode();
+ }
+ }
+
+ /**
+ * Clone of the `implode` function, but calls `render` with the current output format instead of `__toString()`.
+ *
+ * @param string $sSeparator
+ * @param array<array-key, Renderable|string> $aValues
+ * @param bool $bIncreaseLevel
+ *
+ * @return string
+ */
+ public function implode($sSeparator, array $aValues, $bIncreaseLevel = false)
+ {
+ $sResult = '';
+ $oFormat = $this->oFormat;
+ if ($bIncreaseLevel) {
+ $oFormat = $oFormat->nextLevel();
+ }
+ $bIsFirst = true;
+ foreach ($aValues as $mValue) {
+ if ($bIsFirst) {
+ $bIsFirst = false;
+ } else {
+ $sResult .= $sSeparator;
+ }
+ if ($mValue instanceof Renderable) {
+ $sResult .= $mValue->render($oFormat);
+ } else {
+ $sResult .= $mValue;
+ }
+ }
+ return $sResult;
+ }
+
+ /**
+ * @param string $sString
+ *
+ * @return string
+ */
+ public function removeLastSemicolon($sString)
+ {
+ if ($this->oFormat->get('SemicolonAfterLastRule')) {
+ return $sString;
+ }
+ $sString = explode(';', $sString);
+ if (count($sString) < 2) {
+ return $sString[0];
+ }
+ $sLast = array_pop($sString);
+ $sNextToLast = array_pop($sString);
+ array_push($sString, $sNextToLast . $sLast);
+ return implode(';', $sString);
+ }
+
+ /**
+ * @param string $sSpaceString
+ *
+ * @return string
+ */
+ private function prepareSpace($sSpaceString)
+ {
+ return str_replace("\n", "\n" . $this->indent(), $sSpaceString);
+ }
+
+ /**
+ * @return string
+ */
+ private function indent()
+ {
+ return str_repeat($this->oFormat->sIndentation, $this->oFormat->level());
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parser.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parser.php
new file mode 100644
index 0000000..f3b0493
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parser.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Sabberworm\CSS;
+
+use Sabberworm\CSS\CSSList\Document;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\SourceException;
+
+/**
+ * This class parses CSS from text into a data structure.
+ */
+class Parser
+{
+ /**
+ * @var ParserState
+ */
+ private $oParserState;
+
+ /**
+ * @param string $sText
+ * @param Settings|null $oParserSettings
+ * @param int $iLineNo the line number (starting from 1, not from 0)
+ */
+ public function __construct($sText, Settings $oParserSettings = null, $iLineNo = 1)
+ {
+ if ($oParserSettings === null) {
+ $oParserSettings = Settings::create();
+ }
+ $this->oParserState = new ParserState($sText, $oParserSettings, $iLineNo);
+ }
+
+ /**
+ * @param string $sCharset
+ *
+ * @return void
+ */
+ public function setCharset($sCharset)
+ {
+ $this->oParserState->setCharset($sCharset);
+ }
+
+ /**
+ * @return void
+ */
+ public function getCharset()
+ {
+ // Note: The `return` statement is missing here. This is a bug that needs to be fixed.
+ $this->oParserState->getCharset();
+ }
+
+ /**
+ * @return Document
+ *
+ * @throws SourceException
+ */
+ public function parse()
+ {
+ return Document::parse($this->oParserState);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/OutputException.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/OutputException.php
new file mode 100644
index 0000000..9bfbc75
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/OutputException.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Sabberworm\CSS\Parsing;
+
+/**
+ * Thrown if the CSS parser attempts to print something invalid.
+ */
+class OutputException extends SourceException
+{
+ /**
+ * @param string $sMessage
+ * @param int $iLineNo
+ */
+ public function __construct($sMessage, $iLineNo = 0)
+ {
+ parent::__construct($sMessage, $iLineNo);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/ParserState.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/ParserState.php
new file mode 100644
index 0000000..e7d85ee
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/ParserState.php
@@ -0,0 +1,516 @@
+<?php
+
+namespace Sabberworm\CSS\Parsing;
+
+use Sabberworm\CSS\Comment\Comment;
+use Sabberworm\CSS\Settings;
+
+class ParserState
+{
+ /**
+ * @var null
+ */
+ const EOF = null;
+
+ /**
+ * @var Settings
+ */
+ private $oParserSettings;
+
+ /**
+ * @var string
+ */
+ private $sText;
+
+ /**
+ * @var array<int, string>
+ */
+ private $aText;
+
+ /**
+ * @var int
+ */
+ private $iCurrentPosition;
+
+ /**
+ * @var string
+ */
+ private $sCharset;
+
+ /**
+ * @var int
+ */
+ private $iLength;
+
+ /**
+ * @var int
+ */
+ private $iLineNo;
+
+ /**
+ * @param string $sText
+ * @param int $iLineNo
+ */
+ public function __construct($sText, Settings $oParserSettings, $iLineNo = 1)
+ {
+ $this->oParserSettings = $oParserSettings;
+ $this->sText = $sText;
+ $this->iCurrentPosition = 0;
+ $this->iLineNo = $iLineNo;
+ $this->setCharset($this->oParserSettings->sDefaultCharset);
+ }
+
+ /**
+ * @param string $sCharset
+ *
+ * @return void
+ */
+ public function setCharset($sCharset)
+ {
+ $this->sCharset = $sCharset;
+ $this->aText = $this->strsplit($this->sText);
+ if (is_array($this->aText)) {
+ $this->iLength = count($this->aText);
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getCharset()
+ {
+ return $this->sCharset;
+ }
+
+ /**
+ * @return int
+ */
+ public function currentLine()
+ {
+ return $this->iLineNo;
+ }
+
+ /**
+ * @return int
+ */
+ public function currentColumn()
+ {
+ return $this->iCurrentPosition;
+ }
+
+ /**
+ * @return Settings
+ */
+ public function getSettings()
+ {
+ return $this->oParserSettings;
+ }
+
+ /**
+ * @param bool $bIgnoreCase
+ *
+ * @return string
+ *
+ * @throws UnexpectedTokenException
+ */
+ public function parseIdentifier($bIgnoreCase = true)
+ {
+ $sResult = $this->parseCharacter(true);
+ if ($sResult === null) {
+ throw new UnexpectedTokenException($sResult, $this->peek(5), 'identifier', $this->iLineNo);
+ }
+ $sCharacter = null;
+ while (($sCharacter = $this->parseCharacter(true)) !== null) {
+ if (preg_match('/[a-zA-Z0-9\x{00A0}-\x{FFFF}_-]/Sux', $sCharacter)) {
+ $sResult .= $sCharacter;
+ } else {
+ $sResult .= '\\' . $sCharacter;
+ }
+ }
+ if ($bIgnoreCase) {
+ $sResult = $this->strtolower($sResult);
+ }
+ return $sResult;
+ }
+
+ /**
+ * @param bool $bIsForIdentifier
+ *
+ * @return string|null
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public function parseCharacter($bIsForIdentifier)
+ {
+ if ($this->peek() === '\\') {
+ if (
+ $bIsForIdentifier && $this->oParserSettings->bLenientParsing
+ && ($this->comes('\0') || $this->comes('\9'))
+ ) {
+ // Non-strings can contain \0 or \9 which is an IE hack supported in lenient parsing.
+ return null;
+ }
+ $this->consume('\\');
+ if ($this->comes('\n') || $this->comes('\r')) {
+ return '';
+ }
+ if (preg_match('/[0-9a-fA-F]/Su', $this->peek()) === 0) {
+ return $this->consume(1);
+ }
+ $sUnicode = $this->consumeExpression('/^[0-9a-fA-F]{1,6}/u', 6);
+ if ($this->strlen($sUnicode) < 6) {
+ // Consume whitespace after incomplete unicode escape
+ if (preg_match('/\\s/isSu', $this->peek())) {
+ if ($this->comes('\r\n')) {
+ $this->consume(2);
+ } else {
+ $this->consume(1);
+ }
+ }
+ }
+ $iUnicode = intval($sUnicode, 16);
+ $sUtf32 = "";
+ for ($i = 0; $i < 4; ++$i) {
+ $sUtf32 .= chr($iUnicode & 0xff);
+ $iUnicode = $iUnicode >> 8;
+ }
+ return iconv('utf-32le', $this->sCharset, $sUtf32);
+ }
+ if ($bIsForIdentifier) {
+ $peek = ord($this->peek());
+ // Ranges: a-z A-Z 0-9 - _
+ if (
+ ($peek >= 97 && $peek <= 122)
+ || ($peek >= 65 && $peek <= 90)
+ || ($peek >= 48 && $peek <= 57)
+ || ($peek === 45)
+ || ($peek === 95)
+ || ($peek > 0xa1)
+ ) {
+ return $this->consume(1);
+ }
+ } else {
+ return $this->consume(1);
+ }
+ return null;
+ }
+
+ /**
+ * @return array<int, Comment>|void
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public function consumeWhiteSpace()
+ {
+ $comments = [];
+ do {
+ while (preg_match('/\\s/isSu', $this->peek()) === 1) {
+ $this->consume(1);
+ }
+ if ($this->oParserSettings->bLenientParsing) {
+ try {
+ $oComment = $this->consumeComment();
+ } catch (UnexpectedEOFException $e) {
+ $this->iCurrentPosition = $this->iLength;
+ return;
+ }
+ } else {
+ $oComment = $this->consumeComment();
+ }
+ if ($oComment !== false) {
+ $comments[] = $oComment;
+ }
+ } while ($oComment !== false);
+ return $comments;
+ }
+
+ /**
+ * @param string $sString
+ * @param bool $bCaseInsensitive
+ *
+ * @return bool
+ */
+ public function comes($sString, $bCaseInsensitive = false)
+ {
+ $sPeek = $this->peek(strlen($sString));
+ return ($sPeek == '')
+ ? false
+ : $this->streql($sPeek, $sString, $bCaseInsensitive);
+ }
+
+ /**
+ * @param int $iLength
+ * @param int $iOffset
+ *
+ * @return string
+ */
+ public function peek($iLength = 1, $iOffset = 0)
+ {
+ $iOffset += $this->iCurrentPosition;
+ if ($iOffset >= $this->iLength) {
+ return '';
+ }
+ return $this->substr($iOffset, $iLength);
+ }
+
+ /**
+ * @param int $mValue
+ *
+ * @return string
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public function consume($mValue = 1)
+ {
+ if (is_string($mValue)) {
+ $iLineCount = substr_count($mValue, "\n");
+ $iLength = $this->strlen($mValue);
+ if (!$this->streql($this->substr($this->iCurrentPosition, $iLength), $mValue)) {
+ throw new UnexpectedTokenException($mValue, $this->peek(max($iLength, 5)), $this->iLineNo);
+ }
+ $this->iLineNo += $iLineCount;
+ $this->iCurrentPosition += $this->strlen($mValue);
+ return $mValue;
+ } else {
+ if ($this->iCurrentPosition + $mValue > $this->iLength) {
+ throw new UnexpectedEOFException($mValue, $this->peek(5), 'count', $this->iLineNo);
+ }
+ $sResult = $this->substr($this->iCurrentPosition, $mValue);
+ $iLineCount = substr_count($sResult, "\n");
+ $this->iLineNo += $iLineCount;
+ $this->iCurrentPosition += $mValue;
+ return $sResult;
+ }
+ }
+
+ /**
+ * @param string $mExpression
+ * @param int|null $iMaxLength
+ *
+ * @return string
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public function consumeExpression($mExpression, $iMaxLength = null)
+ {
+ $aMatches = null;
+ $sInput = $iMaxLength !== null ? $this->peek($iMaxLength) : $this->inputLeft();
+ if (preg_match($mExpression, $sInput, $aMatches, PREG_OFFSET_CAPTURE) === 1) {
+ return $this->consume($aMatches[0][0]);
+ }
+ throw new UnexpectedTokenException($mExpression, $this->peek(5), 'expression', $this->iLineNo);
+ }
+
+ /**
+ * @return Comment|false
+ */
+ public function consumeComment()
+ {
+ $mComment = false;
+ if ($this->comes('/*')) {
+ $iLineNo = $this->iLineNo;
+ $this->consume(1);
+ $mComment = '';
+ while (($char = $this->consume(1)) !== '') {
+ $mComment .= $char;
+ if ($this->comes('*/')) {
+ $this->consume(2);
+ break;
+ }
+ }
+ }
+
+ if ($mComment !== false) {
+ // We skip the * which was included in the comment.
+ return new Comment(substr($mComment, 1), $iLineNo);
+ }
+
+ return $mComment;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isEnd()
+ {
+ return $this->iCurrentPosition >= $this->iLength;
+ }
+
+ /**
+ * @param array<array-key, string>|string $aEnd
+ * @param string $bIncludeEnd
+ * @param string $consumeEnd
+ * @param array<int, Comment> $comments
+ *
+ * @return string
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false, array &$comments = [])
+ {
+ $aEnd = is_array($aEnd) ? $aEnd : [$aEnd];
+ $out = '';
+ $start = $this->iCurrentPosition;
+
+ while (!$this->isEnd()) {
+ $char = $this->consume(1);
+ if (in_array($char, $aEnd)) {
+ if ($bIncludeEnd) {
+ $out .= $char;
+ } elseif (!$consumeEnd) {
+ $this->iCurrentPosition -= $this->strlen($char);
+ }
+ return $out;
+ }
+ $out .= $char;
+ if ($comment = $this->consumeComment()) {
+ $comments[] = $comment;
+ }
+ }
+
+ if (in_array(self::EOF, $aEnd)) {
+ return $out;
+ }
+
+ $this->iCurrentPosition = $start;
+ throw new UnexpectedEOFException(
+ 'One of ("' . implode('","', $aEnd) . '")',
+ $this->peek(5),
+ 'search',
+ $this->iLineNo
+ );
+ }
+
+ /**
+ * @return string
+ */
+ private function inputLeft()
+ {
+ return $this->substr($this->iCurrentPosition, -1);
+ }
+
+ /**
+ * @param string $sString1
+ * @param string $sString2
+ * @param bool $bCaseInsensitive
+ *
+ * @return bool
+ */
+ public function streql($sString1, $sString2, $bCaseInsensitive = true)
+ {
+ if ($bCaseInsensitive) {
+ return $this->strtolower($sString1) === $this->strtolower($sString2);
+ } else {
+ return $sString1 === $sString2;
+ }
+ }
+
+ /**
+ * @param int $iAmount
+ *
+ * @return void
+ */
+ public function backtrack($iAmount)
+ {
+ $this->iCurrentPosition -= $iAmount;
+ }
+
+ /**
+ * @param string $sString
+ *
+ * @return int
+ */
+ public function strlen($sString)
+ {
+ if ($this->oParserSettings->bMultibyteSupport) {
+ return mb_strlen($sString, $this->sCharset);
+ } else {
+ return strlen($sString);
+ }
+ }
+
+ /**
+ * @param int $iStart
+ * @param int $iLength
+ *
+ * @return string
+ */
+ private function substr($iStart, $iLength)
+ {
+ if ($iLength < 0) {
+ $iLength = $this->iLength - $iStart + $iLength;
+ }
+ if ($iStart + $iLength > $this->iLength) {
+ $iLength = $this->iLength - $iStart;
+ }
+ $sResult = '';
+ while ($iLength > 0) {
+ $sResult .= $this->aText[$iStart];
+ $iStart++;
+ $iLength--;
+ }
+ return $sResult;
+ }
+
+ /**
+ * @param string $sString
+ *
+ * @return string
+ */
+ private function strtolower($sString)
+ {
+ if ($this->oParserSettings->bMultibyteSupport) {
+ return mb_strtolower($sString, $this->sCharset);
+ } else {
+ return strtolower($sString);
+ }
+ }
+
+ /**
+ * @param string $sString
+ *
+ * @return array<int, string>
+ */
+ private function strsplit($sString)
+ {
+ if ($this->oParserSettings->bMultibyteSupport) {
+ if ($this->streql($this->sCharset, 'utf-8')) {
+ return preg_split('//u', $sString, -1, PREG_SPLIT_NO_EMPTY);
+ } else {
+ $iLength = mb_strlen($sString, $this->sCharset);
+ $aResult = [];
+ for ($i = 0; $i < $iLength; ++$i) {
+ $aResult[] = mb_substr($sString, $i, 1, $this->sCharset);
+ }
+ return $aResult;
+ }
+ } else {
+ if ($sString === '') {
+ return [];
+ } else {
+ return str_split($sString);
+ }
+ }
+ }
+
+ /**
+ * @param string $sString
+ * @param string $sNeedle
+ * @param int $iOffset
+ *
+ * @return int|false
+ */
+ private function strpos($sString, $sNeedle, $iOffset)
+ {
+ if ($this->oParserSettings->bMultibyteSupport) {
+ return mb_strpos($sString, $sNeedle, $iOffset, $this->sCharset);
+ } else {
+ return strpos($sString, $sNeedle, $iOffset);
+ }
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/SourceException.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/SourceException.php
new file mode 100644
index 0000000..1ca668a
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/SourceException.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Sabberworm\CSS\Parsing;
+
+class SourceException extends \Exception
+{
+ /**
+ * @var int
+ */
+ private $iLineNo;
+
+ /**
+ * @param string $sMessage
+ * @param int $iLineNo
+ */
+ public function __construct($sMessage, $iLineNo = 0)
+ {
+ $this->iLineNo = $iLineNo;
+ if (!empty($iLineNo)) {
+ $sMessage .= " [line no: $iLineNo]";
+ }
+ parent::__construct($sMessage);
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/UnexpectedEOFException.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/UnexpectedEOFException.php
new file mode 100644
index 0000000..368ec70
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/UnexpectedEOFException.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Sabberworm\CSS\Parsing;
+
+/**
+ * Thrown if the CSS parser encounters end of file it did not expect.
+ *
+ * Extends `UnexpectedTokenException` in order to preserve backwards compatibility.
+ */
+class UnexpectedEOFException extends UnexpectedTokenException
+{
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/UnexpectedTokenException.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/UnexpectedTokenException.php
new file mode 100644
index 0000000..7d5b1a6
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Parsing/UnexpectedTokenException.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Sabberworm\CSS\Parsing;
+
+/**
+ * Thrown if the CSS parser encounters a token it did not expect.
+ */
+class UnexpectedTokenException extends SourceException
+{
+ /**
+ * @var string
+ */
+ private $sExpected;
+
+ /**
+ * @var string
+ */
+ private $sFound;
+
+ /**
+ * Possible values: literal, identifier, count, expression, search
+ *
+ * @var string
+ */
+ private $sMatchType;
+
+ /**
+ * @param string $sExpected
+ * @param string $sFound
+ * @param string $sMatchType
+ * @param int $iLineNo
+ */
+ public function __construct($sExpected, $sFound, $sMatchType = 'literal', $iLineNo = 0)
+ {
+ $this->sExpected = $sExpected;
+ $this->sFound = $sFound;
+ $this->sMatchType = $sMatchType;
+ $sMessage = "Token “{$sExpected}” ({$sMatchType}) not found. Got “{$sFound}”.";
+ if ($this->sMatchType === 'search') {
+ $sMessage = "Search for “{$sExpected}” returned no results. Context: “{$sFound}”.";
+ } elseif ($this->sMatchType === 'count') {
+ $sMessage = "Next token was expected to have {$sExpected} chars. Context: “{$sFound}”.";
+ } elseif ($this->sMatchType === 'identifier') {
+ $sMessage = "Identifier expected. Got “{$sFound}”";
+ } elseif ($this->sMatchType === 'custom') {
+ $sMessage = trim("$sExpected $sFound");
+ }
+
+ parent::__construct($sMessage, $iLineNo);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/AtRule.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/AtRule.php
new file mode 100644
index 0000000..9536ff5
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/AtRule.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Sabberworm\CSS\Property;
+
+use Sabberworm\CSS\Comment\Commentable;
+use Sabberworm\CSS\Renderable;
+
+interface AtRule extends Renderable, Commentable
+{
+ /**
+ * Since there are more set rules than block rules,
+ * we’re whitelisting the block rules and have anything else be treated as a set rule.
+ *
+ * @var string
+ */
+ const BLOCK_RULES = 'media/document/supports/region-style/font-feature-values';
+
+ /**
+ * … and more font-specific ones (to be used inside font-feature-values)
+ *
+ * @var string
+ */
+ const SET_RULES = 'font-face/counter-style/page/swash/styleset/annotation';
+
+ /**
+ * @return string|null
+ */
+ public function atRuleName();
+
+ /**
+ * @return string|null
+ */
+ public function atRuleArgs();
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/CSSNamespace.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/CSSNamespace.php
new file mode 100644
index 0000000..0d7eb49
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/CSSNamespace.php
@@ -0,0 +1,154 @@
+<?php
+
+namespace Sabberworm\CSS\Property;
+
+use Sabberworm\CSS\Comment\Comment;
+use Sabberworm\CSS\OutputFormat;
+
+/**
+ * `CSSNamespace` represents an `@namespace` rule.
+ */
+class CSSNamespace implements AtRule
+{
+ /**
+ * @var string
+ */
+ private $mUrl;
+
+ /**
+ * @var string
+ */
+ private $sPrefix;
+
+ /**
+ * @var int
+ */
+ private $iLineNo;
+
+ /**
+ * @var array<array-key, Comment>
+ */
+ protected $aComments;
+
+ /**
+ * @param string $mUrl
+ * @param string|null $sPrefix
+ * @param int $iLineNo
+ */
+ public function __construct($mUrl, $sPrefix = null, $iLineNo = 0)
+ {
+ $this->mUrl = $mUrl;
+ $this->sPrefix = $sPrefix;
+ $this->iLineNo = $iLineNo;
+ $this->aComments = [];
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ return '@namespace ' . ($this->sPrefix === null ? '' : $this->sPrefix . ' ')
+ . $this->mUrl->render($oOutputFormat) . ';';
+ }
+
+ /**
+ * @return string
+ */
+ public function getUrl()
+ {
+ return $this->mUrl;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getPrefix()
+ {
+ return $this->sPrefix;
+ }
+
+ /**
+ * @param string $mUrl
+ *
+ * @return void
+ */
+ public function setUrl($mUrl)
+ {
+ $this->mUrl = $mUrl;
+ }
+
+ /**
+ * @param string $sPrefix
+ *
+ * @return void
+ */
+ public function setPrefix($sPrefix)
+ {
+ $this->sPrefix = $sPrefix;
+ }
+
+ /**
+ * @return string
+ */
+ public function atRuleName()
+ {
+ return 'namespace';
+ }
+
+ /**
+ * @return array<int, string>
+ */
+ public function atRuleArgs()
+ {
+ $aResult = [$this->mUrl];
+ if ($this->sPrefix) {
+ array_unshift($aResult, $this->sPrefix);
+ }
+ return $aResult;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function addComments(array $aComments)
+ {
+ $this->aComments = array_merge($this->aComments, $aComments);
+ }
+
+ /**
+ * @return array<array-key, Comment>
+ */
+ public function getComments()
+ {
+ return $this->aComments;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function setComments(array $aComments)
+ {
+ $this->aComments = $aComments;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Charset.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Charset.php
new file mode 100644
index 0000000..3ee0c3d
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Charset.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Sabberworm\CSS\Property;
+
+use Sabberworm\CSS\Comment\Comment;
+use Sabberworm\CSS\OutputFormat;
+
+/**
+ * Class representing an `@charset` rule.
+ *
+ * The following restrictions apply:
+ * - May not be found in any CSSList other than the Document.
+ * - May only appear at the very top of a Document’s contents.
+ * - Must not appear more than once.
+ */
+class Charset implements AtRule
+{
+ /**
+ * @var string
+ */
+ private $sCharset;
+
+ /**
+ * @var int
+ */
+ protected $iLineNo;
+
+ /**
+ * @var array<array-key, Comment>
+ */
+ protected $aComments;
+
+ /**
+ * @param string $sCharset
+ * @param int $iLineNo
+ */
+ public function __construct($sCharset, $iLineNo = 0)
+ {
+ $this->sCharset = $sCharset;
+ $this->iLineNo = $iLineNo;
+ $this->aComments = [];
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+
+ /**
+ * @param string $sCharset
+ *
+ * @return void
+ */
+ public function setCharset($sCharset)
+ {
+ $this->sCharset = $sCharset;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCharset()
+ {
+ return $this->sCharset;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ return "@charset {$this->sCharset->render($oOutputFormat)};";
+ }
+
+ /**
+ * @return string
+ */
+ public function atRuleName()
+ {
+ return 'charset';
+ }
+
+ /**
+ * @return string
+ */
+ public function atRuleArgs()
+ {
+ return $this->sCharset;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function addComments(array $aComments)
+ {
+ $this->aComments = array_merge($this->aComments, $aComments);
+ }
+
+ /**
+ * @return array<array-key, Comment>
+ */
+ public function getComments()
+ {
+ return $this->aComments;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function setComments(array $aComments)
+ {
+ $this->aComments = $aComments;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Import.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Import.php
new file mode 100644
index 0000000..a225301
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Import.php
@@ -0,0 +1,137 @@
+<?php
+
+namespace Sabberworm\CSS\Property;
+
+use Sabberworm\CSS\Comment\Comment;
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Value\URL;
+
+/**
+ * Class representing an `@import` rule.
+ */
+class Import implements AtRule
+{
+ /**
+ * @var URL
+ */
+ private $oLocation;
+
+ /**
+ * @var string
+ */
+ private $sMediaQuery;
+
+ /**
+ * @var int
+ */
+ protected $iLineNo;
+
+ /**
+ * @var array<array-key, Comment>
+ */
+ protected $aComments;
+
+ /**
+ * @param URL $oLocation
+ * @param string $sMediaQuery
+ * @param int $iLineNo
+ */
+ public function __construct(URL $oLocation, $sMediaQuery, $iLineNo = 0)
+ {
+ $this->oLocation = $oLocation;
+ $this->sMediaQuery = $sMediaQuery;
+ $this->iLineNo = $iLineNo;
+ $this->aComments = [];
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+
+ /**
+ * @param URL $oLocation
+ *
+ * @return void
+ */
+ public function setLocation($oLocation)
+ {
+ $this->oLocation = $oLocation;
+ }
+
+ /**
+ * @return URL
+ */
+ public function getLocation()
+ {
+ return $this->oLocation;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ return "@import " . $this->oLocation->render($oOutputFormat)
+ . ($this->sMediaQuery === null ? '' : ' ' . $this->sMediaQuery) . ';';
+ }
+
+ /**
+ * @return string
+ */
+ public function atRuleName()
+ {
+ return 'import';
+ }
+
+ /**
+ * @return array<int, URL|string>
+ */
+ public function atRuleArgs()
+ {
+ $aResult = [$this->oLocation];
+ if ($this->sMediaQuery) {
+ array_push($aResult, $this->sMediaQuery);
+ }
+ return $aResult;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function addComments(array $aComments)
+ {
+ $this->aComments = array_merge($this->aComments, $aComments);
+ }
+
+ /**
+ * @return array<array-key, Comment>
+ */
+ public function getComments()
+ {
+ return $this->aComments;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function setComments(array $aComments)
+ {
+ $this->aComments = $aComments;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/KeyframeSelector.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/KeyframeSelector.php
new file mode 100644
index 0000000..14ea5eb
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/KeyframeSelector.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Sabberworm\CSS\Property;
+
+class KeyframeSelector extends Selector
+{
+ /**
+ * regexp for specificity calculations
+ *
+ * @var string
+ */
+ const SELECTOR_VALIDATION_RX = '/
+ ^(
+ (?:
+ [a-zA-Z0-9\x{00A0}-\x{FFFF}_^$|*="\'~\[\]()\-\s\.:#+>]* # any sequence of valid unescaped characters
+ (?:\\\\.)? # a single escaped character
+ (?:([\'"]).*?(?<!\\\\)\2)? # a quoted text like [id="example"]
+ )*
+ )|
+ (\d+%) # keyframe animation progress percentage (e.g. 50%)
+ $
+ /ux';
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Selector.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Selector.php
new file mode 100644
index 0000000..70c9b2f
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Property/Selector.php
@@ -0,0 +1,138 @@
+<?php
+
+namespace Sabberworm\CSS\Property;
+
+/**
+ * Class representing a single CSS selector. Selectors have to be split by the comma prior to being passed into this
+ * class.
+ */
+class Selector
+{
+ /**
+ * regexp for specificity calculations
+ *
+ * @var string
+ */
+ const NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX = '/
+ (\.[\w]+) # classes
+ |
+ \[(\w+) # attributes
+ |
+ (\:( # pseudo classes
+ link|visited|active
+ |hover|focus
+ |lang
+ |target
+ |enabled|disabled|checked|indeterminate
+ |root
+ |nth-child|nth-last-child|nth-of-type|nth-last-of-type
+ |first-child|last-child|first-of-type|last-of-type
+ |only-child|only-of-type
+ |empty|contains
+ ))
+ /ix';
+
+ /**
+ * regexp for specificity calculations
+ *
+ * @var string
+ */
+ const ELEMENTS_AND_PSEUDO_ELEMENTS_RX = '/
+ ((^|[\s\+\>\~]+)[\w]+ # elements
+ |
+ \:{1,2}( # pseudo-elements
+ after|before|first-letter|first-line|selection
+ ))
+ /ix';
+
+ /**
+ * regexp for specificity calculations
+ *
+ * @var string
+ */
+ const SELECTOR_VALIDATION_RX = '/
+ ^(
+ (?:
+ [a-zA-Z0-9\x{00A0}-\x{FFFF}_^$|*="\'~\[\]()\-\s\.:#+>]* # any sequence of valid unescaped characters
+ (?:\\\\.)? # a single escaped character
+ (?:([\'"]).*?(?<!\\\\)\2)? # a quoted text like [id="example"]
+ )*
+ )$
+ /ux';
+
+ /**
+ * @var string
+ */
+ private $sSelector;
+
+ /**
+ * @var int|null
+ */
+ private $iSpecificity;
+
+ /**
+ * @param string $sSelector
+ *
+ * @return bool
+ */
+ public static function isValid($sSelector)
+ {
+ return preg_match(static::SELECTOR_VALIDATION_RX, $sSelector);
+ }
+
+ /**
+ * @param string $sSelector
+ * @param bool $bCalculateSpecificity
+ */
+ public function __construct($sSelector, $bCalculateSpecificity = false)
+ {
+ $this->setSelector($sSelector);
+ if ($bCalculateSpecificity) {
+ $this->getSpecificity();
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getSelector()
+ {
+ return $this->sSelector;
+ }
+
+ /**
+ * @param string $sSelector
+ *
+ * @return void
+ */
+ public function setSelector($sSelector)
+ {
+ $this->sSelector = trim($sSelector);
+ $this->iSpecificity = null;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->getSelector();
+ }
+
+ /**
+ * @return int
+ */
+ public function getSpecificity()
+ {
+ if ($this->iSpecificity === null) {
+ $a = 0;
+ /// @todo should exclude \# as well as "#"
+ $aMatches = null;
+ $b = substr_count($this->sSelector, '#');
+ $c = preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $this->sSelector, $aMatches);
+ $d = preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $this->sSelector, $aMatches);
+ $this->iSpecificity = ($a * 1000) + ($b * 100) + ($c * 10) + $d;
+ }
+ return $this->iSpecificity;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Renderable.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Renderable.php
new file mode 100644
index 0000000..dc1bff3
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Renderable.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Sabberworm\CSS;
+
+interface Renderable
+{
+ /**
+ * @return string
+ */
+ public function __toString();
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat);
+
+ /**
+ * @return int
+ */
+ public function getLineNo();
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Rule/Rule.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Rule/Rule.php
new file mode 100644
index 0000000..c1ea6df
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Rule/Rule.php
@@ -0,0 +1,392 @@
+<?php
+
+namespace Sabberworm\CSS\Rule;
+
+use Sabberworm\CSS\Comment\Comment;
+use Sabberworm\CSS\Comment\Commentable;
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+use Sabberworm\CSS\Renderable;
+use Sabberworm\CSS\Value\RuleValueList;
+use Sabberworm\CSS\Value\Value;
+
+/**
+ * RuleSets contains Rule objects which always have a key and a value.
+ * In CSS, Rules are expressed as follows: “key: value[0][0] value[0][1], value[1][0] value[1][1];”
+ */
+class Rule implements Renderable, Commentable
+{
+ /**
+ * @var string
+ */
+ private $sRule;
+
+ /**
+ * @var RuleValueList|null
+ */
+ private $mValue;
+
+ /**
+ * @var bool
+ */
+ private $bIsImportant;
+
+ /**
+ * @var array<int, int>
+ */
+ private $aIeHack;
+
+ /**
+ * @var int
+ */
+ protected $iLineNo;
+
+ /**
+ * @var int
+ */
+ protected $iColNo;
+
+ /**
+ * @var array<array-key, Comment>
+ */
+ protected $aComments;
+
+ /**
+ * @param string $sRule
+ * @param int $iLineNo
+ * @param int $iColNo
+ */
+ public function __construct($sRule, $iLineNo = 0, $iColNo = 0)
+ {
+ $this->sRule = $sRule;
+ $this->mValue = null;
+ $this->bIsImportant = false;
+ $this->aIeHack = [];
+ $this->iLineNo = $iLineNo;
+ $this->iColNo = $iColNo;
+ $this->aComments = [];
+ }
+
+ /**
+ * @return Rule
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public static function parse(ParserState $oParserState)
+ {
+ $aComments = $oParserState->consumeWhiteSpace();
+ $oRule = new Rule(
+ $oParserState->parseIdentifier(!$oParserState->comes("--")),
+ $oParserState->currentLine(),
+ $oParserState->currentColumn()
+ );
+ $oRule->setComments($aComments);
+ $oRule->addComments($oParserState->consumeWhiteSpace());
+ $oParserState->consume(':');
+ $oValue = Value::parseValue($oParserState, self::listDelimiterForRule($oRule->getRule()));
+ $oRule->setValue($oValue);
+ if ($oParserState->getSettings()->bLenientParsing) {
+ while ($oParserState->comes('\\')) {
+ $oParserState->consume('\\');
+ $oRule->addIeHack($oParserState->consume());
+ $oParserState->consumeWhiteSpace();
+ }
+ }
+ $oParserState->consumeWhiteSpace();
+ if ($oParserState->comes('!')) {
+ $oParserState->consume('!');
+ $oParserState->consumeWhiteSpace();
+ $oParserState->consume('important');
+ $oRule->setIsImportant(true);
+ }
+ $oParserState->consumeWhiteSpace();
+ while ($oParserState->comes(';')) {
+ $oParserState->consume(';');
+ }
+ $oParserState->consumeWhiteSpace();
+
+ return $oRule;
+ }
+
+ /**
+ * @param string $sRule
+ *
+ * @return array<int, string>
+ */
+ private static function listDelimiterForRule($sRule)
+ {
+ if (preg_match('/^font($|-)/', $sRule)) {
+ return [',', '/', ' '];
+ }
+ return [',', ' ', '/'];
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+
+ /**
+ * @return int
+ */
+ public function getColNo()
+ {
+ return $this->iColNo;
+ }
+
+ /**
+ * @param int $iLine
+ * @param int $iColumn
+ *
+ * @return void
+ */
+ public function setPosition($iLine, $iColumn)
+ {
+ $this->iColNo = $iColumn;
+ $this->iLineNo = $iLine;
+ }
+
+ /**
+ * @param string $sRule
+ *
+ * @return void
+ */
+ public function setRule($sRule)
+ {
+ $this->sRule = $sRule;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRule()
+ {
+ return $this->sRule;
+ }
+
+ /**
+ * @return RuleValueList|null
+ */
+ public function getValue()
+ {
+ return $this->mValue;
+ }
+
+ /**
+ * @param RuleValueList|null $mValue
+ *
+ * @return void
+ */
+ public function setValue($mValue)
+ {
+ $this->mValue = $mValue;
+ }
+
+ /**
+ * @param array<array-key, array<array-key, RuleValueList>> $aSpaceSeparatedValues
+ *
+ * @return RuleValueList
+ *
+ * @deprecated will be removed in version 9.0
+ * Old-Style 2-dimensional array given. Retained for (some) backwards-compatibility.
+ * Use `setValue()` instead and wrap the value inside a RuleValueList if necessary.
+ */
+ public function setValues(array $aSpaceSeparatedValues)
+ {
+ $oSpaceSeparatedList = null;
+ if (count($aSpaceSeparatedValues) > 1) {
+ $oSpaceSeparatedList = new RuleValueList(' ', $this->iLineNo);
+ }
+ foreach ($aSpaceSeparatedValues as $aCommaSeparatedValues) {
+ $oCommaSeparatedList = null;
+ if (count($aCommaSeparatedValues) > 1) {
+ $oCommaSeparatedList = new RuleValueList(',', $this->iLineNo);
+ }
+ foreach ($aCommaSeparatedValues as $mValue) {
+ if (!$oSpaceSeparatedList && !$oCommaSeparatedList) {
+ $this->mValue = $mValue;
+ return $mValue;
+ }
+ if ($oCommaSeparatedList) {
+ $oCommaSeparatedList->addListComponent($mValue);
+ } else {
+ $oSpaceSeparatedList->addListComponent($mValue);
+ }
+ }
+ if (!$oSpaceSeparatedList) {
+ $this->mValue = $oCommaSeparatedList;
+ return $oCommaSeparatedList;
+ } else {
+ $oSpaceSeparatedList->addListComponent($oCommaSeparatedList);
+ }
+ }
+ $this->mValue = $oSpaceSeparatedList;
+ return $oSpaceSeparatedList;
+ }
+
+ /**
+ * @return array<int, array<int, RuleValueList>>
+ *
+ * @deprecated will be removed in version 9.0
+ * Old-Style 2-dimensional array returned. Retained for (some) backwards-compatibility.
+ * Use `getValue()` instead and check for the existence of a (nested set of) ValueList object(s).
+ */
+ public function getValues()
+ {
+ if (!$this->mValue instanceof RuleValueList) {
+ return [[$this->mValue]];
+ }
+ if ($this->mValue->getListSeparator() === ',') {
+ return [$this->mValue->getListComponents()];
+ }
+ $aResult = [];
+ foreach ($this->mValue->getListComponents() as $mValue) {
+ if (!$mValue instanceof RuleValueList || $mValue->getListSeparator() !== ',') {
+ $aResult[] = [$mValue];
+ continue;
+ }
+ if ($this->mValue->getListSeparator() === ' ' || count($aResult) === 0) {
+ $aResult[] = [];
+ }
+ foreach ($mValue->getListComponents() as $mValue) {
+ $aResult[count($aResult) - 1][] = $mValue;
+ }
+ }
+ return $aResult;
+ }
+
+ /**
+ * Adds a value to the existing value. Value will be appended if a `RuleValueList` exists of the given type.
+ * Otherwise, the existing value will be wrapped by one.
+ *
+ * @param RuleValueList|array<int, RuleValueList> $mValue
+ * @param string $sType
+ *
+ * @return void
+ */
+ public function addValue($mValue, $sType = ' ')
+ {
+ if (!is_array($mValue)) {
+ $mValue = [$mValue];
+ }
+ if (!$this->mValue instanceof RuleValueList || $this->mValue->getListSeparator() !== $sType) {
+ $mCurrentValue = $this->mValue;
+ $this->mValue = new RuleValueList($sType, $this->iLineNo);
+ if ($mCurrentValue) {
+ $this->mValue->addListComponent($mCurrentValue);
+ }
+ }
+ foreach ($mValue as $mValueItem) {
+ $this->mValue->addListComponent($mValueItem);
+ }
+ }
+
+ /**
+ * @param int $iModifier
+ *
+ * @return void
+ */
+ public function addIeHack($iModifier)
+ {
+ $this->aIeHack[] = $iModifier;
+ }
+
+ /**
+ * @param array<int, int> $aModifiers
+ *
+ * @return void
+ */
+ public function setIeHack(array $aModifiers)
+ {
+ $this->aIeHack = $aModifiers;
+ }
+
+ /**
+ * @return array<int, int>
+ */
+ public function getIeHack()
+ {
+ return $this->aIeHack;
+ }
+
+ /**
+ * @param bool $bIsImportant
+ *
+ * @return void
+ */
+ public function setIsImportant($bIsImportant)
+ {
+ $this->bIsImportant = $bIsImportant;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getIsImportant()
+ {
+ return $this->bIsImportant;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $sResult = "{$this->sRule}:{$oOutputFormat->spaceAfterRuleName()}";
+ if ($this->mValue instanceof Value) { //Can also be a ValueList
+ $sResult .= $this->mValue->render($oOutputFormat);
+ } else {
+ $sResult .= $this->mValue;
+ }
+ if (!empty($this->aIeHack)) {
+ $sResult .= ' \\' . implode('\\', $this->aIeHack);
+ }
+ if ($this->bIsImportant) {
+ $sResult .= ' !important';
+ }
+ $sResult .= ';';
+ return $sResult;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function addComments(array $aComments)
+ {
+ $this->aComments = array_merge($this->aComments, $aComments);
+ }
+
+ /**
+ * @return array<array-key, Comment>
+ */
+ public function getComments()
+ {
+ return $this->aComments;
+ }
+
+ /**
+ * @param array<array-key, Comment> $aComments
+ *
+ * @return void
+ */
+ public function setComments(array $aComments)
+ {
+ $this->aComments = $aComments;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/AtRuleSet.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/AtRuleSet.php
new file mode 100644
index 0000000..88bc5bd
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/AtRuleSet.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Sabberworm\CSS\RuleSet;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Property\AtRule;
+
+/**
+ * A RuleSet constructed by an unknown at-rule. `@font-face` rules are rendered into AtRuleSet objects.
+ */
+class AtRuleSet extends RuleSet implements AtRule
+{
+ /**
+ * @var string
+ */
+ private $sType;
+
+ /**
+ * @var string
+ */
+ private $sArgs;
+
+ /**
+ * @param string $sType
+ * @param string $sArgs
+ * @param int $iLineNo
+ */
+ public function __construct($sType, $sArgs = '', $iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ $this->sType = $sType;
+ $this->sArgs = $sArgs;
+ }
+
+ /**
+ * @return string
+ */
+ public function atRuleName()
+ {
+ return $this->sType;
+ }
+
+ /**
+ * @return string
+ */
+ public function atRuleArgs()
+ {
+ return $this->sArgs;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $sArgs = $this->sArgs;
+ if ($sArgs) {
+ $sArgs = ' ' . $sArgs;
+ }
+ $sResult = "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{";
+ $sResult .= parent::render($oOutputFormat);
+ $sResult .= '}';
+ return $sResult;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/DeclarationBlock.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/DeclarationBlock.php
new file mode 100644
index 0000000..c27cdd4
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/DeclarationBlock.php
@@ -0,0 +1,831 @@
+<?php
+
+namespace Sabberworm\CSS\RuleSet;
+
+use Sabberworm\CSS\CSSList\CSSList;
+use Sabberworm\CSS\CSSList\KeyFrame;
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\OutputException;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+use Sabberworm\CSS\Property\KeyframeSelector;
+use Sabberworm\CSS\Property\Selector;
+use Sabberworm\CSS\Rule\Rule;
+use Sabberworm\CSS\Value\Color;
+use Sabberworm\CSS\Value\RuleValueList;
+use Sabberworm\CSS\Value\Size;
+use Sabberworm\CSS\Value\URL;
+use Sabberworm\CSS\Value\Value;
+
+/**
+ * Declaration blocks are the parts of a CSS file which denote the rules belonging to a selector.
+ *
+ * Declaration blocks usually appear directly inside a `Document` or another `CSSList` (mostly a `MediaQuery`).
+ */
+class DeclarationBlock extends RuleSet
+{
+ /**
+ * @var array<int, Selector|string>
+ */
+ private $aSelectors;
+
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ $this->aSelectors = [];
+ }
+
+ /**
+ * @param CSSList|null $oList
+ *
+ * @return DeclarationBlock|false
+ *
+ * @throws UnexpectedTokenException
+ * @throws UnexpectedEOFException
+ */
+ public static function parse(ParserState $oParserState, $oList = null)
+ {
+ $aComments = [];
+ $oResult = new DeclarationBlock($oParserState->currentLine());
+ try {
+ $aSelectorParts = [];
+ $sStringWrapperChar = false;
+ do {
+ $aSelectorParts[] = $oParserState->consume(1)
+ . $oParserState->consumeUntil(['{', '}', '\'', '"'], false, false, $aComments);
+ if (in_array($oParserState->peek(), ['\'', '"']) && substr(end($aSelectorParts), -1) != "\\") {
+ if ($sStringWrapperChar === false) {
+ $sStringWrapperChar = $oParserState->peek();
+ } elseif ($sStringWrapperChar == $oParserState->peek()) {
+ $sStringWrapperChar = false;
+ }
+ }
+ } while (!in_array($oParserState->peek(), ['{', '}']) || $sStringWrapperChar !== false);
+ $oResult->setSelectors(implode('', $aSelectorParts), $oList);
+ if ($oParserState->comes('{')) {
+ $oParserState->consume(1);
+ }
+ } catch (UnexpectedTokenException $e) {
+ if ($oParserState->getSettings()->bLenientParsing) {
+ if (!$oParserState->comes('}')) {
+ $oParserState->consumeUntil('}', false, true);
+ }
+ return false;
+ } else {
+ throw $e;
+ }
+ }
+ $oResult->setComments($aComments);
+ RuleSet::parseRuleSet($oParserState, $oResult);
+ return $oResult;
+ }
+
+ /**
+ * @param array<int, Selector|string>|string $mSelector
+ * @param CSSList|null $oList
+ *
+ * @throws UnexpectedTokenException
+ */
+ public function setSelectors($mSelector, $oList = null)
+ {
+ if (is_array($mSelector)) {
+ $this->aSelectors = $mSelector;
+ } else {
+ $this->aSelectors = explode(',', $mSelector);
+ }
+ foreach ($this->aSelectors as $iKey => $mSelector) {
+ if (!($mSelector instanceof Selector)) {
+ if ($oList === null || !($oList instanceof KeyFrame)) {
+ if (!Selector::isValid($mSelector)) {
+ throw new UnexpectedTokenException(
+ "Selector did not match '" . Selector::SELECTOR_VALIDATION_RX . "'.",
+ $mSelector,
+ "custom"
+ );
+ }
+ $this->aSelectors[$iKey] = new Selector($mSelector);
+ } else {
+ if (!KeyframeSelector::isValid($mSelector)) {
+ throw new UnexpectedTokenException(
+ "Selector did not match '" . KeyframeSelector::SELECTOR_VALIDATION_RX . "'.",
+ $mSelector,
+ "custom"
+ );
+ }
+ $this->aSelectors[$iKey] = new KeyframeSelector($mSelector);
+ }
+ }
+ }
+ }
+
+ /**
+ * Remove one of the selectors of the block.
+ *
+ * @param Selector|string $mSelector
+ *
+ * @return bool
+ */
+ public function removeSelector($mSelector)
+ {
+ if ($mSelector instanceof Selector) {
+ $mSelector = $mSelector->getSelector();
+ }
+ foreach ($this->aSelectors as $iKey => $oSelector) {
+ if ($oSelector->getSelector() === $mSelector) {
+ unset($this->aSelectors[$iKey]);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return array<int, Selector|string>
+ *
+ * @deprecated will be removed in version 9.0; use `getSelectors()` instead
+ */
+ public function getSelector()
+ {
+ return $this->getSelectors();
+ }
+
+ /**
+ * @param Selector|string $mSelector
+ * @param CSSList|null $oList
+ *
+ * @return void
+ *
+ * @deprecated will be removed in version 9.0; use `setSelectors()` instead
+ */
+ public function setSelector($mSelector, $oList = null)
+ {
+ $this->setSelectors($mSelector, $oList);
+ }
+
+ /**
+ * @return array<int, Selector|string>
+ */
+ public function getSelectors()
+ {
+ return $this->aSelectors;
+ }
+
+ /**
+ * Splits shorthand declarations (e.g. `margin` or `font`) into their constituent parts.
+ *
+ * @return void
+ */
+ public function expandShorthands()
+ {
+ // border must be expanded before dimensions
+ $this->expandBorderShorthand();
+ $this->expandDimensionsShorthand();
+ $this->expandFontShorthand();
+ $this->expandBackgroundShorthand();
+ $this->expandListStyleShorthand();
+ }
+
+ /**
+ * Creates shorthand declarations (e.g. `margin` or `font`) whenever possible.
+ *
+ * @return void
+ */
+ public function createShorthands()
+ {
+ $this->createBackgroundShorthand();
+ $this->createDimensionsShorthand();
+ // border must be shortened after dimensions
+ $this->createBorderShorthand();
+ $this->createFontShorthand();
+ $this->createListStyleShorthand();
+ }
+
+ /**
+ * Splits shorthand border declarations (e.g. `border: 1px red;`).
+ *
+ * Additional splitting happens in expandDimensionsShorthand.
+ *
+ * Multiple borders are not yet supported as of 3.
+ *
+ * @return void
+ */
+ public function expandBorderShorthand()
+ {
+ $aBorderRules = [
+ 'border',
+ 'border-left',
+ 'border-right',
+ 'border-top',
+ 'border-bottom',
+ ];
+ $aBorderSizes = [
+ 'thin',
+ 'medium',
+ 'thick',
+ ];
+ $aRules = $this->getRulesAssoc();
+ foreach ($aBorderRules as $sBorderRule) {
+ if (!isset($aRules[$sBorderRule])) {
+ continue;
+ }
+ $oRule = $aRules[$sBorderRule];
+ $mRuleValue = $oRule->getValue();
+ $aValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aValues[] = $mRuleValue;
+ } else {
+ $aValues = $mRuleValue->getListComponents();
+ }
+ foreach ($aValues as $mValue) {
+ if ($mValue instanceof Value) {
+ $mNewValue = clone $mValue;
+ } else {
+ $mNewValue = $mValue;
+ }
+ if ($mValue instanceof Size) {
+ $sNewRuleName = $sBorderRule . "-width";
+ } elseif ($mValue instanceof Color) {
+ $sNewRuleName = $sBorderRule . "-color";
+ } else {
+ if (in_array($mValue, $aBorderSizes)) {
+ $sNewRuleName = $sBorderRule . "-width";
+ } else {
+ $sNewRuleName = $sBorderRule . "-style";
+ }
+ }
+ $oNewRule = new Rule($sNewRuleName, $oRule->getLineNo(), $oRule->getColNo());
+ $oNewRule->setIsImportant($oRule->getIsImportant());
+ $oNewRule->addValue([$mNewValue]);
+ $this->addRule($oNewRule);
+ }
+ $this->removeRule($sBorderRule);
+ }
+ }
+
+ /**
+ * Splits shorthand dimensional declarations (e.g. `margin: 0px auto;`)
+ * into their constituent parts.
+ *
+ * Handles `margin`, `padding`, `border-color`, `border-style` and `border-width`.
+ *
+ * @return void
+ */
+ public function expandDimensionsShorthand()
+ {
+ $aExpansions = [
+ 'margin' => 'margin-%s',
+ 'padding' => 'padding-%s',
+ 'border-color' => 'border-%s-color',
+ 'border-style' => 'border-%s-style',
+ 'border-width' => 'border-%s-width',
+ ];
+ $aRules = $this->getRulesAssoc();
+ foreach ($aExpansions as $sProperty => $sExpanded) {
+ if (!isset($aRules[$sProperty])) {
+ continue;
+ }
+ $oRule = $aRules[$sProperty];
+ $mRuleValue = $oRule->getValue();
+ $aValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aValues[] = $mRuleValue;
+ } else {
+ $aValues = $mRuleValue->getListComponents();
+ }
+ $top = $right = $bottom = $left = null;
+ switch (count($aValues)) {
+ case 1:
+ $top = $right = $bottom = $left = $aValues[0];
+ break;
+ case 2:
+ $top = $bottom = $aValues[0];
+ $left = $right = $aValues[1];
+ break;
+ case 3:
+ $top = $aValues[0];
+ $left = $right = $aValues[1];
+ $bottom = $aValues[2];
+ break;
+ case 4:
+ $top = $aValues[0];
+ $right = $aValues[1];
+ $bottom = $aValues[2];
+ $left = $aValues[3];
+ break;
+ }
+ foreach (['top', 'right', 'bottom', 'left'] as $sPosition) {
+ $oNewRule = new Rule(sprintf($sExpanded, $sPosition), $oRule->getLineNo(), $oRule->getColNo());
+ $oNewRule->setIsImportant($oRule->getIsImportant());
+ $oNewRule->addValue(${$sPosition});
+ $this->addRule($oNewRule);
+ }
+ $this->removeRule($sProperty);
+ }
+ }
+
+ /**
+ * Converts shorthand font declarations
+ * (e.g. `font: 300 italic 11px/14px verdana, helvetica, sans-serif;`)
+ * into their constituent parts.
+ *
+ * @return void
+ */
+ public function expandFontShorthand()
+ {
+ $aRules = $this->getRulesAssoc();
+ if (!isset($aRules['font'])) {
+ return;
+ }
+ $oRule = $aRules['font'];
+ // reset properties to 'normal' per http://www.w3.org/TR/21/fonts.html#font-shorthand
+ $aFontProperties = [
+ 'font-style' => 'normal',
+ 'font-variant' => 'normal',
+ 'font-weight' => 'normal',
+ 'font-size' => 'normal',
+ 'line-height' => 'normal',
+ ];
+ $mRuleValue = $oRule->getValue();
+ $aValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aValues[] = $mRuleValue;
+ } else {
+ $aValues = $mRuleValue->getListComponents();
+ }
+ foreach ($aValues as $mValue) {
+ if (!$mValue instanceof Value) {
+ $mValue = mb_strtolower($mValue);
+ }
+ if (in_array($mValue, ['normal', 'inherit'])) {
+ foreach (['font-style', 'font-weight', 'font-variant'] as $sProperty) {
+ if (!isset($aFontProperties[$sProperty])) {
+ $aFontProperties[$sProperty] = $mValue;
+ }
+ }
+ } elseif (in_array($mValue, ['italic', 'oblique'])) {
+ $aFontProperties['font-style'] = $mValue;
+ } elseif ($mValue == 'small-caps') {
+ $aFontProperties['font-variant'] = $mValue;
+ } elseif (
+ in_array($mValue, ['bold', 'bolder', 'lighter'])
+ || ($mValue instanceof Size
+ && in_array($mValue->getSize(), range(100, 900, 100)))
+ ) {
+ $aFontProperties['font-weight'] = $mValue;
+ } elseif ($mValue instanceof RuleValueList && $mValue->getListSeparator() == '/') {
+ list($oSize, $oHeight) = $mValue->getListComponents();
+ $aFontProperties['font-size'] = $oSize;
+ $aFontProperties['line-height'] = $oHeight;
+ } elseif ($mValue instanceof Size && $mValue->getUnit() !== null) {
+ $aFontProperties['font-size'] = $mValue;
+ } else {
+ $aFontProperties['font-family'] = $mValue;
+ }
+ }
+ foreach ($aFontProperties as $sProperty => $mValue) {
+ $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
+ $oNewRule->addValue($mValue);
+ $oNewRule->setIsImportant($oRule->getIsImportant());
+ $this->addRule($oNewRule);
+ }
+ $this->removeRule('font');
+ }
+
+ /**
+ * Converts shorthand background declarations
+ * (e.g. `background: url("chess.png") gray 50% repeat fixed;`)
+ * into their constituent parts.
+ *
+ * @see http://www.w3.org/TR/21/colors.html#propdef-background
+ *
+ * @return void
+ */
+ public function expandBackgroundShorthand()
+ {
+ $aRules = $this->getRulesAssoc();
+ if (!isset($aRules['background'])) {
+ return;
+ }
+ $oRule = $aRules['background'];
+ $aBgProperties = [
+ 'background-color' => ['transparent'],
+ 'background-image' => ['none'],
+ 'background-repeat' => ['repeat'],
+ 'background-attachment' => ['scroll'],
+ 'background-position' => [
+ new Size(0, '%', null, false, $this->iLineNo),
+ new Size(0, '%', null, false, $this->iLineNo),
+ ],
+ ];
+ $mRuleValue = $oRule->getValue();
+ $aValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aValues[] = $mRuleValue;
+ } else {
+ $aValues = $mRuleValue->getListComponents();
+ }
+ if (count($aValues) == 1 && $aValues[0] == 'inherit') {
+ foreach ($aBgProperties as $sProperty => $mValue) {
+ $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
+ $oNewRule->addValue('inherit');
+ $oNewRule->setIsImportant($oRule->getIsImportant());
+ $this->addRule($oNewRule);
+ }
+ $this->removeRule('background');
+ return;
+ }
+ $iNumBgPos = 0;
+ foreach ($aValues as $mValue) {
+ if (!$mValue instanceof Value) {
+ $mValue = mb_strtolower($mValue);
+ }
+ if ($mValue instanceof URL) {
+ $aBgProperties['background-image'] = $mValue;
+ } elseif ($mValue instanceof Color) {
+ $aBgProperties['background-color'] = $mValue;
+ } elseif (in_array($mValue, ['scroll', 'fixed'])) {
+ $aBgProperties['background-attachment'] = $mValue;
+ } elseif (in_array($mValue, ['repeat', 'no-repeat', 'repeat-x', 'repeat-y'])) {
+ $aBgProperties['background-repeat'] = $mValue;
+ } elseif (
+ in_array($mValue, ['left', 'center', 'right', 'top', 'bottom'])
+ || $mValue instanceof Size
+ ) {
+ if ($iNumBgPos == 0) {
+ $aBgProperties['background-position'][0] = $mValue;
+ $aBgProperties['background-position'][1] = 'center';
+ } else {
+ $aBgProperties['background-position'][$iNumBgPos] = $mValue;
+ }
+ $iNumBgPos++;
+ }
+ }
+ foreach ($aBgProperties as $sProperty => $mValue) {
+ $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
+ $oNewRule->setIsImportant($oRule->getIsImportant());
+ $oNewRule->addValue($mValue);
+ $this->addRule($oNewRule);
+ }
+ $this->removeRule('background');
+ }
+
+ /**
+ * @return void
+ */
+ public function expandListStyleShorthand()
+ {
+ $aListProperties = [
+ 'list-style-type' => 'disc',
+ 'list-style-position' => 'outside',
+ 'list-style-image' => 'none',
+ ];
+ $aListStyleTypes = [
+ 'none',
+ 'disc',
+ 'circle',
+ 'square',
+ 'decimal-leading-zero',
+ 'decimal',
+ 'lower-roman',
+ 'upper-roman',
+ 'lower-greek',
+ 'lower-alpha',
+ 'lower-latin',
+ 'upper-alpha',
+ 'upper-latin',
+ 'hebrew',
+ 'armenian',
+ 'georgian',
+ 'cjk-ideographic',
+ 'hiragana',
+ 'hira-gana-iroha',
+ 'katakana-iroha',
+ 'katakana',
+ ];
+ $aListStylePositions = [
+ 'inside',
+ 'outside',
+ ];
+ $aRules = $this->getRulesAssoc();
+ if (!isset($aRules['list-style'])) {
+ return;
+ }
+ $oRule = $aRules['list-style'];
+ $mRuleValue = $oRule->getValue();
+ $aValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aValues[] = $mRuleValue;
+ } else {
+ $aValues = $mRuleValue->getListComponents();
+ }
+ if (count($aValues) == 1 && $aValues[0] == 'inherit') {
+ foreach ($aListProperties as $sProperty => $mValue) {
+ $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
+ $oNewRule->addValue('inherit');
+ $oNewRule->setIsImportant($oRule->getIsImportant());
+ $this->addRule($oNewRule);
+ }
+ $this->removeRule('list-style');
+ return;
+ }
+ foreach ($aValues as $mValue) {
+ if (!$mValue instanceof Value) {
+ $mValue = mb_strtolower($mValue);
+ }
+ if ($mValue instanceof Url) {
+ $aListProperties['list-style-image'] = $mValue;
+ } elseif (in_array($mValue, $aListStyleTypes)) {
+ $aListProperties['list-style-types'] = $mValue;
+ } elseif (in_array($mValue, $aListStylePositions)) {
+ $aListProperties['list-style-position'] = $mValue;
+ }
+ }
+ foreach ($aListProperties as $sProperty => $mValue) {
+ $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
+ $oNewRule->setIsImportant($oRule->getIsImportant());
+ $oNewRule->addValue($mValue);
+ $this->addRule($oNewRule);
+ }
+ $this->removeRule('list-style');
+ }
+
+ /**
+ * @param array<array-key, string> $aProperties
+ * @param string $sShorthand
+ *
+ * @return void
+ */
+ public function createShorthandProperties(array $aProperties, $sShorthand)
+ {
+ $aRules = $this->getRulesAssoc();
+ $aNewValues = [];
+ foreach ($aProperties as $sProperty) {
+ if (!isset($aRules[$sProperty])) {
+ continue;
+ }
+ $oRule = $aRules[$sProperty];
+ if (!$oRule->getIsImportant()) {
+ $mRuleValue = $oRule->getValue();
+ $aValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aValues[] = $mRuleValue;
+ } else {
+ $aValues = $mRuleValue->getListComponents();
+ }
+ foreach ($aValues as $mValue) {
+ $aNewValues[] = $mValue;
+ }
+ $this->removeRule($sProperty);
+ }
+ }
+ if (count($aNewValues)) {
+ $oNewRule = new Rule($sShorthand, $oRule->getLineNo(), $oRule->getColNo());
+ foreach ($aNewValues as $mValue) {
+ $oNewRule->addValue($mValue);
+ }
+ $this->addRule($oNewRule);
+ }
+ }
+
+ /**
+ * @return void
+ */
+ public function createBackgroundShorthand()
+ {
+ $aProperties = [
+ 'background-color',
+ 'background-image',
+ 'background-repeat',
+ 'background-position',
+ 'background-attachment',
+ ];
+ $this->createShorthandProperties($aProperties, 'background');
+ }
+
+ /**
+ * @return void
+ */
+ public function createListStyleShorthand()
+ {
+ $aProperties = [
+ 'list-style-type',
+ 'list-style-position',
+ 'list-style-image',
+ ];
+ $this->createShorthandProperties($aProperties, 'list-style');
+ }
+
+ /**
+ * Combines `border-color`, `border-style` and `border-width` into `border`.
+ *
+ * Should be run after `create_dimensions_shorthand`!
+ *
+ * @return void
+ */
+ public function createBorderShorthand()
+ {
+ $aProperties = [
+ 'border-width',
+ 'border-style',
+ 'border-color',
+ ];
+ $this->createShorthandProperties($aProperties, 'border');
+ }
+
+ /**
+ * Looks for long format CSS dimensional properties
+ * (margin, padding, border-color, border-style and border-width)
+ * and converts them into shorthand CSS properties.
+ *
+ * @return void
+ */
+ public function createDimensionsShorthand()
+ {
+ $aPositions = ['top', 'right', 'bottom', 'left'];
+ $aExpansions = [
+ 'margin' => 'margin-%s',
+ 'padding' => 'padding-%s',
+ 'border-color' => 'border-%s-color',
+ 'border-style' => 'border-%s-style',
+ 'border-width' => 'border-%s-width',
+ ];
+ $aRules = $this->getRulesAssoc();
+ foreach ($aExpansions as $sProperty => $sExpanded) {
+ $aFoldable = [];
+ foreach ($aRules as $sRuleName => $oRule) {
+ foreach ($aPositions as $sPosition) {
+ if ($sRuleName == sprintf($sExpanded, $sPosition)) {
+ $aFoldable[$sRuleName] = $oRule;
+ }
+ }
+ }
+ // All four dimensions must be present
+ if (count($aFoldable) == 4) {
+ $aValues = [];
+ foreach ($aPositions as $sPosition) {
+ $oRule = $aRules[sprintf($sExpanded, $sPosition)];
+ $mRuleValue = $oRule->getValue();
+ $aRuleValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aRuleValues[] = $mRuleValue;
+ } else {
+ $aRuleValues = $mRuleValue->getListComponents();
+ }
+ $aValues[$sPosition] = $aRuleValues;
+ }
+ $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo());
+ if ((string)$aValues['left'][0] == (string)$aValues['right'][0]) {
+ if ((string)$aValues['top'][0] == (string)$aValues['bottom'][0]) {
+ if ((string)$aValues['top'][0] == (string)$aValues['left'][0]) {
+ // All 4 sides are equal
+ $oNewRule->addValue($aValues['top']);
+ } else {
+ // Top and bottom are equal, left and right are equal
+ $oNewRule->addValue($aValues['top']);
+ $oNewRule->addValue($aValues['left']);
+ }
+ } else {
+ // Only left and right are equal
+ $oNewRule->addValue($aValues['top']);
+ $oNewRule->addValue($aValues['left']);
+ $oNewRule->addValue($aValues['bottom']);
+ }
+ } else {
+ // No sides are equal
+ $oNewRule->addValue($aValues['top']);
+ $oNewRule->addValue($aValues['left']);
+ $oNewRule->addValue($aValues['bottom']);
+ $oNewRule->addValue($aValues['right']);
+ }
+ $this->addRule($oNewRule);
+ foreach ($aPositions as $sPosition) {
+ $this->removeRule(sprintf($sExpanded, $sPosition));
+ }
+ }
+ }
+ }
+
+ /**
+ * Looks for long format CSS font properties (e.g. `font-weight`) and
+ * tries to convert them into a shorthand CSS `font` property.
+ *
+ * At least `font-size` AND `font-family` must be present in order to create a shorthand declaration.
+ *
+ * @return void
+ */
+ public function createFontShorthand()
+ {
+ $aFontProperties = [
+ 'font-style',
+ 'font-variant',
+ 'font-weight',
+ 'font-size',
+ 'line-height',
+ 'font-family',
+ ];
+ $aRules = $this->getRulesAssoc();
+ if (!isset($aRules['font-size']) || !isset($aRules['font-family'])) {
+ return;
+ }
+ $oOldRule = isset($aRules['font-size']) ? $aRules['font-size'] : $aRules['font-family'];
+ $oNewRule = new Rule('font', $oOldRule->getLineNo(), $oOldRule->getColNo());
+ unset($oOldRule);
+ foreach (['font-style', 'font-variant', 'font-weight'] as $sProperty) {
+ if (isset($aRules[$sProperty])) {
+ $oRule = $aRules[$sProperty];
+ $mRuleValue = $oRule->getValue();
+ $aValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aValues[] = $mRuleValue;
+ } else {
+ $aValues = $mRuleValue->getListComponents();
+ }
+ if ($aValues[0] !== 'normal') {
+ $oNewRule->addValue($aValues[0]);
+ }
+ }
+ }
+ // Get the font-size value
+ $oRule = $aRules['font-size'];
+ $mRuleValue = $oRule->getValue();
+ $aFSValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aFSValues[] = $mRuleValue;
+ } else {
+ $aFSValues = $mRuleValue->getListComponents();
+ }
+ // But wait to know if we have line-height to add it
+ if (isset($aRules['line-height'])) {
+ $oRule = $aRules['line-height'];
+ $mRuleValue = $oRule->getValue();
+ $aLHValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aLHValues[] = $mRuleValue;
+ } else {
+ $aLHValues = $mRuleValue->getListComponents();
+ }
+ if ($aLHValues[0] !== 'normal') {
+ $val = new RuleValueList('/', $this->iLineNo);
+ $val->addListComponent($aFSValues[0]);
+ $val->addListComponent($aLHValues[0]);
+ $oNewRule->addValue($val);
+ }
+ } else {
+ $oNewRule->addValue($aFSValues[0]);
+ }
+ $oRule = $aRules['font-family'];
+ $mRuleValue = $oRule->getValue();
+ $aFFValues = [];
+ if (!$mRuleValue instanceof RuleValueList) {
+ $aFFValues[] = $mRuleValue;
+ } else {
+ $aFFValues = $mRuleValue->getListComponents();
+ }
+ $oFFValue = new RuleValueList(',', $this->iLineNo);
+ $oFFValue->setListComponents($aFFValues);
+ $oNewRule->addValue($oFFValue);
+
+ $this->addRule($oNewRule);
+ foreach ($aFontProperties as $sProperty) {
+ $this->removeRule($sProperty);
+ }
+ }
+
+ /**
+ * @return string
+ *
+ * @throws OutputException
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ *
+ * @throws OutputException
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ if (count($this->aSelectors) === 0) {
+ // If all the selectors have been removed, this declaration block becomes invalid
+ throw new OutputException("Attempt to print declaration block with missing selector", $this->iLineNo);
+ }
+ $sResult = $oOutputFormat->sBeforeDeclarationBlock;
+ $sResult .= $oOutputFormat->implode(
+ $oOutputFormat->spaceBeforeSelectorSeparator() . ',' . $oOutputFormat->spaceAfterSelectorSeparator(),
+ $this->aSelectors
+ );
+ $sResult .= $oOutputFormat->sAfterDeclarationBlockSelectors;
+ $sResult .= $oOutputFormat->spaceBeforeOpeningBrace() . '{';
+ $sResult .= parent::render($oOutputFormat);
+ $sResult .= '}';
+ $sResult .= $oOutputFormat->sAfterDeclarationBlock;
+ return $sResult;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/RuleSet.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/RuleSet.php
new file mode 100644
index 0000000..9404bb0
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/RuleSet/RuleSet.php
@@ -0,0 +1,326 @@
+<?php
+
+namespace Sabberworm\CSS\RuleSet;
+
+use Sabberworm\CSS\Comment\Comment;
+use Sabberworm\CSS\Comment\Commentable;
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+use Sabberworm\CSS\Renderable;
+use Sabberworm\CSS\Rule\Rule;
+
+/**
+ * RuleSet is a generic superclass denoting rules. The typical example for rule sets are declaration block.
+ * However, unknown At-Rules (like `@font-face`) are also rule sets.
+ */
+abstract class RuleSet implements Renderable, Commentable
+{
+ /**
+ * @var array<string, Rule>
+ */
+ private $aRules;
+
+ /**
+ * @var int
+ */
+ protected $iLineNo;
+
+ /**
+ * @var array<array-key, Comment>
+ */
+ protected $aComments;
+
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ $this->aRules = [];
+ $this->iLineNo = $iLineNo;
+ $this->aComments = [];
+ }
+
+ /**
+ * @return void
+ *
+ * @throws UnexpectedTokenException
+ * @throws UnexpectedEOFException
+ */
+ public static function parseRuleSet(ParserState $oParserState, RuleSet $oRuleSet)
+ {
+ while ($oParserState->comes(';')) {
+ $oParserState->consume(';');
+ }
+ while (!$oParserState->comes('}')) {
+ $oRule = null;
+ if ($oParserState->getSettings()->bLenientParsing) {
+ try {
+ $oRule = Rule::parse($oParserState);
+ } catch (UnexpectedTokenException $e) {
+ try {
+ $sConsume = $oParserState->consumeUntil(["\n", ";", '}'], true);
+ // We need to “unfind” the matches to the end of the ruleSet as this will be matched later
+ if ($oParserState->streql(substr($sConsume, -1), '}')) {
+ $oParserState->backtrack(1);
+ } else {
+ while ($oParserState->comes(';')) {
+ $oParserState->consume(';');
+ }
+ }
+ } catch (UnexpectedTokenException $e) {
+ // We’ve reached the end of the document. Just close the RuleSet.
+ return;
+ }
+ }
+ } else {
+ $oRule = Rule::parse($oParserState);
+ }
+ if ($oRule) {
+ $oRuleSet->addRule($oRule);
+ }
+ }
+ $oParserState->consume('}');
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+
+ /**
+ * @param Rule|null $oSibling
+ *
+ * @return void
+ */
+ public function addRule(Rule $oRule, Rule $oSibling = null)
+ {
+ $sRule = $oRule->getRule();
+ if (!isset($this->aRules[$sRule])) {
+ $this->aRules[$sRule] = [];
+ }
+
+ $iPosition = count($this->aRules[$sRule]);
+
+ if ($oSibling !== null) {
+ $iSiblingPos = array_search($oSibling, $this->aRules[$sRule], true);
+ if ($iSiblingPos !== false) {
+ $iPosition = $iSiblingPos;
+ $oRule->setPosition($oSibling->getLineNo(), $oSibling->getColNo() - 1);
+ }
+ }
+ if ($oRule->getLineNo() === 0 && $oRule->getColNo() === 0) {
+ //this node is added manually, give it the next best line
+ $rules = $this->getRules();
+ $pos = count($rules);
+ if ($pos > 0) {
+ $last = $rules[$pos - 1];
+ $oRule->setPosition($last->getLineNo() + 1, 0);
+ }
+ }
+
+ array_splice($this->aRules[$sRule], $iPosition, 0, [$oRule]);
+ }
+
+ /**
+ * Returns all rules matching the given rule name
+ *
+ * @example $oRuleSet->getRules('font') // returns array(0 => $oRule, …) or array().
+ *
+ * @example $oRuleSet->getRules('font-')
+ * //returns an array of all rules either beginning with font- or matching font.
+ *
+ * @param Rule|string|null $mRule
+ * Pattern to search for. If null, returns all rules.
+ * If the pattern ends with a dash, all rules starting with the pattern are returned
+ * as well as one matching the pattern with the dash excluded.
+ * Passing a Rule behaves like calling `getRules($mRule->getRule())`.
+ *
+ * @return array<int, Rule>
+ */
+ public function getRules($mRule = null)
+ {
+ if ($mRule instanceof Rule) {
+ $mRule = $mRule->getRule();
+ }
+ /** @var array<int, Rule> $aResult */
+ $aResult = [];
+ foreach ($this->aRules as $sName => $aRules) {
+ // Either no search rule is given or the search rule matches the found rule exactly
+ // or the search rule ends in “-” and the found rule starts with the search rule.
+ if (
+ !$mRule || $sName === $mRule
+ || (
+ strrpos($mRule, '-') === strlen($mRule) - strlen('-')
+ && (strpos($sName, $mRule) === 0 || $sName === substr($mRule, 0, -1))
+ )
+ ) {
+ $aResult = array_merge($aResult, $aRules);
+ }
+ }
+ usort($aResult, function (Rule $first, Rule $second) {
+ if ($first->getLineNo() === $second->getLineNo()) {
+ return $first->getColNo() - $second->getColNo();
+ }
+ return $first->getLineNo() - $second->getLineNo();
+ });
+ return $aResult;
+ }
+
+ /**
+ * Overrides all the rules of this set.
+ *
+ * @param array<array-key, Rule> $aRules The rules to override with.
+ *
+ * @return void
+ */
+ public function setRules(array $aRules)
+ {
+ $this->aRules = [];
+ foreach ($aRules as $rule) {
+ $this->addRule($rule);
+ }
+ }
+
+ /**
+ * Returns all rules matching the given pattern and returns them in an associative array with the rule’s name
+ * as keys. This method exists mainly for backwards-compatibility and is really only partially useful.
+ *
+ * Note: This method loses some information: Calling this (with an argument of `background-`) on a declaration block
+ * like `{ background-color: green; background-color; rgba(0, 127, 0, 0.7); }` will only yield an associative array
+ * containing the rgba-valued rule while `getRules()` would yield an indexed array containing both.
+ *
+ * @param Rule|string|null $mRule $mRule
+ * Pattern to search for. If null, returns all rules. If the pattern ends with a dash,
+ * all rules starting with the pattern are returned as well as one matching the pattern with the dash
+ * excluded. Passing a Rule behaves like calling `getRules($mRule->getRule())`.
+ *
+ * @return array<string, Rule>
+ */
+ public function getRulesAssoc($mRule = null)
+ {
+ /** @var array<string, Rule> $aResult */
+ $aResult = [];
+ foreach ($this->getRules($mRule) as $oRule) {
+ $aResult[$oRule->getRule()] = $oRule;
+ }
+ return $aResult;
+ }
+
+ /**
+ * Removes a rule from this RuleSet. This accepts all the possible values that `getRules()` accepts.
+ *
+ * If given a Rule, it will only remove this particular rule (by identity).
+ * If given a name, it will remove all rules by that name.
+ *
+ * Note: this is different from pre-v.2.0 behaviour of PHP-CSS-Parser, where passing a Rule instance would
+ * remove all rules with the same name. To get the old behaviour, use `removeRule($oRule->getRule())`.
+ *
+ * @param Rule|string|null $mRule
+ * pattern to remove. If $mRule is null, all rules are removed. If the pattern ends in a dash,
+ * all rules starting with the pattern are removed as well as one matching the pattern with the dash
+ * excluded. Passing a Rule behaves matches by identity.
+ *
+ * @return void
+ */
+ public function removeRule($mRule)
+ {
+ if ($mRule instanceof Rule) {
+ $sRule = $mRule->getRule();
+ if (!isset($this->aRules[$sRule])) {
+ return;
+ }
+ foreach ($this->aRules[$sRule] as $iKey => $oRule) {
+ if ($oRule === $mRule) {
+ unset($this->aRules[$sRule][$iKey]);
+ }
+ }
+ } else {
+ foreach ($this->aRules as $sName => $aRules) {
+ // Either no search rule is given or the search rule matches the found rule exactly
+ // or the search rule ends in “-” and the found rule starts with the search rule or equals it
+ // (without the trailing dash).
+ if (
+ !$mRule || $sName === $mRule
+ || (strrpos($mRule, '-') === strlen($mRule) - strlen('-')
+ && (strpos($sName, $mRule) === 0 || $sName === substr($mRule, 0, -1)))
+ ) {
+ unset($this->aRules[$sName]);
+ }
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $sResult = '';
+ $bIsFirst = true;
+ foreach ($this->aRules as $aRules) {
+ foreach ($aRules as $oRule) {
+ $sRendered = $oOutputFormat->safely(function () use ($oRule, $oOutputFormat) {
+ return $oRule->render($oOutputFormat->nextLevel());
+ });
+ if ($sRendered === null) {
+ continue;
+ }
+ if ($bIsFirst) {
+ $bIsFirst = false;
+ $sResult .= $oOutputFormat->nextLevel()->spaceBeforeRules();
+ } else {
+ $sResult .= $oOutputFormat->nextLevel()->spaceBetweenRules();
+ }
+ $sResult .= $sRendered;
+ }
+ }
+
+ if (!$bIsFirst) {
+ // Had some output
+ $sResult .= $oOutputFormat->spaceAfterRules();
+ }
+
+ return $oOutputFormat->removeLastSemicolon($sResult);
+ }
+
+ /**
+ * @param array<string, Comment> $aComments
+ *
+ * @return void
+ */
+ public function addComments(array $aComments)
+ {
+ $this->aComments = array_merge($this->aComments, $aComments);
+ }
+
+ /**
+ * @return array<string, Comment>
+ */
+ public function getComments()
+ {
+ return $this->aComments;
+ }
+
+ /**
+ * @param array<string, Comment> $aComments
+ *
+ * @return void
+ */
+ public function setComments(array $aComments)
+ {
+ $this->aComments = $aComments;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Settings.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Settings.php
new file mode 100644
index 0000000..7b85809
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Settings.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Sabberworm\CSS;
+
+/**
+ * Parser settings class.
+ *
+ * Configure parser behaviour here.
+ */
+class Settings
+{
+ /**
+ * Multi-byte string support.
+ * If true (mbstring extension must be enabled), will use (slower) `mb_strlen`, `mb_convert_case`, `mb_substr`
+ * and `mb_strpos` functions. Otherwise, the normal (ASCII-Only) functions will be used.
+ *
+ * @var bool
+ */
+ public $bMultibyteSupport;
+
+ /**
+ * The default charset for the CSS if no `@charset` rule is found. Defaults to utf-8.
+ *
+ * @var string
+ */
+ public $sDefaultCharset = 'utf-8';
+
+ /**
+ * Lenient parsing. When used (which is true by default), the parser will not choke
+ * on unexpected tokens but simply ignore them.
+ *
+ * @var bool
+ */
+ public $bLenientParsing = true;
+
+ private function __construct()
+ {
+ $this->bMultibyteSupport = extension_loaded('mbstring');
+ }
+
+ /**
+ * @return self new instance
+ */
+ public static function create()
+ {
+ return new Settings();
+ }
+
+ /**
+ * @param bool $bMultibyteSupport
+ *
+ * @return self fluent interface
+ */
+ public function withMultibyteSupport($bMultibyteSupport = true)
+ {
+ $this->bMultibyteSupport = $bMultibyteSupport;
+ return $this;
+ }
+
+ /**
+ * @param string $sDefaultCharset
+ *
+ * @return self fluent interface
+ */
+ public function withDefaultCharset($sDefaultCharset)
+ {
+ $this->sDefaultCharset = $sDefaultCharset;
+ return $this;
+ }
+
+ /**
+ * @param bool $bLenientParsing
+ *
+ * @return self fluent interface
+ */
+ public function withLenientParsing($bLenientParsing = true)
+ {
+ $this->bLenientParsing = $bLenientParsing;
+ return $this;
+ }
+
+ /**
+ * @return self fluent interface
+ */
+ public function beStrict()
+ {
+ return $this->withLenientParsing(false);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CSSFunction.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CSSFunction.php
new file mode 100644
index 0000000..e6b8c11
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CSSFunction.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\OutputFormat;
+
+class CSSFunction extends ValueList
+{
+ /**
+ * @var string
+ */
+ protected $sName;
+
+ /**
+ * @param string $sName
+ * @param RuleValueList|array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aArguments
+ * @param string $sSeparator
+ * @param int $iLineNo
+ */
+ public function __construct($sName, $aArguments, $sSeparator = ',', $iLineNo = 0)
+ {
+ if ($aArguments instanceof RuleValueList) {
+ $sSeparator = $aArguments->getListSeparator();
+ $aArguments = $aArguments->getListComponents();
+ }
+ $this->sName = $sName;
+ $this->iLineNo = $iLineNo;
+ parent::__construct($aArguments, $sSeparator, $iLineNo);
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->sName;
+ }
+
+ /**
+ * @param string $sName
+ *
+ * @return void
+ */
+ public function setName($sName)
+ {
+ $this->sName = $sName;
+ }
+
+ /**
+ * @return array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string>
+ */
+ public function getArguments()
+ {
+ return $this->aComponents;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $aArguments = parent::render($oOutputFormat);
+ return "{$this->sName}({$aArguments})";
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CSSString.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CSSString.php
new file mode 100644
index 0000000..9fafedd
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CSSString.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\SourceException;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+
+class CSSString extends PrimitiveValue
+{
+ /**
+ * @var string
+ */
+ private $sString;
+
+ /**
+ * @param string $sString
+ * @param int $iLineNo
+ */
+ public function __construct($sString, $iLineNo = 0)
+ {
+ $this->sString = $sString;
+ parent::__construct($iLineNo);
+ }
+
+ /**
+ * @return CSSString
+ *
+ * @throws SourceException
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public static function parse(ParserState $oParserState)
+ {
+ $sBegin = $oParserState->peek();
+ $sQuote = null;
+ if ($sBegin === "'") {
+ $sQuote = "'";
+ } elseif ($sBegin === '"') {
+ $sQuote = '"';
+ }
+ if ($sQuote !== null) {
+ $oParserState->consume($sQuote);
+ }
+ $sResult = "";
+ $sContent = null;
+ if ($sQuote === null) {
+ // Unquoted strings end in whitespace or with braces, brackets, parentheses
+ while (!preg_match('/[\\s{}()<>\\[\\]]/isu', $oParserState->peek())) {
+ $sResult .= $oParserState->parseCharacter(false);
+ }
+ } else {
+ while (!$oParserState->comes($sQuote)) {
+ $sContent = $oParserState->parseCharacter(false);
+ if ($sContent === null) {
+ throw new SourceException(
+ "Non-well-formed quoted string {$oParserState->peek(3)}",
+ $oParserState->currentLine()
+ );
+ }
+ $sResult .= $sContent;
+ }
+ $oParserState->consume($sQuote);
+ }
+ return new CSSString($sResult, $oParserState->currentLine());
+ }
+
+ /**
+ * @param string $sString
+ *
+ * @return void
+ */
+ public function setString($sString)
+ {
+ $this->sString = $sString;
+ }
+
+ /**
+ * @return string
+ */
+ public function getString()
+ {
+ return $this->sString;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $sString = addslashes($this->sString);
+ $sString = str_replace("\n", '\A', $sString);
+ return $oOutputFormat->getStringQuotingType() . $sString . $oOutputFormat->getStringQuotingType();
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CalcFunction.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CalcFunction.php
new file mode 100644
index 0000000..5c92e0c
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CalcFunction.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+
+class CalcFunction extends CSSFunction
+{
+ /**
+ * @var int
+ */
+ const T_OPERAND = 1;
+
+ /**
+ * @var int
+ */
+ const T_OPERATOR = 2;
+
+ /**
+ * @return CalcFunction
+ *
+ * @throws UnexpectedTokenException
+ * @throws UnexpectedEOFException
+ */
+ public static function parse(ParserState $oParserState)
+ {
+ $aOperators = ['+', '-', '*', '/'];
+ $sFunction = trim($oParserState->consumeUntil('(', false, true));
+ $oCalcList = new CalcRuleValueList($oParserState->currentLine());
+ $oList = new RuleValueList(',', $oParserState->currentLine());
+ $iNestingLevel = 0;
+ $iLastComponentType = null;
+ while (!$oParserState->comes(')') || $iNestingLevel > 0) {
+ $oParserState->consumeWhiteSpace();
+ if ($oParserState->comes('(')) {
+ $iNestingLevel++;
+ $oCalcList->addListComponent($oParserState->consume(1));
+ $oParserState->consumeWhiteSpace();
+ continue;
+ } elseif ($oParserState->comes(')')) {
+ $iNestingLevel--;
+ $oCalcList->addListComponent($oParserState->consume(1));
+ $oParserState->consumeWhiteSpace();
+ continue;
+ }
+ if ($iLastComponentType != CalcFunction::T_OPERAND) {
+ $oVal = Value::parsePrimitiveValue($oParserState);
+ $oCalcList->addListComponent($oVal);
+ $iLastComponentType = CalcFunction::T_OPERAND;
+ } else {
+ if (in_array($oParserState->peek(), $aOperators)) {
+ if (($oParserState->comes('-') || $oParserState->comes('+'))) {
+ if (
+ $oParserState->peek(1, -1) != ' '
+ || !($oParserState->comes('- ')
+ || $oParserState->comes('+ '))
+ ) {
+ throw new UnexpectedTokenException(
+ " {$oParserState->peek()} ",
+ $oParserState->peek(1, -1) . $oParserState->peek(2),
+ 'literal',
+ $oParserState->currentLine()
+ );
+ }
+ }
+ $oCalcList->addListComponent($oParserState->consume(1));
+ $iLastComponentType = CalcFunction::T_OPERATOR;
+ } else {
+ throw new UnexpectedTokenException(
+ sprintf(
+ 'Next token was expected to be an operand of type %s. Instead "%s" was found.',
+ implode(', ', $aOperators),
+ $oVal
+ ),
+ '',
+ 'custom',
+ $oParserState->currentLine()
+ );
+ }
+ }
+ $oParserState->consumeWhiteSpace();
+ }
+ $oList->addListComponent($oCalcList);
+ $oParserState->consume(')');
+ return new CalcFunction($sFunction, $oList, ',', $oParserState->currentLine());
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CalcRuleValueList.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CalcRuleValueList.php
new file mode 100644
index 0000000..7dbd26a
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/CalcRuleValueList.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\OutputFormat;
+
+class CalcRuleValueList extends RuleValueList
+{
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ parent::__construct(',', $iLineNo);
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ return $oOutputFormat->implode(' ', $this->aComponents);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Color.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Color.php
new file mode 100644
index 0000000..8dc5296
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Color.php
@@ -0,0 +1,166 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+
+class Color extends CSSFunction
+{
+ /**
+ * @param array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aColor
+ * @param int $iLineNo
+ */
+ public function __construct(array $aColor, $iLineNo = 0)
+ {
+ parent::__construct(implode('', array_keys($aColor)), $aColor, ',', $iLineNo);
+ }
+
+ /**
+ * @return Color|CSSFunction
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public static function parse(ParserState $oParserState)
+ {
+ $aColor = [];
+ if ($oParserState->comes('#')) {
+ $oParserState->consume('#');
+ $sValue = $oParserState->parseIdentifier(false);
+ if ($oParserState->strlen($sValue) === 3) {
+ $sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2];
+ } elseif ($oParserState->strlen($sValue) === 4) {
+ $sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2] . $sValue[3]
+ . $sValue[3];
+ }
+
+ if ($oParserState->strlen($sValue) === 8) {
+ $aColor = [
+ 'r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $oParserState->currentLine()),
+ 'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $oParserState->currentLine()),
+ 'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $oParserState->currentLine()),
+ 'a' => new Size(
+ round(self::mapRange(intval($sValue[6] . $sValue[7], 16), 0, 255, 0, 1), 2),
+ null,
+ true,
+ $oParserState->currentLine()
+ ),
+ ];
+ } else {
+ $aColor = [
+ 'r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $oParserState->currentLine()),
+ 'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $oParserState->currentLine()),
+ 'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $oParserState->currentLine()),
+ ];
+ }
+ } else {
+ $sColorMode = $oParserState->parseIdentifier(true);
+ $oParserState->consumeWhiteSpace();
+ $oParserState->consume('(');
+
+ $bContainsVar = false;
+ $iLength = $oParserState->strlen($sColorMode);
+ for ($i = 0; $i < $iLength; ++$i) {
+ $oParserState->consumeWhiteSpace();
+ if ($oParserState->comes('var')) {
+ $aColor[$sColorMode[$i]] = CSSFunction::parseIdentifierOrFunction($oParserState);
+ $bContainsVar = true;
+ } else {
+ $aColor[$sColorMode[$i]] = Size::parse($oParserState, true);
+ }
+
+ if ($bContainsVar && $oParserState->comes(')')) {
+ // With a var argument the function can have fewer arguments
+ break;
+ }
+
+ $oParserState->consumeWhiteSpace();
+ if ($i < ($iLength - 1)) {
+ $oParserState->consume(',');
+ }
+ }
+ $oParserState->consume(')');
+
+ if ($bContainsVar) {
+ return new CSSFunction($sColorMode, array_values($aColor), ',', $oParserState->currentLine());
+ }
+ }
+ return new Color($aColor, $oParserState->currentLine());
+ }
+
+ /**
+ * @param float $fVal
+ * @param float $fFromMin
+ * @param float $fFromMax
+ * @param float $fToMin
+ * @param float $fToMax
+ *
+ * @return float
+ */
+ private static function mapRange($fVal, $fFromMin, $fFromMax, $fToMin, $fToMax)
+ {
+ $fFromRange = $fFromMax - $fFromMin;
+ $fToRange = $fToMax - $fToMin;
+ $fMultiplier = $fToRange / $fFromRange;
+ $fNewVal = $fVal - $fFromMin;
+ $fNewVal *= $fMultiplier;
+ return $fNewVal + $fToMin;
+ }
+
+ /**
+ * @return array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string>
+ */
+ public function getColor()
+ {
+ return $this->aComponents;
+ }
+
+ /**
+ * @param array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aColor
+ *
+ * @return void
+ */
+ public function setColor(array $aColor)
+ {
+ $this->setName(implode('', array_keys($aColor)));
+ $this->aComponents = $aColor;
+ }
+
+ /**
+ * @return string
+ */
+ public function getColorDescription()
+ {
+ return $this->getName();
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ // Shorthand RGB color values
+ if ($oOutputFormat->getRGBHashNotation() && implode('', array_keys($this->aComponents)) === 'rgb') {
+ $sResult = sprintf(
+ '%02x%02x%02x',
+ $this->aComponents['r']->getSize(),
+ $this->aComponents['g']->getSize(),
+ $this->aComponents['b']->getSize()
+ );
+ return '#' . (($sResult[0] == $sResult[1]) && ($sResult[2] == $sResult[3]) && ($sResult[4] == $sResult[5])
+ ? "$sResult[0]$sResult[2]$sResult[4]" : $sResult);
+ }
+ return parent::render($oOutputFormat);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/LineName.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/LineName.php
new file mode 100644
index 0000000..e231ce3
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/LineName.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+
+class LineName extends ValueList
+{
+ /**
+ * @param array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aComponents
+ * @param int $iLineNo
+ */
+ public function __construct(array $aComponents = [], $iLineNo = 0)
+ {
+ parent::__construct($aComponents, ' ', $iLineNo);
+ }
+
+ /**
+ * @return LineName
+ *
+ * @throws UnexpectedTokenException
+ * @throws UnexpectedEOFException
+ */
+ public static function parse(ParserState $oParserState)
+ {
+ $oParserState->consume('[');
+ $oParserState->consumeWhiteSpace();
+ $aNames = [];
+ do {
+ if ($oParserState->getSettings()->bLenientParsing) {
+ try {
+ $aNames[] = $oParserState->parseIdentifier();
+ } catch (UnexpectedTokenException $e) {
+ if (!$oParserState->comes(']')) {
+ throw $e;
+ }
+ }
+ } else {
+ $aNames[] = $oParserState->parseIdentifier();
+ }
+ $oParserState->consumeWhiteSpace();
+ } while (!$oParserState->comes(']'));
+ $oParserState->consume(']');
+ return new LineName($aNames, $oParserState->currentLine());
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ return '[' . parent::render(OutputFormat::createCompact()) . ']';
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/PrimitiveValue.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/PrimitiveValue.php
new file mode 100644
index 0000000..055a439
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/PrimitiveValue.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+abstract class PrimitiveValue extends Value
+{
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/RuleValueList.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/RuleValueList.php
new file mode 100644
index 0000000..5d533a7
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/RuleValueList.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+class RuleValueList extends ValueList
+{
+ /**
+ * @param string $sSeparator
+ * @param int $iLineNo
+ */
+ public function __construct($sSeparator = ',', $iLineNo = 0)
+ {
+ parent::__construct([], $sSeparator, $iLineNo);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Size.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Size.php
new file mode 100644
index 0000000..b3801dc
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Size.php
@@ -0,0 +1,209 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+
+class Size extends PrimitiveValue
+{
+ /**
+ * vh/vw/vm(ax)/vmin/rem are absolute insofar as they don’t scale to the immediate parent (only the viewport)
+ *
+ * @var array<int, string>
+ */
+ const ABSOLUTE_SIZE_UNITS = ['px', 'cm', 'mm', 'mozmm', 'in', 'pt', 'pc', 'vh', 'vw', 'vmin', 'vmax', 'rem'];
+
+ /**
+ * @var array<int, string>
+ */
+ const RELATIVE_SIZE_UNITS = ['%', 'em', 'ex', 'ch', 'fr'];
+
+ /**
+ * @var array<int, string>
+ */
+ const NON_SIZE_UNITS = ['deg', 'grad', 'rad', 's', 'ms', 'turns', 'Hz', 'kHz'];
+
+ /**
+ * @var array<int, array<string, string>>|null
+ */
+ private static $SIZE_UNITS = null;
+
+ /**
+ * @var float
+ */
+ private $fSize;
+
+ /**
+ * @var string|null
+ */
+ private $sUnit;
+
+ /**
+ * @var bool
+ */
+ private $bIsColorComponent;
+
+ /**
+ * @param float|int|string $fSize
+ * @param string|null $sUnit
+ * @param bool $bIsColorComponent
+ * @param int $iLineNo
+ */
+ public function __construct($fSize, $sUnit = null, $bIsColorComponent = false, $iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ $this->fSize = (float)$fSize;
+ $this->sUnit = $sUnit;
+ $this->bIsColorComponent = $bIsColorComponent;
+ }
+
+ /**
+ * @param bool $bIsColorComponent
+ *
+ * @return Size
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public static function parse(ParserState $oParserState, $bIsColorComponent = false)
+ {
+ $sSize = '';
+ if ($oParserState->comes('-')) {
+ $sSize .= $oParserState->consume('-');
+ }
+ while (is_numeric($oParserState->peek()) || $oParserState->comes('.')) {
+ if ($oParserState->comes('.')) {
+ $sSize .= $oParserState->consume('.');
+ } else {
+ $sSize .= $oParserState->consume(1);
+ }
+ }
+
+ $sUnit = null;
+ $aSizeUnits = self::getSizeUnits();
+ foreach ($aSizeUnits as $iLength => &$aValues) {
+ $sKey = strtolower($oParserState->peek($iLength));
+ if (array_key_exists($sKey, $aValues)) {
+ if (($sUnit = $aValues[$sKey]) !== null) {
+ $oParserState->consume($iLength);
+ break;
+ }
+ }
+ }
+ return new Size((float)$sSize, $sUnit, $bIsColorComponent, $oParserState->currentLine());
+ }
+
+ /**
+ * @return array<int, array<string, string>>
+ */
+ private static function getSizeUnits()
+ {
+ if (!is_array(self::$SIZE_UNITS)) {
+ self::$SIZE_UNITS = [];
+ foreach (array_merge(self::ABSOLUTE_SIZE_UNITS, self::RELATIVE_SIZE_UNITS, self::NON_SIZE_UNITS) as $val) {
+ $iSize = strlen($val);
+ if (!isset(self::$SIZE_UNITS[$iSize])) {
+ self::$SIZE_UNITS[$iSize] = [];
+ }
+ self::$SIZE_UNITS[$iSize][strtolower($val)] = $val;
+ }
+
+ krsort(self::$SIZE_UNITS, SORT_NUMERIC);
+ }
+
+ return self::$SIZE_UNITS;
+ }
+
+ /**
+ * @param string $sUnit
+ *
+ * @return void
+ */
+ public function setUnit($sUnit)
+ {
+ $this->sUnit = $sUnit;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getUnit()
+ {
+ return $this->sUnit;
+ }
+
+ /**
+ * @param float|int|string $fSize
+ */
+ public function setSize($fSize)
+ {
+ $this->fSize = (float)$fSize;
+ }
+
+ /**
+ * @return float
+ */
+ public function getSize()
+ {
+ return $this->fSize;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isColorComponent()
+ {
+ return $this->bIsColorComponent;
+ }
+
+ /**
+ * Returns whether the number stored in this Size really represents a size (as in a length of something on screen).
+ *
+ * @return false if the unit an angle, a duration, a frequency or the number is a component in a Color object.
+ */
+ public function isSize()
+ {
+ if (in_array($this->sUnit, self::NON_SIZE_UNITS, true)) {
+ return false;
+ }
+ return !$this->isColorComponent();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRelative()
+ {
+ if (in_array($this->sUnit, self::RELATIVE_SIZE_UNITS, true)) {
+ return true;
+ }
+ if ($this->sUnit === null && $this->fSize != 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ $l = localeconv();
+ $sPoint = preg_quote($l['decimal_point'], '/');
+ $sSize = preg_match("/[\d\.]+e[+-]?\d+/i", (string)$this->fSize)
+ ? preg_replace("/$sPoint?0+$/", "", sprintf("%f", $this->fSize)) : $this->fSize;
+ return preg_replace(["/$sPoint/", "/^(-?)0\./"], ['.', '$1.'], $sSize)
+ . ($this->sUnit === null ? '' : $this->sUnit);
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/URL.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/URL.php
new file mode 100644
index 0000000..1467d50
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/URL.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\OutputFormat;
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\SourceException;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+
+class URL extends PrimitiveValue
+{
+ /**
+ * @var CSSString
+ */
+ private $oURL;
+
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct(CSSString $oURL, $iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ $this->oURL = $oURL;
+ }
+
+ /**
+ * @return URL
+ *
+ * @throws SourceException
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public static function parse(ParserState $oParserState)
+ {
+ $bUseUrl = $oParserState->comes('url', true);
+ if ($bUseUrl) {
+ $oParserState->consume('url');
+ $oParserState->consumeWhiteSpace();
+ $oParserState->consume('(');
+ }
+ $oParserState->consumeWhiteSpace();
+ $oResult = new URL(CSSString::parse($oParserState), $oParserState->currentLine());
+ if ($bUseUrl) {
+ $oParserState->consumeWhiteSpace();
+ $oParserState->consume(')');
+ }
+ return $oResult;
+ }
+
+ /**
+ * @return void
+ */
+ public function setURL(CSSString $oURL)
+ {
+ $this->oURL = $oURL;
+ }
+
+ /**
+ * @return CSSString
+ */
+ public function getURL()
+ {
+ return $this->oURL;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ return "url({$this->oURL->render($oOutputFormat)})";
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Value.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Value.php
new file mode 100644
index 0000000..66cb9fd
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/Value.php
@@ -0,0 +1,198 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\Parsing\ParserState;
+use Sabberworm\CSS\Parsing\SourceException;
+use Sabberworm\CSS\Parsing\UnexpectedEOFException;
+use Sabberworm\CSS\Parsing\UnexpectedTokenException;
+use Sabberworm\CSS\Renderable;
+
+abstract class Value implements Renderable
+{
+ /**
+ * @var int
+ */
+ protected $iLineNo;
+
+ /**
+ * @param int $iLineNo
+ */
+ public function __construct($iLineNo = 0)
+ {
+ $this->iLineNo = $iLineNo;
+ }
+
+ /**
+ * @param array<array-key, string> $aListDelimiters
+ *
+ * @return RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string
+ *
+ * @throws UnexpectedTokenException
+ * @throws UnexpectedEOFException
+ */
+ public static function parseValue(ParserState $oParserState, array $aListDelimiters = [])
+ {
+ /** @var array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aStack */
+ $aStack = [];
+ $oParserState->consumeWhiteSpace();
+ //Build a list of delimiters and parsed values
+ while (
+ !($oParserState->comes('}') || $oParserState->comes(';') || $oParserState->comes('!')
+ || $oParserState->comes(')')
+ || $oParserState->comes('\\'))
+ ) {
+ if (count($aStack) > 0) {
+ $bFoundDelimiter = false;
+ foreach ($aListDelimiters as $sDelimiter) {
+ if ($oParserState->comes($sDelimiter)) {
+ array_push($aStack, $oParserState->consume($sDelimiter));
+ $oParserState->consumeWhiteSpace();
+ $bFoundDelimiter = true;
+ break;
+ }
+ }
+ if (!$bFoundDelimiter) {
+ //Whitespace was the list delimiter
+ array_push($aStack, ' ');
+ }
+ }
+ array_push($aStack, self::parsePrimitiveValue($oParserState));
+ $oParserState->consumeWhiteSpace();
+ }
+ // Convert the list to list objects
+ foreach ($aListDelimiters as $sDelimiter) {
+ if (count($aStack) === 1) {
+ return $aStack[0];
+ }
+ $iStartPosition = null;
+ while (($iStartPosition = array_search($sDelimiter, $aStack, true)) !== false) {
+ $iLength = 2; //Number of elements to be joined
+ for ($i = $iStartPosition + 2; $i < count($aStack); $i += 2, ++$iLength) {
+ if ($sDelimiter !== $aStack[$i]) {
+ break;
+ }
+ }
+ $oList = new RuleValueList($sDelimiter, $oParserState->currentLine());
+ for ($i = $iStartPosition - 1; $i - $iStartPosition + 1 < $iLength * 2; $i += 2) {
+ $oList->addListComponent($aStack[$i]);
+ }
+ array_splice($aStack, $iStartPosition - 1, $iLength * 2 - 1, [$oList]);
+ }
+ }
+ if (!isset($aStack[0])) {
+ throw new UnexpectedTokenException(
+ " {$oParserState->peek()} ",
+ $oParserState->peek(1, -1) . $oParserState->peek(2),
+ 'literal',
+ $oParserState->currentLine()
+ );
+ }
+ return $aStack[0];
+ }
+
+ /**
+ * @param bool $bIgnoreCase
+ *
+ * @return CSSFunction|string
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ public static function parseIdentifierOrFunction(ParserState $oParserState, $bIgnoreCase = false)
+ {
+ $sResult = $oParserState->parseIdentifier($bIgnoreCase);
+
+ if ($oParserState->comes('(')) {
+ $oParserState->consume('(');
+ $aArguments = Value::parseValue($oParserState, ['=', ' ', ',']);
+ $sResult = new CSSFunction($sResult, $aArguments, ',', $oParserState->currentLine());
+ $oParserState->consume(')');
+ }
+
+ return $sResult;
+ }
+
+ /**
+ * @return CSSFunction|CSSString|LineName|Size|URL|string
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ * @throws SourceException
+ */
+ public static function parsePrimitiveValue(ParserState $oParserState)
+ {
+ $oValue = null;
+ $oParserState->consumeWhiteSpace();
+ if (
+ is_numeric($oParserState->peek())
+ || ($oParserState->comes('-.')
+ && is_numeric($oParserState->peek(1, 2)))
+ || (($oParserState->comes('-') || $oParserState->comes('.')) && is_numeric($oParserState->peek(1, 1)))
+ ) {
+ $oValue = Size::parse($oParserState);
+ } elseif ($oParserState->comes('#') || $oParserState->comes('rgb', true) || $oParserState->comes('hsl', true)) {
+ $oValue = Color::parse($oParserState);
+ } elseif ($oParserState->comes('url', true)) {
+ $oValue = URL::parse($oParserState);
+ } elseif (
+ $oParserState->comes('calc', true) || $oParserState->comes('-webkit-calc', true)
+ || $oParserState->comes('-moz-calc', true)
+ ) {
+ $oValue = CalcFunction::parse($oParserState);
+ } elseif ($oParserState->comes("'") || $oParserState->comes('"')) {
+ $oValue = CSSString::parse($oParserState);
+ } elseif ($oParserState->comes("progid:") && $oParserState->getSettings()->bLenientParsing) {
+ $oValue = self::parseMicrosoftFilter($oParserState);
+ } elseif ($oParserState->comes("[")) {
+ $oValue = LineName::parse($oParserState);
+ } elseif ($oParserState->comes("U+")) {
+ $oValue = self::parseUnicodeRangeValue($oParserState);
+ } else {
+ $oValue = self::parseIdentifierOrFunction($oParserState);
+ }
+ $oParserState->consumeWhiteSpace();
+ return $oValue;
+ }
+
+ /**
+ * @return CSSFunction
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ private static function parseMicrosoftFilter(ParserState $oParserState)
+ {
+ $sFunction = $oParserState->consumeUntil('(', false, true);
+ $aArguments = Value::parseValue($oParserState, [',', '=']);
+ return new CSSFunction($sFunction, $aArguments, ',', $oParserState->currentLine());
+ }
+
+ /**
+ * @return string
+ *
+ * @throws UnexpectedEOFException
+ * @throws UnexpectedTokenException
+ */
+ private static function parseUnicodeRangeValue(ParserState $oParserState)
+ {
+ $iCodepointMaxLength = 6; // Code points outside BMP can use up to six digits
+ $sRange = "";
+ $oParserState->consume("U+");
+ do {
+ if ($oParserState->comes('-')) {
+ $iCodepointMaxLength = 13; // Max length is 2 six digit code points + the dash(-) between them
+ }
+ $sRange .= $oParserState->consume(1);
+ } while (strlen($sRange) < $iCodepointMaxLength && preg_match("/[A-Fa-f0-9\?-]/", $oParserState->peek()));
+ return "U+{$sRange}";
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineNo()
+ {
+ return $this->iLineNo;
+ }
+}
diff --git a/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/ValueList.php b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/ValueList.php
new file mode 100644
index 0000000..af5348b
--- /dev/null
+++ b/library/vendor/dompdf/vendor/sabberworm/php-css-parser/src/Value/ValueList.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Sabberworm\CSS\Value;
+
+use Sabberworm\CSS\OutputFormat;
+
+abstract class ValueList extends Value
+{
+ /**
+ * @var array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string>
+ */
+ protected $aComponents;
+
+ /**
+ * @var string
+ */
+ protected $sSeparator;
+
+ /**
+ * phpcs:ignore Generic.Files.LineLength
+ * @param array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string>|RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string $aComponents
+ * @param string $sSeparator
+ * @param int $iLineNo
+ */
+ public function __construct($aComponents = [], $sSeparator = ',', $iLineNo = 0)
+ {
+ parent::__construct($iLineNo);
+ if (!is_array($aComponents)) {
+ $aComponents = [$aComponents];
+ }
+ $this->aComponents = $aComponents;
+ $this->sSeparator = $sSeparator;
+ }
+
+ /**
+ * @param RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string $mComponent
+ *
+ * @return void
+ */
+ public function addListComponent($mComponent)
+ {
+ $this->aComponents[] = $mComponent;
+ }
+
+ /**
+ * @return array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string>
+ */
+ public function getListComponents()
+ {
+ return $this->aComponents;
+ }
+
+ /**
+ * @param array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aComponents
+ *
+ * @return void
+ */
+ public function setListComponents(array $aComponents)
+ {
+ $this->aComponents = $aComponents;
+ }
+
+ /**
+ * @return string
+ */
+ public function getListSeparator()
+ {
+ return $this->sSeparator;
+ }
+
+ /**
+ * @param string $sSeparator
+ *
+ * @return void
+ */
+ public function setListSeparator($sSeparator)
+ {
+ $this->sSeparator = $sSeparator;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render(new OutputFormat());
+ }
+
+ /**
+ * @return string
+ */
+ public function render(OutputFormat $oOutputFormat)
+ {
+ return $oOutputFormat->implode(
+ $oOutputFormat->spaceBeforeListArgumentSeparator($this->sSeparator) . $this->sSeparator
+ . $oOutputFormat->spaceAfterListArgumentSeparator($this->sSeparator),
+ $this->aComponents
+ );
+ }
+}