diff --git a/composer.lock b/composer.lock
index 513da5531..0a6f574a8 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1352,24 +1352,23 @@
},
{
"name": "twig/twig",
- "version": "v3.11.0",
+ "version": "v3.12.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d"
+ "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
- "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea",
+ "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea",
"shasum": ""
},
"require": {
- "php": ">=7.2.5",
+ "php": ">=8.0.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3",
- "symfony/polyfill-php80": "^1.22",
"symfony/polyfill-php81": "^1.29"
},
"require-dev": {
@@ -1416,7 +1415,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.11.0"
+ "source": "https://github.com/twigphp/Twig/tree/v3.12.0"
},
"funding": [
{
@@ -1428,20 +1427,20 @@
"type": "tidelift"
}
],
- "time": "2024-08-08T16:15:16+00:00"
+ "time": "2024-08-29T09:51:12+00:00"
},
{
"name": "zoujingli/wechat-developer",
- "version": "v1.2.54",
+ "version": "v1.2.59",
"source": {
"type": "git",
"url": "https://github.com/zoujingli/WeChatDeveloper.git",
- "reference": "812aae37ffc5b6038b03163796f6eed97bb79730"
+ "reference": "d422e5dc1768033dd6849f7e23180ee7da02d8ee"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zoujingli/WeChatDeveloper/zipball/812aae37ffc5b6038b03163796f6eed97bb79730",
- "reference": "812aae37ffc5b6038b03163796f6eed97bb79730",
+ "url": "https://api.github.com/repos/zoujingli/WeChatDeveloper/zipball/d422e5dc1768033dd6849f7e23180ee7da02d8ee",
+ "reference": "d422e5dc1768033dd6849f7e23180ee7da02d8ee",
"shasum": ""
},
"require": {
@@ -1457,6 +1456,9 @@
},
"type": "library",
"autoload": {
+ "files": [
+ "helper.php"
+ ],
"psr-4": {
"WePay\\": "WePay",
"AliPay\\": "AliPay",
@@ -1490,9 +1492,9 @@
],
"support": {
"issues": "https://github.com/zoujingli/WeChatDeveloper/issues",
- "source": "https://github.com/zoujingli/WeChatDeveloper/tree/v1.2.54"
+ "source": "https://github.com/zoujingli/WeChatDeveloper/tree/v1.2.59"
},
- "time": "2024-01-16T13:13:59+00:00"
+ "time": "2024-08-18T14:32:01+00:00"
}
],
"packages-dev": [],
diff --git a/upload/system/storage/vendor/composer/autoload_files.php b/upload/system/storage/vendor/composer/autoload_files.php
index 95c41dc18..673c5913a 100644
--- a/upload/system/storage/vendor/composer/autoload_files.php
+++ b/upload/system/storage/vendor/composer/autoload_files.php
@@ -8,14 +8,15 @@
return array(
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
- 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
+ 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php',
'23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
'89efb1254ef2d1c5d80096acd12c4098' => $vendorDir . '/twig/twig/src/Resources/core.php',
'ffecb95d45175fd40f75be8a23b34f90' => $vendorDir . '/twig/twig/src/Resources/debug.php',
'c7baa00073ee9c61edf148c51917cfb4' => $vendorDir . '/twig/twig/src/Resources/escaper.php',
'f844ccf1d25df8663951193c3fc307c8' => $vendorDir . '/twig/twig/src/Resources/string_loader.php',
+ 'c8e8d17e7ab157f630af324c6fb87d41' => $vendorDir . '/zoujingli/wechat-developer/helper.php',
);
diff --git a/upload/system/storage/vendor/composer/autoload_static.php b/upload/system/storage/vendor/composer/autoload_static.php
index 9beecd570..29d688215 100644
--- a/upload/system/storage/vendor/composer/autoload_static.php
+++ b/upload/system/storage/vendor/composer/autoload_static.php
@@ -9,16 +9,17 @@ class ComposerStaticInit723df5bcd9366cc0d09a11e95c1b3994
public static $files = array (
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
- 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
+ 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php',
'23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
'89efb1254ef2d1c5d80096acd12c4098' => __DIR__ . '/..' . '/twig/twig/src/Resources/core.php',
'ffecb95d45175fd40f75be8a23b34f90' => __DIR__ . '/..' . '/twig/twig/src/Resources/debug.php',
'c7baa00073ee9c61edf148c51917cfb4' => __DIR__ . '/..' . '/twig/twig/src/Resources/escaper.php',
'f844ccf1d25df8663951193c3fc307c8' => __DIR__ . '/..' . '/twig/twig/src/Resources/string_loader.php',
+ 'c8e8d17e7ab157f630af324c6fb87d41' => __DIR__ . '/..' . '/zoujingli/wechat-developer/helper.php',
);
public static $prefixLengthsPsr4 = array (
diff --git a/upload/system/storage/vendor/composer/installed.json b/upload/system/storage/vendor/composer/installed.json
index c17a7a824..7451426f4 100644
--- a/upload/system/storage/vendor/composer/installed.json
+++ b/upload/system/storage/vendor/composer/installed.json
@@ -1400,34 +1400,33 @@
},
{
"name": "twig/twig",
- "version": "v3.11.0",
- "version_normalized": "3.11.0.0",
+ "version": "v3.12.0",
+ "version_normalized": "3.12.0.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d"
+ "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
- "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea",
+ "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea",
"shasum": ""
},
"require": {
- "php": ">=7.2.5",
+ "php": ">=8.0.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3",
- "symfony/polyfill-php80": "^1.22",
"symfony/polyfill-php81": "^1.29"
},
"require-dev": {
"psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
},
- "time": "2024-08-08T16:15:16+00:00",
+ "time": "2024-08-29T09:51:12+00:00",
"type": "library",
- "installation-source": "dist",
+ "installation-source": "source",
"autoload": {
"files": [
"src/Resources/core.php",
@@ -1467,7 +1466,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.11.0"
+ "source": "https://github.com/twigphp/Twig/tree/v3.12.0"
},
"funding": [
{
@@ -1483,17 +1482,17 @@
},
{
"name": "zoujingli/wechat-developer",
- "version": "v1.2.54",
- "version_normalized": "1.2.54.0",
+ "version": "v1.2.59",
+ "version_normalized": "1.2.59.0",
"source": {
"type": "git",
"url": "https://github.com/zoujingli/WeChatDeveloper.git",
- "reference": "812aae37ffc5b6038b03163796f6eed97bb79730"
+ "reference": "d422e5dc1768033dd6849f7e23180ee7da02d8ee"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zoujingli/WeChatDeveloper/zipball/812aae37ffc5b6038b03163796f6eed97bb79730",
- "reference": "812aae37ffc5b6038b03163796f6eed97bb79730",
+ "url": "https://api.github.com/repos/zoujingli/WeChatDeveloper/zipball/d422e5dc1768033dd6849f7e23180ee7da02d8ee",
+ "reference": "d422e5dc1768033dd6849f7e23180ee7da02d8ee",
"shasum": ""
},
"require": {
@@ -1507,10 +1506,13 @@
"ext-xml": "*",
"php": ">=5.4"
},
- "time": "2024-01-16T13:13:59+00:00",
+ "time": "2024-08-18T14:32:01+00:00",
"type": "library",
- "installation-source": "dist",
+ "installation-source": "source",
"autoload": {
+ "files": [
+ "helper.php"
+ ],
"psr-4": {
"WePay\\": "WePay",
"AliPay\\": "AliPay",
@@ -1544,7 +1546,7 @@
],
"support": {
"issues": "https://github.com/zoujingli/WeChatDeveloper/issues",
- "source": "https://github.com/zoujingli/WeChatDeveloper/tree/v1.2.54"
+ "source": "https://github.com/zoujingli/WeChatDeveloper/tree/v1.2.59"
},
"install-path": "../zoujingli/wechat-developer"
}
diff --git a/upload/system/storage/vendor/composer/installed.php b/upload/system/storage/vendor/composer/installed.php
index 9038f820d..6e4be943f 100644
--- a/upload/system/storage/vendor/composer/installed.php
+++ b/upload/system/storage/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'opencart/opencart-3',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
- 'reference' => '5930e7357189d9fe45ecea0498fbd7f199902bec',
+ 'reference' => '7142bae06b051db7aba9450f86dea75c041af710',
'type' => 'project',
'install_path' => __DIR__ . '/../../../../../',
'aliases' => array(),
@@ -58,7 +58,7 @@
'opencart/opencart-3' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
- 'reference' => '5930e7357189d9fe45ecea0498fbd7f199902bec',
+ 'reference' => '7142bae06b051db7aba9450f86dea75c041af710',
'type' => 'project',
'install_path' => __DIR__ . '/../../../../../',
'aliases' => array(),
@@ -200,18 +200,18 @@
'dev_requirement' => false,
),
'twig/twig' => array(
- 'pretty_version' => 'v3.11.0',
- 'version' => '3.11.0.0',
- 'reference' => 'e80fb8ebba85c7341a97a9ebf825d7fd4b77708d',
+ 'pretty_version' => 'v3.12.0',
+ 'version' => '3.12.0.0',
+ 'reference' => '4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea',
'type' => 'library',
'install_path' => __DIR__ . '/../twig/twig',
'aliases' => array(),
'dev_requirement' => false,
),
'zoujingli/wechat-developer' => array(
- 'pretty_version' => 'v1.2.54',
- 'version' => '1.2.54.0',
- 'reference' => '812aae37ffc5b6038b03163796f6eed97bb79730',
+ 'pretty_version' => 'v1.2.59',
+ 'version' => '1.2.59.0',
+ 'reference' => 'd422e5dc1768033dd6849f7e23180ee7da02d8ee',
'type' => 'library',
'install_path' => __DIR__ . '/../zoujingli/wechat-developer',
'aliases' => array(),
diff --git a/upload/system/storage/vendor/twig/twig/.editorconfig b/upload/system/storage/vendor/twig/twig/.editorconfig
new file mode 100644
index 000000000..270f1d1b7
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/.editorconfig
@@ -0,0 +1,18 @@
+; top-most EditorConfig file
+root = true
+
+; Unix-style newlines
+[*]
+end_of_line = LF
+
+[*.php]
+indent_style = space
+indent_size = 4
+
+[*.test]
+indent_style = space
+indent_size = 4
+
+[*.rst]
+indent_style = space
+indent_size = 4
diff --git a/upload/system/storage/vendor/twig/twig/.gitattributes b/upload/system/storage/vendor/twig/twig/.gitattributes
new file mode 100644
index 000000000..86b9ef413
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/.gitattributes
@@ -0,0 +1,9 @@
+/.github/ export-ignore
+/doc/ export-ignore
+/extra/ export-ignore
+/tests/ export-ignore
+/.editorconfig export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
+/.php-cs-fixer.dist.php export-ignore
+/phpunit.xml.dist export-ignore
diff --git a/upload/system/storage/vendor/twig/twig/.github/dependabot.yml b/upload/system/storage/vendor/twig/twig/.github/dependabot.yml
new file mode 100644
index 000000000..5ace4600a
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/upload/system/storage/vendor/twig/twig/.github/workflows/ci.yml b/upload/system/storage/vendor/twig/twig/.github/workflows/ci.yml
new file mode 100644
index 000000000..3de8aa10c
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/.github/workflows/ci.yml
@@ -0,0 +1,158 @@
+name: "CI"
+
+on:
+ pull_request:
+ push:
+ branches:
+ - '3.x'
+
+env:
+ SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE: 1
+
+permissions:
+ contents: read
+
+jobs:
+ tests:
+ name: "PHP ${{ matrix.php-version }}"
+
+ runs-on: 'ubuntu-latest'
+
+ strategy:
+ matrix:
+ php-version:
+ - '8.0'
+ - '8.1'
+ - '8.2'
+ - '8.3'
+ - '8.4'
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@v4
+
+ - name: "Install PHP with extensions"
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: "none"
+ php-version: ${{ matrix.php-version }}
+ ini-values: memory_limit=-1
+
+ - name: "Add PHPUnit matcher"
+ run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
+
+ - run: composer install
+
+ - name: "Switch use_yield to true on PHP ${{ matrix.php-version }}"
+ if: "matrix.php-version == '8.2'"
+ run: |
+ sed -i -e "s/'use_yield' => false/'use_yield' => true/" src/Environment.php
+
+ - name: "Install PHPUnit"
+ run: vendor/bin/simple-phpunit install
+
+ - name: "PHPUnit version"
+ run: vendor/bin/simple-phpunit --version
+
+ - name: "Run tests"
+ run: vendor/bin/simple-phpunit
+
+ extension-tests:
+ needs:
+ - 'tests'
+
+ name: "${{ matrix.extension }} PHP ${{ matrix.php-version }}"
+
+ runs-on: 'ubuntu-latest'
+
+ continue-on-error: true
+
+ strategy:
+ matrix:
+ php-version:
+ - '8.0'
+ - '8.1'
+ - '8.2'
+ - '8.3'
+ - '8.4'
+ extension:
+ - 'cache-extra'
+ - 'cssinliner-extra'
+ - 'html-extra'
+ - 'inky-extra'
+ - 'intl-extra'
+ - 'markdown-extra'
+ - 'string-extra'
+ - 'twig-extra-bundle'
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@v4
+
+ - name: "Install PHP with extensions"
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: "none"
+ php-version: ${{ matrix.php-version }}
+ ini-values: memory_limit=-1
+
+ - name: "Add PHPUnit matcher"
+ run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
+
+ - name: "Composer install Twig"
+ run: composer install
+
+ - name: "Install PHPUnit"
+ run: vendor/bin/simple-phpunit install
+
+ - name: "PHPUnit version"
+ run: vendor/bin/simple-phpunit --version
+
+ - name: "Prevent installing symfony/translation-contract 3.0"
+ if: "matrix.extension == 'twig-extra-bundle'"
+ working-directory: extra/${{ matrix.extension }}
+ run: "composer require --no-update 'symfony/translation-contracts:^1.1|^2.0'"
+
+ - name: "Composer install ${{ matrix.extension }}"
+ working-directory: extra/${{ matrix.extension }}
+ run: composer install
+
+ - name: "Switch use_yield to true"
+ if: "matrix.php-version == '8.2'"
+ run: |
+ sed -i -e "s/'use_yield' => false/'use_yield' => true/" extra/${{ matrix.extension }}/vendor/twig/twig/src/Environment.php
+
+ - name: "Run tests for ${{ matrix.extension }}"
+ working-directory: extra/${{ matrix.extension }}
+ run: ../../vendor/bin/simple-phpunit
+
+ integration-tests:
+ needs:
+ - 'tests'
+
+ name: "Integration tests with PHP ${{ matrix.php-version }}"
+
+ runs-on: 'ubuntu-latest'
+
+ continue-on-error: true
+
+ strategy:
+ matrix:
+ php-version:
+ - '8.2'
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@v4
+
+ - name: "Install PHP with extensions"
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: "none"
+ extensions: "gd, pdo_sqlite, uuid"
+ php-version: ${{ matrix.php-version }}
+ ini-values: memory_limit=-1
+ tools: composer:v2
+
+ - run: bash ./tests/drupal_test.sh
+ shell: "bash"
diff --git a/upload/system/storage/vendor/twig/twig/.github/workflows/documentation.yml b/upload/system/storage/vendor/twig/twig/.github/workflows/documentation.yml
new file mode 100644
index 000000000..8fe7c868c
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/.github/workflows/documentation.yml
@@ -0,0 +1,64 @@
+name: "Documentation"
+
+on:
+ pull_request:
+ push:
+ branches:
+ - '2.x'
+ - '3.x'
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ name: "Build"
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@v4
+
+ - name: "Set-up PHP"
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 8.2
+ coverage: none
+ tools: "composer:v2"
+
+ - name: Get composer cache directory
+ id: composercache
+ working-directory: doc/_build
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache dependencies
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.composercache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ runner.os }}-composer-
+
+ - name: "Install dependencies"
+ working-directory: doc/_build
+ run: composer install --prefer-dist --no-progress
+
+ - name: "Build the docs"
+ working-directory: doc/_build
+ run: php build.php --disable-cache
+
+ doctor-rst:
+ name: "DOCtor-RST"
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@v4
+
+ - name: "Run DOCtor-RST"
+ uses: docker://oskarstark/doctor-rst
+ with:
+ args: --short
+ env:
+ DOCS_DIR: 'doc/'
diff --git a/upload/system/storage/vendor/twig/twig/.gitignore b/upload/system/storage/vendor/twig/twig/.gitignore
new file mode 100644
index 000000000..b197246ba
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/.gitignore
@@ -0,0 +1,6 @@
+/doc/_build/vendor
+/doc/_build/output
+/composer.lock
+/phpunit.xml
+/vendor
+.phpunit.result.cache
diff --git a/upload/system/storage/vendor/twig/twig/.php-cs-fixer.dist.php b/upload/system/storage/vendor/twig/twig/.php-cs-fixer.dist.php
new file mode 100644
index 000000000..5c3a731a1
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/.php-cs-fixer.dist.php
@@ -0,0 +1,21 @@
+setRules([
+ '@Symfony' => true,
+ '@Symfony:risky' => true,
+ '@PHPUnit75Migration:risky' => true,
+ 'php_unit_dedicate_assert' => ['target' => '5.6'],
+ 'array_syntax' => ['syntax' => 'short'],
+ 'php_unit_fqcn_annotation' => true,
+ 'no_unreachable_default_argument_value' => false,
+ 'braces' => ['allow_single_line_closure' => true],
+ 'heredoc_to_nowdoc' => false,
+ 'ordered_imports' => true,
+ 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
+ // TODO: Remove once the "compiler_optimized" set includes "sprintf"
+ 'native_function_invocation' => ['include' => ['@compiler_optimized', 'sprintf'], 'scope' => 'all'],
+ ])
+ ->setRiskyAllowed(true)
+ ->setFinder((new PhpCsFixer\Finder())->in(__DIR__))
+;
diff --git a/upload/system/storage/vendor/twig/twig/CHANGELOG b/upload/system/storage/vendor/twig/twig/CHANGELOG
index dd776e083..ff6951e6d 100644
--- a/upload/system/storage/vendor/twig/twig/CHANGELOG
+++ b/upload/system/storage/vendor/twig/twig/CHANGELOG
@@ -1,5 +1,36 @@
+# 3.12.0 (2024-08-29)
+
+ * Deprecate the fact that the `extends` and `use` tags are always allowed in a sandboxed template.
+ This behavior will change in 4.0 where these tags will need to be explicitly allowed like any other tag.
+ * Deprecate the "tag" constructor argument of the "Twig\Node\Node" class as the tag is now automatically set by the Parser when needed
+ * Fix precedence of two-word tests when the first word is a valid test
+ * Deprecate the `spaceless` filter
+ * Deprecate some internal methods from `Parser`: `getBlockStack()`, `hasBlock()`, `getBlock()`, `hasMacro()`, `hasTraits()`, `getParent()`
+ * Deprecate passing `null` to `Twig\Parser::setParent()`
+ * Update `Node::__toString()` to include the node tag if set
+ * Add support for integers in methods of `Twig\Node\Node` that take a Node name
+ * Deprecate not passing a `BodyNode` instance as the body of a `ModuleNode` or `MacroNode` constructor
+ * Deprecate returning "null" from "TokenParserInterface::parse()".
+ * Deprecate `OptimizerNodeVisitor::OPTIMIZE_TEXT_NODES`
+ * Fix performance regression when `use_yield` is `false` (which is the default)
+ * Improve compatibility when `use_yield` is `false` (as extensions still using `echo` will work as is)
+ * Accept colons (`:`) in addition to equals (`=`) to separate argument names and values in named arguments
+ * Add the `html_cva` function (in the HTML extra package)
+ * Add support for named arguments to the `block` and `attribute` functions
+ * Throw a SyntaxError exception at compile time when a Twig callable has not the minimum number of required arguments
+ * Add a `CallableArgumentsExtractor` class
+ * Deprecate passing a name to `FunctionExpression`, `FilterExpression`, and `TestExpression`;
+ pass a `TwigFunction`, `TwigFilter`, or `TestFilter` instead
+ * Deprecate all Twig callable attributes on `FunctionExpression`, `FilterExpression`, and `TestExpression`
+ * Deprecate the `filter` node of `FilterExpression`
+ * Add the notion of Twig callables (functions, filters, and tests)
+ * Bump minimum PHP version to 8.0
+ * Fix integration tests when a test has more than one data/expect section and deprecations
+ * Add the `enum_cases` function
+
# 3.11.0 (2024-08-08)
+ * Deprecate `OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER`
* Add `Twig\Cache\ChainCache` and `Twig\Cache\ReadOnlyFilesystemCache`
* Add the possibility to deprecate attributes and nodes on `Node`
* Add the possibility to add a package and a version to the `deprecated` tag
diff --git a/upload/system/storage/vendor/twig/twig/composer.json b/upload/system/storage/vendor/twig/twig/composer.json
index 26cb4972e..e0c3e6c6c 100644
--- a/upload/system/storage/vendor/twig/twig/composer.json
+++ b/upload/system/storage/vendor/twig/twig/composer.json
@@ -24,8 +24,7 @@
}
],
"require": {
- "php": ">=7.2.5",
- "symfony/polyfill-php80": "^1.22",
+ "php": ">=8.0.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-ctype": "^1.8",
diff --git a/upload/system/storage/vendor/twig/twig/doc/.doctor-rst.yaml b/upload/system/storage/vendor/twig/twig/doc/.doctor-rst.yaml
new file mode 100644
index 000000000..bfb404263
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/.doctor-rst.yaml
@@ -0,0 +1,54 @@
+rules:
+ american_english: ~
+ avoid_repetetive_words: ~
+ blank_line_after_directive: ~
+ blank_line_before_directive: ~
+ composer_dev_option_not_at_the_end: ~
+ correct_code_block_directive_based_on_the_content: ~
+ deprecated_directive_should_have_version: ~
+ ensure_order_of_code_blocks_in_configuration_block: ~
+ extension_xlf_instead_of_xliff: ~
+ indention: ~
+ lowercase_as_in_use_statements: ~
+ max_blank_lines:
+ max: 2
+ no_blank_line_after_filepath_in_php_code_block: ~
+ no_blank_line_after_filepath_in_twig_code_block: ~
+ no_blank_line_after_filepath_in_xml_code_block: ~
+ no_blank_line_after_filepath_in_yaml_code_block: ~
+ no_composer_req: ~
+ no_explicit_use_of_code_block_php: ~
+ no_inheritdoc: ~
+ no_namespace_after_use_statements: ~
+ no_php_open_tag_in_code_block_php_directive: ~
+ no_space_before_self_xml_closing_tag: ~
+ ordered_use_statements: ~
+ php_prefix_before_bin_console: ~
+ replace_code_block_types: ~
+ replacement: ~
+ short_array_syntax: ~
+ typo: ~
+ unused_links: ~
+ use_deprecated_directive_instead_of_versionadded: ~
+ use_https_xsd_urls: ~
+ valid_inline_highlighted_namespaces: ~
+ valid_use_statements: ~
+ versionadded_directive_should_have_version: ~
+ yaml_instead_of_yml_suffix: ~
+ yarn_dev_option_at_the_end: ~
+
+ versionadded_directive_major_version:
+ major_version: 3
+
+ versionadded_directive_min_version:
+ min_version: '3.0'
+
+ deprecated_directive_major_version:
+ major_version: 3
+
+ deprecated_directive_min_version:
+ min_version: '3.0'
+
+whitelist:
+ lines:
+ - 'I like Twig. '
diff --git a/upload/system/storage/vendor/twig/twig/doc/_build/build.php b/upload/system/storage/vendor/twig/twig/doc/_build/build.php
new file mode 100644
index 000000000..2b183b186
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/_build/build.php
@@ -0,0 +1,56 @@
+#!/usr/bin/env php
+register('build-docs')
+ ->addOption('disable-cache', null, InputOption::VALUE_NONE, 'Use this option to force a full regeneration of all doc contents')
+ ->setCode(function (InputInterface $input, OutputInterface $output) {
+ $io = new SymfonyStyle($input, $output);
+ $io->text('Building all Twig docs...');
+
+ $outputDir = __DIR__.'/output';
+ $buildConfig = (new BuildConfig())
+ ->setContentDir(__DIR__.'/..')
+ ->setOutputDir($outputDir)
+ ->setImagesDir(__DIR__.'/output/_images')
+ ->setImagesPublicPrefix('_images')
+ ->setTheme('rtd')
+ ;
+
+ $buildConfig->setExcludedPaths(['vendor/']);
+ $buildConfig->disableJsonFileGeneration();
+ $buildConfig->disableBuildCache();
+
+ $result = (new DocBuilder())->build($buildConfig);
+
+ if ($result->isSuccessful()) {
+ // fix assets URLs to make them absolute (otherwise, they don't work in subdirectories)
+ foreach (glob($outputDir.'/**/*.html') as $htmlFilePath) {
+ $htmlContents = file_get_contents($htmlFilePath);
+ file_put_contents($htmlFilePath, str_replace('href="assets/', 'href="/assets/', $htmlContents));
+ }
+
+ $io->success(\sprintf('The Twig docs were successfully built at %s', realpath($outputDir)));
+ } else {
+ $io->error(\sprintf("There were some errors while building the docs:\n\n%s\n", $result->getErrorTrace()));
+ $io->newLine();
+ $io->comment('Tip: you can add the -v, -vv or -vvv flags to this command to get debug information.');
+
+ return 1;
+ }
+
+ return 0;
+ })
+ ->getApplication()
+ ->setDefaultCommand('build-docs', true)
+ ->run();
diff --git a/upload/system/storage/vendor/twig/twig/doc/_build/composer.json b/upload/system/storage/vendor/twig/twig/doc/_build/composer.json
new file mode 100644
index 000000000..d9b1e5d41
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/_build/composer.json
@@ -0,0 +1,19 @@
+{
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "config": {
+ "platform": {
+ "php": "8.1.0"
+ },
+ "preferred-install": {
+ "*": "dist"
+ },
+ "sort-packages": true
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/console": "^5.4",
+ "symfony/process": "^5.4",
+ "symfony-tools/docs-builder": "^0.18"
+ }
+}
diff --git a/upload/system/storage/vendor/twig/twig/doc/_build/composer.lock b/upload/system/storage/vendor/twig/twig/doc/_build/composer.lock
new file mode 100644
index 000000000..765fc3e72
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/_build/composer.lock
@@ -0,0 +1,1962 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "b71f84fed3bf9d4dddbc68f14f71b9b4",
+ "packages": [
+ {
+ "name": "doctrine/event-manager",
+ "version": "1.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/event-manager.git",
+ "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/event-manager/zipball/eb2ecf80e3093e8f3c2769ac838e27d8ede8e683",
+ "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/common": "<2.9"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9",
+ "phpstan/phpstan": "~1.4.10 || ^1.5.4",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "vimeo/psalm": "^4.22"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\": "lib/Doctrine/Common"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ },
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
+ }
+ ],
+ "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
+ "homepage": "https://www.doctrine-project.org/projects/event-manager.html",
+ "keywords": [
+ "event",
+ "event dispatcher",
+ "event manager",
+ "event system",
+ "events"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/event-manager/issues",
+ "source": "https://github.com/doctrine/event-manager/tree/1.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-27T22:18:11+00:00"
+ },
+ {
+ "name": "doctrine/rst-parser",
+ "version": "0.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/rst-parser.git",
+ "reference": "3b914d5eb8f6a91afc7462ea7794b0e05b884a35"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/rst-parser/zipball/3b914d5eb8f6a91afc7462ea7794b0e05b884a35",
+ "reference": "3b914d5eb8f6a91afc7462ea7794b0e05b884a35",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/event-manager": "^1.0",
+ "php": "^7.2 || ^8.0",
+ "symfony/filesystem": "^4.1 || ^5.0 || ^6.0",
+ "symfony/finder": "^4.1 || ^5.0 || ^6.0",
+ "symfony/polyfill-mbstring": "^1.0",
+ "symfony/string": "^5.3 || ^6.0",
+ "symfony/translation-contracts": "^1.1 || ^2.0",
+ "twig/twig": "^2.9 || ^3.3"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^8.0",
+ "gajus/dindent": "^2.0.2",
+ "phpstan/phpstan": "^0.12",
+ "phpstan/phpstan-deprecation-rules": "^0.12",
+ "phpstan/phpstan-phpunit": "^0.12",
+ "phpstan/phpstan-strict-rules": "^0.12",
+ "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0",
+ "symfony/css-selector": "4.4 || ^5.2 || ^6.0",
+ "symfony/dom-crawler": "4.4 || ^5.2 || ^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\RST\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Grégoire Passault",
+ "email": "g.passault@gmail.com",
+ "homepage": "http://www.gregwar.com/"
+ },
+ {
+ "name": "Jonathan H. Wage",
+ "email": "jonwage@gmail.com",
+ "homepage": "https://jwage.com"
+ }
+ ],
+ "description": "PHP library to parse reStructuredText documents and generate HTML or LaTeX documents.",
+ "homepage": "https://github.com/doctrine/rst-parser",
+ "keywords": [
+ "html",
+ "latex",
+ "markup",
+ "parser",
+ "reStructuredText",
+ "rst"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/rst-parser/issues",
+ "source": "https://github.com/doctrine/rst-parser/tree/0.5.2"
+ },
+ "time": "2022-03-22T13:52:20+00:00"
+ },
+ {
+ "name": "masterminds/html5",
+ "version": "2.7.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Masterminds/html5-php.git",
+ "reference": "f640ac1bdddff06ea333a920c95bbad8872429ab"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f640ac1bdddff06ea333a920c95bbad8872429ab",
+ "reference": "f640ac1bdddff06ea333a920c95bbad8872429ab",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Masterminds\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matt Butcher",
+ "email": "technosophos@gmail.com"
+ },
+ {
+ "name": "Matt Farina",
+ "email": "matt@mattfarina.com"
+ },
+ {
+ "name": "Asmir Mustafic",
+ "email": "goetas@gmail.com"
+ }
+ ],
+ "description": "An HTML5 parser and serializer.",
+ "homepage": "http://masterminds.github.io/html5-php",
+ "keywords": [
+ "HTML5",
+ "dom",
+ "html",
+ "parser",
+ "querypath",
+ "serializer",
+ "xml"
+ ],
+ "support": {
+ "issues": "https://github.com/Masterminds/html5-php/issues",
+ "source": "https://github.com/Masterminds/html5-php/tree/2.7.5"
+ },
+ "time": "2021-07-01T14:25:37+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/2.0.2"
+ },
+ "time": "2021-11-05T16:47:00+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376",
+ "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/2.0.0"
+ },
+ "time": "2021-07-14T16:41:46+00:00"
+ },
+ {
+ "name": "scrivo/highlight.php",
+ "version": "v9.18.1.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/scrivo/highlight.php.git",
+ "reference": "d45585504777e6194a91dffc7270ca39833787f8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/d45585504777e6194a91dffc7270ca39833787f8",
+ "reference": "d45585504777e6194a91dffc7270ca39833787f8",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "php": ">=5.4"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8|^5.7",
+ "sabberworm/php-css-parser": "^8.3",
+ "symfony/finder": "^2.8|^3.4",
+ "symfony/var-dumper": "^2.8|^3.4"
+ },
+ "suggest": {
+ "ext-mbstring": "Allows highlighting code with unicode characters and supports language with unicode keywords"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "HighlightUtilities/functions.php"
+ ],
+ "psr-0": {
+ "Highlight\\": "",
+ "HighlightUtilities\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Geert Bergman",
+ "homepage": "http://www.scrivo.org/",
+ "role": "Project Author"
+ },
+ {
+ "name": "Vladimir Jimenez",
+ "homepage": "https://allejo.io",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Martin Folkers",
+ "homepage": "https://twobrain.io",
+ "role": "Contributor"
+ }
+ ],
+ "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js",
+ "keywords": [
+ "code",
+ "highlight",
+ "highlight.js",
+ "highlight.php",
+ "syntax"
+ ],
+ "support": {
+ "issues": "https://github.com/scrivo/highlight.php/issues",
+ "source": "https://github.com/scrivo/highlight.php"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/allejo",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-03T06:45:28+00:00"
+ },
+ {
+ "name": "symfony-tools/docs-builder",
+ "version": "v0.18.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony-tools/docs-builder.git",
+ "reference": "1bc91f91887b115d78e7d2c8879c19af515b36ae"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony-tools/docs-builder/zipball/1bc91f91887b115d78e7d2c8879c19af515b36ae",
+ "reference": "1bc91f91887b115d78e7d2c8879c19af515b36ae",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/rst-parser": "^0.5",
+ "ext-curl": "*",
+ "ext-json": "*",
+ "php": ">=7.4",
+ "scrivo/highlight.php": "^9.12.0",
+ "symfony/console": "^5.2 || ^6.0",
+ "symfony/css-selector": "^5.2 || ^6.0",
+ "symfony/dom-crawler": "^5.2 || ^6.0",
+ "symfony/filesystem": "^5.2 || ^6.0",
+ "symfony/finder": "^5.2 || ^6.0",
+ "symfony/http-client": "^5.2 || ^6.0",
+ "twig/twig": "^2.14 || ^3.3"
+ },
+ "require-dev": {
+ "gajus/dindent": "^2.0",
+ "symfony/phpunit-bridge": "^5.2 || ^6.0",
+ "symfony/process": "^5.2 || ^6.0"
+ },
+ "bin": [
+ "bin/docs-builder"
+ ],
+ "type": "project",
+ "autoload": {
+ "psr-4": {
+ "SymfonyDocsBuilder\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "The build system for Symfony's documentation",
+ "support": {
+ "issues": "https://github.com/symfony-tools/docs-builder/issues",
+ "source": "https://github.com/symfony-tools/docs-builder/tree/v0.18.9"
+ },
+ "time": "2022-03-22T14:32:49+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v5.4.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "535846c7ee6bc4dd027ca0d93220601456734b10"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/535846c7ee6bc4dd027ca0d93220601456734b10",
+ "reference": "535846c7ee6bc4dd027ca0d93220601456734b10",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php73": "^1.9",
+ "symfony/polyfill-php80": "^1.16",
+ "symfony/service-contracts": "^1.1|^2|^3",
+ "symfony/string": "^5.1|^6.0"
+ },
+ "conflict": {
+ "psr/log": ">=3",
+ "symfony/dependency-injection": "<4.4",
+ "symfony/dotenv": "<5.1",
+ "symfony/event-dispatcher": "<4.4",
+ "symfony/lock": "<4.4",
+ "symfony/process": "<4.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2",
+ "symfony/config": "^4.4|^5.0|^6.0",
+ "symfony/dependency-injection": "^4.4|^5.0|^6.0",
+ "symfony/event-dispatcher": "^4.4|^5.0|^6.0",
+ "symfony/lock": "^4.4|^5.0|^6.0",
+ "symfony/process": "^4.4|^5.0|^6.0",
+ "symfony/var-dumper": "^4.4|^5.0|^6.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/lock": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v5.4.11"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-22T10:42:43+00:00"
+ },
+ {
+ "name": "symfony/css-selector",
+ "version": "v6.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/0dd5e36b80e1de97f8f74ed7023ac2b837a36443",
+ "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\CssSelector\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Jean-François Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Converts CSS selectors to XPath expressions",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/css-selector/tree/v6.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-27T17:24:16+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
+ "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.1-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-02-25T11:15:52+00:00"
+ },
+ {
+ "name": "symfony/dom-crawler",
+ "version": "v6.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "58eb9858d8752ac3586fffb37421441fc18f793c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/58eb9858d8752ac3586fffb37421441fc18f793c",
+ "reference": "58eb9858d8752ac3586fffb37421441fc18f793c",
+ "shasum": ""
+ },
+ "require": {
+ "masterminds/html5": "^2.6",
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "^5.4|^6.0"
+ },
+ "suggest": {
+ "symfony/css-selector": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\DomCrawler\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases DOM navigation for HTML and XML documents",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/dom-crawler/tree/v6.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-27T17:24:16+00:00"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v6.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "c780e677cddda78417fa5187a7c6cd2f21110db9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/c780e677cddda78417fa5187a7c6cd2f21110db9",
+ "reference": "c780e677cddda78417fa5187a7c6cd2f21110db9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides basic utilities for the filesystem",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/filesystem/tree/v6.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-20T14:45:06+00:00"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v6.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/39696bff2c2970b3779a5cac7bf9f0b88fc2b709",
+ "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/filesystem": "^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Finder\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Finds files and directories via an intuitive fluent interface",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v6.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-29T07:42:06+00:00"
+ },
+ {
+ "name": "symfony/http-client",
+ "version": "v6.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-client.git",
+ "reference": "1ef59920a9cedf223e8564ae8ad7608cbe799b4d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-client/zipball/1ef59920a9cedf223e8564ae8ad7608cbe799b4d",
+ "reference": "1ef59920a9cedf223e8564ae8ad7608cbe799b4d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/log": "^1|^2|^3",
+ "symfony/http-client-contracts": "^3",
+ "symfony/service-contracts": "^1.0|^2|^3"
+ },
+ "provide": {
+ "php-http/async-client-implementation": "*",
+ "php-http/client-implementation": "*",
+ "psr/http-client-implementation": "1.0",
+ "symfony/http-client-implementation": "3.0"
+ },
+ "require-dev": {
+ "amphp/amp": "^2.5",
+ "amphp/http-client": "^4.2.1",
+ "amphp/http-tunnel": "^1.0",
+ "amphp/socket": "^1.1",
+ "guzzlehttp/promises": "^1.4",
+ "nyholm/psr7": "^1.0",
+ "php-http/httplug": "^1.0|^2.0",
+ "psr/http-client": "^1.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/stopwatch": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpClient\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/http-client/tree/v6.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-28T13:40:41+00:00"
+ },
+ {
+ "name": "symfony/http-client-contracts",
+ "version": "v3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-client-contracts.git",
+ "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/fd038f08c623ab5d22b26e9ba35afe8c79071800",
+ "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "suggest": {
+ "symfony/http-client-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.1-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\HttpClient\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to HTTP clients",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/http-client-contracts/tree/v3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-04-22T07:30:54+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
+ "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "433d05519ce6990bf3530fba6957499d327395c2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2",
+ "reference": "433d05519ce6990bf3530fba6957499d327395c2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's grapheme_* functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "219aa369ceff116e673852dce47c3a41794c14bd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd",
+ "reference": "219aa369ceff116e673852dce47c3a41794c14bd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+ "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php73",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php73.git",
+ "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85",
+ "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php73\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+ "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-10T07:21:04+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v5.4.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1",
+ "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Executes commands in sub-processes",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/process/tree/v5.4.11"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-27T16:58:25+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "v3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239",
+ "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/container": "^2.0"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2"
+ },
+ "suggest": {
+ "symfony/service-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.1-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Service\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to writing services",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/v3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-30T19:18:58+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "v6.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "f35241f45c30bcd9046af2bb200a7086f70e1d6b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/f35241f45c30bcd9046af2bb200a7086f70e1d6b",
+ "reference": "f35241f45c30bcd9046af2bb200a7086f70e1d6b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/translation-contracts": "<2.0"
+ },
+ "require-dev": {
+ "symfony/error-handler": "^5.4|^6.0",
+ "symfony/http-client": "^5.4|^6.0",
+ "symfony/translation-contracts": "^2.0|^3.0",
+ "symfony/var-exporter": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\String\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v6.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-27T15:50:51+00:00"
+ },
+ {
+ "name": "symfony/translation-contracts",
+ "version": "v2.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/translation-contracts.git",
+ "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/136b19dd05cdf0709db6537d058bcab6dd6e2dbe",
+ "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5"
+ },
+ "suggest": {
+ "symfony/translation-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Translation\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to translation",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/translation-contracts/tree/v2.5.2"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-27T16:58:25+00:00"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v3.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077",
+ "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-mbstring": "^1.3"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/v3.4.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-08-12T06:47:24+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "dev",
+ "stability-flags": [],
+ "prefer-stable": true,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=8.1"
+ },
+ "platform-dev": [],
+ "platform-overrides": {
+ "php": "8.1.0"
+ },
+ "plugin-api-version": "2.3.0"
+}
diff --git a/upload/system/storage/vendor/twig/twig/doc/advanced.rst b/upload/system/storage/vendor/twig/twig/doc/advanced.rst
new file mode 100644
index 000000000..b3eaa1a2e
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/advanced.rst
@@ -0,0 +1,936 @@
+Extending Twig
+==============
+
+Twig can be extended in many ways; you can add extra tags, filters, tests,
+operators, global variables, and functions. You can even extend the parser
+itself with node visitors.
+
+.. note::
+
+ The first section of this chapter describes how to extend Twig. If you want
+ to reuse your changes in different projects or if you want to share them
+ with others, you should then create an extension as described in the
+ following section.
+
+.. caution::
+
+ When extending Twig without creating an extension, Twig won't be able to
+ recompile your templates when the PHP code is updated. To see your changes
+ in real-time, either disable template caching or package your code into an
+ extension (see the next section of this chapter).
+
+Before extending Twig, you must understand the differences between all the
+different possible extension points and when to use them.
+
+First, remember that Twig has two main language constructs:
+
+* ``{{ }}``: used to print the result of an expression evaluation;
+
+* ``{% %}``: used to execute statements.
+
+To understand why Twig exposes so many extension points, let's see how to
+implement a *Lorem ipsum* generator (it needs to know the number of words to
+generate).
+
+You can use a ``lipsum`` *tag*:
+
+.. code-block:: twig
+
+ {% lipsum 40 %}
+
+That works, but using a tag for ``lipsum`` is not a good idea for at least
+three main reasons:
+
+* ``lipsum`` is not a language construct;
+* The tag outputs something;
+* The tag is not flexible as you cannot use it in an expression:
+
+ .. code-block:: twig
+
+ {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}
+
+In fact, you rarely need to create tags; and that's good news because tags are
+the most complex extension point.
+
+Now, let's use a ``lipsum`` *filter*:
+
+.. code-block:: twig
+
+ {{ 40|lipsum }}
+
+Again, it works. But a filter should transform the passed value to something
+else. Here, we use the value to indicate the number of words to generate (so,
+``40`` is an argument of the filter, not the value we want to transform).
+
+Next, let's use a ``lipsum`` *function*:
+
+.. code-block:: twig
+
+ {{ lipsum(40) }}
+
+Here we go. For this specific example, the creation of a function is the
+extension point to use. And you can use it anywhere an expression is accepted:
+
+.. code-block:: twig
+
+ {{ 'some text' ~ lipsum(40) ~ 'some more text' }}
+
+ {% set lipsum = lipsum(40) %}
+
+Lastly, you can also use a *global* object with a method able to generate lorem
+ipsum text:
+
+.. code-block:: twig
+
+ {{ text.lipsum(40) }}
+
+As a rule of thumb, use functions for frequently used features and global
+objects for everything else.
+
+Keep in mind the following when you want to extend Twig:
+
+========== ========================== ========== =========================
+What? Implementation difficulty? How often? When?
+========== ========================== ========== =========================
+*macro* simple frequent Content generation
+*global* simple frequent Helper object
+*function* simple frequent Content generation
+*filter* simple frequent Value transformation
+*tag* complex rare DSL language construct
+*test* simple rare Boolean decision
+*operator* simple rare Values transformation
+========== ========================== ========== =========================
+
+Globals
+-------
+
+A global variable is like any other template variable, except that it's
+available in all templates and macros::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addGlobal('text', new Text());
+
+You can then use the ``text`` variable anywhere in a template:
+
+.. code-block:: twig
+
+ {{ text.lipsum(40) }}
+
+Filters
+-------
+
+Creating a filter consists of associating a name with a PHP callable::
+
+ // an anonymous function
+ $filter = new \Twig\TwigFilter('rot13', function ($string) {
+ return str_rot13($string);
+ });
+
+ // or a simple PHP function
+ $filter = new \Twig\TwigFilter('rot13', 'str_rot13');
+
+ // or a class static method
+ $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
+ $filter = new \Twig\TwigFilter('rot13', 'SomeClass::rot13Filter');
+
+ // or a class method
+ $filter = new \Twig\TwigFilter('rot13', [$this, 'rot13Filter']);
+ // the one below needs a runtime implementation (see below for more information)
+ $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
+
+The first argument passed to the ``\Twig\TwigFilter`` constructor is the name of the
+filter you will use in templates and the second one is the PHP callable to
+associate with it.
+
+Then, add the filter to the Twig environment::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addFilter($filter);
+
+And here is how to use it in a template:
+
+.. code-block:: twig
+
+ {{ 'Twig'|rot13 }}
+
+ {# will output Gjvt #}
+
+When called by Twig, the PHP callable receives the left side of the filter
+(before the pipe ``|``) as the first argument and the extra arguments passed
+to the filter (within parentheses ``()``) as extra arguments.
+
+For instance, the following code:
+
+.. code-block:: twig
+
+ {{ 'TWIG'|lower }}
+ {{ now|date('d/m/Y') }}
+
+is compiled to something like the following::
+
+
+
+
+The ``\Twig\TwigFilter`` class takes an array of options as its last argument::
+
+ $filter = new \Twig\TwigFilter('rot13', 'str_rot13', $options);
+
+Charset-aware Filters
+~~~~~~~~~~~~~~~~~~~~~
+
+If you want to access the default charset in your filter, set the
+``needs_charset`` option to ``true``; Twig will pass the default charset as the
+first argument to the filter call::
+
+ $filter = new \Twig\TwigFilter('rot13', function (string $charset, $string) {
+ return str_rot13($string);
+ }, ['needs_charset' => true]);
+
+Environment-aware Filters
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you want to access the current environment instance in your filter, set the
+``needs_environment`` option to ``true``; Twig will pass the current
+environment as the first argument to the filter call::
+
+ $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $string) {
+ // get the current charset for instance
+ $charset = $env->getCharset();
+
+ return str_rot13($string);
+ }, ['needs_environment' => true]);
+
+Context-aware Filters
+~~~~~~~~~~~~~~~~~~~~~
+
+If you want to access the current context in your filter, set the
+``needs_context`` option to ``true``; Twig will pass the current context as
+the first argument to the filter call (or the second one if
+``needs_environment`` is also set to ``true``)::
+
+ $filter = new \Twig\TwigFilter('rot13', function ($context, $string) {
+ // ...
+ }, ['needs_context' => true]);
+
+ $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $context, $string) {
+ // ...
+ }, ['needs_context' => true, 'needs_environment' => true]);
+
+Automatic Escaping
+~~~~~~~~~~~~~~~~~~
+
+If automatic escaping is enabled, the output of the filter may be escaped
+before printing. If your filter acts as an escaper (or explicitly outputs HTML
+or JavaScript code), you will want the raw output to be printed. In such a
+case, set the ``is_safe`` option::
+
+ $filter = new \Twig\TwigFilter('nl2br', 'nl2br', ['is_safe' => ['html']]);
+
+Some filters may need to work on input that is already escaped or safe, for
+example when adding (safe) HTML tags to originally unsafe output. In such a
+case, set the ``pre_escape`` option to escape the input data before it is run
+through your filter::
+
+ $filter = new \Twig\TwigFilter('somefilter', 'somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);
+
+Variadic Filters
+~~~~~~~~~~~~~~~~
+
+When a filter should accept an arbitrary number of arguments, set the
+``is_variadic`` option to ``true``; Twig will pass the extra arguments as the
+last argument to the filter call as an array::
+
+ $filter = new \Twig\TwigFilter('thumbnail', function ($file, array $options = []) {
+ // ...
+ }, ['is_variadic' => true]);
+
+Be warned that :ref:`named arguments ` passed to a variadic
+filter cannot be checked for validity as they will automatically end up in the
+option array.
+
+Dynamic Filters
+~~~~~~~~~~~~~~~
+
+A filter name containing the special ``*`` character is a dynamic filter and
+the ``*`` part will match any string::
+
+ $filter = new \Twig\TwigFilter('*_path', function ($name, $arguments) {
+ // ...
+ });
+
+The following filters are matched by the above defined dynamic filter:
+
+* ``product_path``
+* ``category_path``
+
+A dynamic filter can define more than one dynamic parts::
+
+ $filter = new \Twig\TwigFilter('*_path_*', function ($name, $suffix, $arguments) {
+ // ...
+ });
+
+The filter receives all dynamic part values before the normal filter arguments,
+but after the environment and the context. For instance, a call to
+``'foo'|a_path_b()`` will result in the following arguments to be passed to the
+filter: ``('a', 'b', 'foo')``.
+
+Deprecated Filters
+~~~~~~~~~~~~~~~~~~
+
+You can mark a filter as being deprecated by setting the ``deprecated`` option
+to ``true``. You can also give an alternative filter that replaces the
+deprecated one when that makes sense::
+
+ $filter = new \Twig\TwigFilter('obsolete', function () {
+ // ...
+ }, ['deprecated' => true, 'alternative' => 'new_one']);
+
+.. versionadded:: 3.11
+
+ The ``deprecating_package`` option was added in Twig 3.11.
+
+You can also set the ``deprecating_package`` option to specify the package that
+is deprecating the filter, and ``deprecated`` can be set to the package version
+when the filter was deprecated::
+
+ $filter = new \Twig\TwigFilter('obsolete', function () {
+ // ...
+ }, ['deprecated' => '1.1', 'deprecating_package' => 'foo/bar']);
+
+When a filter is deprecated, Twig emits a deprecation notice when compiling a
+template using it. See :ref:`deprecation-notices` for more information.
+
+Functions
+---------
+
+Functions are defined in the exact same way as filters, but you need to create
+an instance of ``\Twig\TwigFunction``::
+
+ $twig = new \Twig\Environment($loader);
+ $function = new \Twig\TwigFunction('function_name', function () {
+ // ...
+ });
+ $twig->addFunction($function);
+
+Functions support the same features as filters, except for the ``pre_escape``
+and ``preserves_safety`` options.
+
+Tests
+-----
+
+Tests are defined in the exact same way as filters and functions, but you need
+to create an instance of ``\Twig\TwigTest``::
+
+ $twig = new \Twig\Environment($loader);
+ $test = new \Twig\TwigTest('test_name', function () {
+ // ...
+ });
+ $twig->addTest($test);
+
+Tests allow you to create custom application specific logic for evaluating
+boolean conditions. As a simple example, let's create a Twig test that checks if
+objects are 'red'::
+
+ $twig = new \Twig\Environment($loader);
+ $test = new \Twig\TwigTest('red', function ($value) {
+ if (isset($value->color) && $value->color == 'red') {
+ return true;
+ }
+ if (isset($value->paint) && $value->paint == 'red') {
+ return true;
+ }
+ return false;
+ });
+ $twig->addTest($test);
+
+Test functions must always return ``true``/``false``.
+
+When creating tests you can use the ``node_class`` option to provide custom test
+compilation. This is useful if your test can be compiled into PHP primitives.
+This is used by many of the tests built into Twig::
+
+ namespace App;
+
+ use Twig\Environment;
+ use Twig\Node\Expression\TestExpression;
+ use Twig\TwigTest;
+
+ $twig = new Environment($loader);
+ $test = new TwigTest(
+ 'odd',
+ null,
+ ['node_class' => OddTestExpression::class]);
+ $twig->addTest($test);
+
+ class OddTestExpression extends TestExpression
+ {
+ public function compile(\Twig\Compiler $compiler)
+ {
+ $compiler
+ ->raw('(')
+ ->subcompile($this->getNode('node'))
+ ->raw(' % 2 != 0')
+ ->raw(')')
+ ;
+ }
+ }
+
+The above example shows how you can create tests that use a node class. The node
+class has access to one sub-node called ``node``. This sub-node contains the
+value that is being tested. When the ``odd`` filter is used in code such as:
+
+.. code-block:: twig
+
+ {% if my_value is odd %}
+
+The ``node`` sub-node will contain an expression of ``my_value``. Node-based
+tests also have access to the ``arguments`` node. This node will contain the
+various other arguments that have been provided to your test.
+
+If you want to pass a variable number of positional or named arguments to the
+test, set the ``is_variadic`` option to ``true``. Tests support dynamic
+names (see dynamic filters for the syntax).
+
+Tags
+----
+
+One of the most exciting features of a template engine like Twig is the
+possibility to define new **language constructs**. This is also the most complex
+feature as you need to understand how Twig's internals work.
+
+Most of the time though, a tag is not needed:
+
+* If your tag generates some output, use a **function** instead.
+
+* If your tag modifies some content and returns it, use a **filter** instead.
+
+ For instance, if you want to create a tag that converts a Markdown formatted
+ text to HTML, create a ``markdown`` filter instead:
+
+ .. code-block:: twig
+
+ {{ '**markdown** text'|markdown }}
+
+ If you want use this filter on large amounts of text, wrap it with the
+ :doc:`apply ` tag:
+
+ .. code-block:: twig
+
+ {% apply markdown %}
+ Title
+ =====
+
+ Much better than creating a tag as you can **compose** filters.
+ {% endapply %}
+
+* If your tag does not output anything, but only exists because of a side
+ effect, create a **function** that returns nothing and call it via the
+ :doc:`do ` tag.
+
+ For instance, if you want to create a tag that logs text, create a ``log``
+ function instead and call it via the :doc:`do ` tag:
+
+ .. code-block:: twig
+
+ {% do log('Log some things') %}
+
+If you still want to create a tag for a new language construct, great!
+
+Let's create a ``set`` tag that allows the definition of simple variables from
+within a template. The tag can be used like follows:
+
+.. code-block:: twig
+
+ {% set name = "value" %}
+
+ {{ name }}
+
+ {# should output value #}
+
+.. note::
+
+ The ``set`` tag is part of the Core extension and as such is always
+ available. The built-in version is slightly more powerful and supports
+ multiple assignments by default.
+
+Three steps are needed to define a new tag:
+
+* Defining a Token Parser class (responsible for parsing the template code);
+
+* Defining a Node class (responsible for converting the parsed code to PHP);
+
+* Registering the tag.
+
+Registering a new tag
+~~~~~~~~~~~~~~~~~~~~~
+
+Add a tag by calling the ``addTokenParser`` method on the ``\Twig\Environment``
+instance::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addTokenParser(new CustomSetTokenParser());
+
+Defining a Token Parser
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Now, let's see the actual code of this class::
+
+ class CustomSetTokenParser extends \Twig\TokenParser\AbstractTokenParser
+ {
+ public function parse(\Twig\Token $token)
+ {
+ $parser = $this->parser;
+ $stream = $parser->getStream();
+
+ $name = $stream->expect(\Twig\Token::NAME_TYPE)->getValue();
+ $stream->expect(\Twig\Token::OPERATOR_TYPE, '=');
+ $value = $parser->getExpressionParser()->parseExpression();
+ $stream->expect(\Twig\Token::BLOCK_END_TYPE);
+
+ return new CustomSetNode($name, $value, $token->getLine());
+ }
+
+ public function getTag()
+ {
+ return 'set';
+ }
+ }
+
+The ``getTag()`` method must return the tag we want to parse, here ``set``.
+
+The ``parse()`` method is invoked whenever the parser encounters a ``set``
+tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
+``CustomSetNode`` calls creating is explained in the next section).
+
+The parsing process is simplified thanks to a bunch of methods you can call
+from the token stream (``$this->parser->getStream()``):
+
+* ``getCurrent()``: Gets the current token in the stream.
+
+* ``next()``: Moves to the next token in the stream, *but returns the old one*.
+
+* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
+ the current token is of a particular type or value (or both). The value may be an
+ array of several possible values.
+
+* ``expect($type[, $value[, $message]])``: If the current token isn't of the given
+ type/value a syntax error is thrown. Otherwise, if the type and value are correct,
+ the token is returned and the stream moves to the next token.
+
+* ``look()``: Looks at the next token without consuming it.
+
+Parsing expressions is done by calling the ``parseExpression()`` like we did for
+the ``set`` tag.
+
+.. tip::
+
+ Reading the existing ``TokenParser`` classes is the best way to learn all
+ the nitty-gritty details of the parsing process.
+
+Defining a Node
+~~~~~~~~~~~~~~~
+
+The ``CustomSetNode`` class itself is quite short::
+
+ class CustomSetNode extends \Twig\Node\Node
+ {
+ public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $line)
+ {
+ parent::__construct(['value' => $value], ['name' => $name], $line);
+ }
+
+ public function compile(\Twig\Compiler $compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('$context[\''.$this->getAttribute('name').'\'] = ')
+ ->subcompile($this->getNode('value'))
+ ->raw(";\n")
+ ;
+ }
+ }
+
+The compiler implements a fluid interface and provides methods that help the
+developer generate beautiful and readable PHP code:
+
+* ``subcompile()``: Compiles a node.
+
+* ``raw()``: Writes the given string as is.
+
+* ``write()``: Writes the given string by adding indentation at the beginning
+ of each line.
+
+* ``string()``: Writes a quoted string.
+
+* ``repr()``: Writes a PHP representation of a given value (see
+ ``\Twig\Node\ForNode`` for a usage example).
+
+* ``addDebugInfo()``: Adds the line of the original template file related to
+ the current node as a comment.
+
+* ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
+ usage example).
+
+* ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
+ usage example).
+
+.. _creating_extensions:
+
+Creating an Extension
+---------------------
+
+The main motivation for writing an extension is to move often used code into a
+reusable class like adding support for internationalization. An extension can
+define tags, filters, tests, operators, functions, and node visitors.
+
+Most of the time, it is useful to create a single extension for your project,
+to host all the specific tags and filters you want to add to Twig.
+
+.. tip::
+
+ When packaging your code into an extension, Twig is smart enough to
+ recompile your templates whenever you make a change to it (when
+ ``auto_reload`` is enabled).
+
+An extension is a class that implements the following interface::
+
+ interface \Twig\Extension\ExtensionInterface
+ {
+ /**
+ * Returns the token parser instances to add to the existing list.
+ *
+ * @return \Twig\TokenParser\TokenParserInterface[]
+ */
+ public function getTokenParsers();
+
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return \Twig\NodeVisitor\NodeVisitorInterface[]
+ */
+ public function getNodeVisitors();
+
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return \Twig\TwigFilter[]
+ */
+ public function getFilters();
+
+ /**
+ * Returns a list of tests to add to the existing list.
+ *
+ * @return \Twig\TwigTest[]
+ */
+ public function getTests();
+
+ /**
+ * Returns a list of functions to add to the existing list.
+ *
+ * @return \Twig\TwigFunction[]
+ */
+ public function getFunctions();
+
+ /**
+ * Returns a list of operators to add to the existing list.
+ *
+ * @return array First array of unary operators, second array of binary operators
+ */
+ public function getOperators();
+ }
+
+To keep your extension class clean and lean, inherit from the built-in
+``\Twig\Extension\AbstractExtension`` class instead of implementing the interface as it provides
+empty implementations for all methods::
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension
+ {
+ }
+
+This extension does nothing for now. We will customize it in the next sections.
+
+You can save your extension anywhere on the filesystem, as all extensions must
+be registered explicitly to be available in your templates.
+
+You can register an extension by using the ``addExtension()`` method on your
+main ``Environment`` object::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->addExtension(new CustomTwigExtension());
+
+.. tip::
+
+ The Twig core extensions are great examples of how extensions work.
+
+Globals
+~~~~~~~
+
+Global variables can be registered in an extension via the ``getGlobals()``
+method::
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
+ {
+ public function getGlobals(): array
+ {
+ return [
+ 'text' => new Text(),
+ ];
+ }
+
+ // ...
+ }
+
+Functions
+~~~~~~~~~
+
+Functions can be registered in an extension via the ``getFunctions()``
+method::
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFunctions()
+ {
+ return [
+ new \Twig\TwigFunction('lipsum', 'generate_lipsum'),
+ ];
+ }
+
+ // ...
+ }
+
+Filters
+~~~~~~~
+
+To add a filter to an extension, you need to override the ``getFilters()``
+method. This method must return an array of filters to add to the Twig
+environment::
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFilters()
+ {
+ return [
+ new \Twig\TwigFilter('rot13', 'str_rot13'),
+ ];
+ }
+
+ // ...
+ }
+
+Tags
+~~~~
+
+Adding a tag in an extension can be done by overriding the
+``getTokenParsers()`` method. This method must return an array of tags to add
+to the Twig environment::
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension
+ {
+ public function getTokenParsers()
+ {
+ return [new CustomSetTokenParser()];
+ }
+
+ // ...
+ }
+
+In the above code, we have added a single new tag, defined by the
+``CustomSetTokenParser`` class. The ``CustomSetTokenParser`` class is
+responsible for parsing the tag and compiling it to PHP.
+
+Operators
+~~~~~~~~~
+
+The ``getOperators()`` methods lets you add new operators. Here is how to add
+the ``!``, ``||``, and ``&&`` operators::
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension
+ {
+ public function getOperators()
+ {
+ return [
+ [
+ '!' => ['precedence' => 50, 'class' => \Twig\Node\Expression\Unary\NotUnary::class],
+ ],
+ [
+ '||' => ['precedence' => 10, 'class' => \Twig\Node\Expression\Binary\OrBinary::class, 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
+ '&&' => ['precedence' => 15, 'class' => \Twig\Node\Expression\Binary\AndBinary::class, 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
+ ],
+ ];
+ }
+
+ // ...
+ }
+
+Tests
+~~~~~
+
+The ``getTests()`` method lets you add new test functions::
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension
+ {
+ public function getTests()
+ {
+ return [
+ new \Twig\TwigTest('even', 'twig_test_even'),
+ ];
+ }
+
+ // ...
+ }
+
+Definition vs Runtime
+~~~~~~~~~~~~~~~~~~~~~
+
+Twig filters, functions, and tests runtime implementations can be defined as
+any valid PHP callable:
+
+* **functions/static methods**: Simple to implement and fast (used by all Twig
+ core extensions); but it is hard for the runtime to depend on external
+ objects;
+
+* **closures**: Simple to implement;
+
+* **object methods**: More flexible and required if your runtime code depends
+ on external objects.
+
+The simplest way to use methods is to define them on the extension itself::
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension
+ {
+ private $rot13Provider;
+
+ public function __construct($rot13Provider)
+ {
+ $this->rot13Provider = $rot13Provider;
+ }
+
+ public function getFunctions()
+ {
+ return [
+ new \Twig\TwigFunction('rot13', [$this, 'rot13']),
+ ];
+ }
+
+ public function rot13($value)
+ {
+ return $this->rot13Provider->rot13($value);
+ }
+ }
+
+This is very convenient but not recommended as it makes template compilation
+depend on runtime dependencies even if they are not needed (think for instance
+as a dependency that connects to a database engine).
+
+You can decouple the extension definitions from their runtime implementations by
+registering a ``\Twig\RuntimeLoader\RuntimeLoaderInterface`` instance on the
+environment that knows how to instantiate such runtime classes (runtime classes
+must be autoload-able)::
+
+ class RuntimeLoader implements \Twig\RuntimeLoader\RuntimeLoaderInterface
+ {
+ public function load($class)
+ {
+ // implement the logic to create an instance of $class
+ // and inject its dependencies
+ // most of the time, it means using your dependency injection container
+ if ('CustomRuntimeExtension' === $class) {
+ return new $class(new Rot13Provider());
+ } else {
+ // ...
+ }
+ }
+ }
+
+ $twig->addRuntimeLoader(new RuntimeLoader());
+
+.. note::
+
+ Twig comes with a PSR-11 compatible runtime loader
+ (``\Twig\RuntimeLoader\ContainerRuntimeLoader``).
+
+It is now possible to move the runtime logic to a new
+``CustomRuntimeExtension`` class and use it directly in the extension::
+
+ class CustomRuntimeExtension
+ {
+ private $rot13Provider;
+
+ public function __construct($rot13Provider)
+ {
+ $this->rot13Provider = $rot13Provider;
+ }
+
+ public function rot13($value)
+ {
+ return $this->rot13Provider->rot13($value);
+ }
+ }
+
+ class CustomTwigExtension extends \Twig\Extension\AbstractExtension
+ {
+ public function getFunctions()
+ {
+ return [
+ new \Twig\TwigFunction('rot13', ['CustomRuntimeExtension', 'rot13']),
+ // or
+ new \Twig\TwigFunction('rot13', 'CustomRuntimeExtension::rot13'),
+ ];
+ }
+ }
+
+Testing an Extension
+--------------------
+
+Functional Tests
+~~~~~~~~~~~~~~~~
+
+You can create functional tests for extensions by creating the following file
+structure in your test directory::
+
+ Fixtures/
+ filters/
+ foo.test
+ bar.test
+ functions/
+ foo.test
+ bar.test
+ tags/
+ foo.test
+ bar.test
+ IntegrationTest.php
+
+The ``IntegrationTest.php`` file should look like this::
+
+ namespace Project\Tests;
+
+ use Twig\Test\IntegrationTestCase;
+
+ class IntegrationTest extends IntegrationTestCase
+ {
+ public function getExtensions()
+ {
+ return [
+ new CustomTwigExtension1(),
+ new CustomTwigExtension2(),
+ ];
+ }
+
+ public function getFixturesDir()
+ {
+ return __DIR__.'/Fixtures/';
+ }
+ }
+
+Fixtures examples can be found within the Twig repository
+`tests/Twig/Fixtures`_ directory.
+
+Node Tests
+~~~~~~~~~~
+
+Testing the node visitors can be complex, so extend your test cases from
+``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
+`tests/Twig/Node`_ directory.
+
+.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/3.x/tests/Fixtures
+.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/3.x/tests/Node
diff --git a/upload/system/storage/vendor/twig/twig/doc/api.rst b/upload/system/storage/vendor/twig/twig/doc/api.rst
new file mode 100644
index 000000000..09c553175
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/api.rst
@@ -0,0 +1,585 @@
+Twig for Developers
+===================
+
+This chapter describes the API to Twig and not the template language. It will
+be most useful as reference to those implementing the template interface to
+the application and not those who are creating Twig templates.
+
+Basics
+------
+
+Twig uses a central object called the **environment** (of class
+``\Twig\Environment``). Instances of this class are used to store the
+configuration and extensions, and are used to load templates.
+
+Most applications create one ``\Twig\Environment`` object on application
+initialization and use that to load templates. In some cases, it might be useful
+to have multiple environments side by side, with different configurations.
+
+The typical way to configure Twig to load templates for an application looks
+roughly like this::
+
+ require_once '/path/to/vendor/autoload.php';
+
+ $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
+ $twig = new \Twig\Environment($loader, [
+ 'cache' => '/path/to/compilation_cache',
+ ]);
+
+This creates a template environment with a default configuration and a loader
+that looks up templates in the ``/path/to/templates/`` directory. Different
+loaders are available and you can also write your own if you want to load
+templates from a database or other resources.
+
+.. note::
+
+ Notice that the second argument of the environment is an array of options.
+ The ``cache`` option is a compilation cache directory, where Twig caches
+ the compiled templates to avoid the parsing phase for sub-sequent
+ requests. It is very different from the cache you might want to add for
+ the evaluated templates. For such a need, you can use any available PHP
+ cache library.
+
+Rendering Templates
+-------------------
+
+To load a template from a Twig environment, call the ``load()`` method which
+returns a ``\Twig\TemplateWrapper`` instance::
+
+ $template = $twig->load('index.html');
+
+To render the template with some variables, call the ``render()`` method::
+
+ echo $template->render(['the' => 'variables', 'go' => 'here']);
+
+.. note::
+
+ The ``display()`` method is a shortcut to output the rendered template.
+
+You can also load and render the template in one fell swoop::
+
+ echo $twig->render('index.html', ['the' => 'variables', 'go' => 'here']);
+
+If a template defines blocks, they can be rendered individually via the
+``renderBlock()`` call::
+
+ echo $template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']);
+
+.. _environment_options:
+
+Environment Options
+-------------------
+
+When creating a new ``\Twig\Environment`` instance, you can pass an array of
+options as the constructor second argument::
+
+ $twig = new \Twig\Environment($loader, ['debug' => true]);
+
+The following options are available:
+
+* ``debug`` *boolean*
+
+ When set to ``true``, the generated templates have a
+ ``__toString()`` method that you can use to display the generated nodes
+ (default to ``false``).
+
+* ``charset`` *string* (defaults to ``utf-8``)
+
+ The charset used by the templates.
+
+* ``cache`` *string* or ``false``
+
+ An absolute path where to store the compiled templates, or
+ ``false`` to disable caching (which is the default).
+
+* ``auto_reload`` *boolean*
+
+ When developing with Twig, it's useful to recompile the
+ template whenever the source code changes. If you don't provide a value for
+ the ``auto_reload`` option, it will be determined automatically based on the
+ ``debug`` value.
+
+.. _environment_options_strict_variables:
+
+* ``strict_variables`` *boolean*
+
+ If set to ``false``, Twig will silently ignore invalid
+ variables (variables and or attributes/methods that do not exist) and
+ replace them with a ``null`` value. When set to ``true``, Twig throws an
+ exception instead (default to ``false``).
+
+* ``autoescape`` *string*
+
+ Sets the default auto-escaping strategy (``name``, ``html``, ``js``, ``css``,
+ ``url``, ``html_attr``, or a PHP callback that takes the template "filename"
+ and returns the escaping strategy to use -- the callback cannot be a function
+ name to avoid collision with built-in escaping strategies); set it to
+ ``false`` to disable auto-escaping. The ``name`` escaping strategy determines
+ the escaping strategy to use for a template based on the template filename
+ extension (this strategy does not incur any overhead at runtime as
+ auto-escaping is done at compilation time.)
+
+* ``optimizations`` *integer*
+
+ A flag that indicates which optimizations to apply
+ (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to
+ disable).
+
+Loaders
+-------
+
+Loaders are responsible for loading templates from a resource such as the file
+system.
+
+Compilation Cache
+~~~~~~~~~~~~~~~~~
+
+All template loaders can cache the compiled templates on the filesystem for
+future reuse. It speeds up Twig a lot as templates are only compiled once.
+
+Built-in Loaders
+~~~~~~~~~~~~~~~~
+
+Here is a list of the built-in loaders:
+
+``\Twig\Loader\FilesystemLoader``
+.................................
+
+``\Twig\Loader\FilesystemLoader`` loads templates from the file system. This loader
+can find templates in folders on the file system and is the preferred way to
+load them::
+
+ $loader = new \Twig\Loader\FilesystemLoader($templateDir);
+
+It can also look for templates in an array of directories::
+
+ $loader = new \Twig\Loader\FilesystemLoader([$templateDir1, $templateDir2]);
+
+With such a configuration, Twig will first look for templates in
+``$templateDir1`` and if they do not exist, it will fallback to look for them
+in the ``$templateDir2``.
+
+You can add or prepend paths via the ``addPath()`` and ``prependPath()``
+methods::
+
+ $loader->addPath($templateDir3);
+ $loader->prependPath($templateDir4);
+
+The filesystem loader also supports namespaced templates. This allows to group
+your templates under different namespaces which have their own template paths.
+
+When using the ``setPaths()``, ``addPath()``, and ``prependPath()`` methods,
+specify the namespace as the second argument (when not specified, these
+methods act on the "main" namespace)::
+
+ $loader->addPath($templateDir, 'admin');
+
+Namespaced templates can be accessed via the special
+``@namespace_name/template_path`` notation::
+
+ $twig->render('@admin/index.html', []);
+
+``\Twig\Loader\FilesystemLoader`` supports absolute and relative paths. Using relative
+paths is preferred as it makes the cache keys independent of the project root
+directory (for instance, it allows warming the cache from a build server where
+the directory might be different from the one used on production servers)::
+
+ $loader = new \Twig\Loader\FilesystemLoader('templates', getcwd().'/..');
+
+.. note::
+
+ When not passing the root path as a second argument, Twig uses ``getcwd()``
+ for relative paths.
+
+``\Twig\Loader\ArrayLoader``
+............................
+
+``\Twig\Loader\ArrayLoader`` loads a template from a PHP array. It is passed an
+array of strings bound to template names::
+
+ $loader = new \Twig\Loader\ArrayLoader([
+ 'index.html' => 'Hello {{ name }}!',
+ ]);
+ $twig = new \Twig\Environment($loader);
+
+ echo $twig->render('index.html', ['name' => 'Fabien']);
+
+This loader is very useful for unit testing. It can also be used for small
+projects where storing all templates in a single PHP file might make sense.
+
+.. tip::
+
+ When using the ``Array`` loader with a cache mechanism, you should know that
+ a new cache key is generated each time a template content "changes" (the
+ cache key being the source code of the template). If you don't want to see
+ your cache grows out of control, you need to take care of clearing the old
+ cache file by yourself.
+
+``\Twig\Loader\ChainLoader``
+............................
+
+``\Twig\Loader\ChainLoader`` delegates the loading of templates to other loaders::
+
+ $loader1 = new \Twig\Loader\ArrayLoader([
+ 'base.html' => '{% block content %}{% endblock %}',
+ ]);
+ $loader2 = new \Twig\Loader\ArrayLoader([
+ 'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}',
+ 'base.html' => 'Will never be loaded',
+ ]);
+
+ $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);
+
+ $twig = new \Twig\Environment($loader);
+
+When looking for a template, Twig tries each loader in turn and returns as soon
+as the template is found. When rendering the ``index.html`` template from the
+above example, Twig will load it with ``$loader2`` but the ``base.html``
+template will be loaded from ``$loader1``.
+
+.. note::
+
+ You can also add loaders via the ``addLoader()`` method.
+
+Create your own Loader
+~~~~~~~~~~~~~~~~~~~~~~
+
+All loaders implement the ``\Twig\Loader\LoaderInterface``::
+
+ interface \Twig\Loader\LoaderInterface
+ {
+ /**
+ * Returns the source context for a given template logical name.
+ *
+ * @param string $name The template logical name
+ *
+ * @return \Twig\Source
+ *
+ * @throws \Twig\Error\LoaderError When $name is not found
+ */
+ public function getSourceContext($name);
+
+ /**
+ * Gets the cache key to use for the cache for a given template name.
+ *
+ * @param string $name The name of the template to load
+ *
+ * @return string The cache key
+ *
+ * @throws \Twig\Error\LoaderError When $name is not found
+ */
+ public function getCacheKey($name);
+
+ /**
+ * Returns true if the template is still fresh.
+ *
+ * @param string $name The template name
+ * @param timestamp $time The last modification time of the cached template
+ *
+ * @return bool true if the template is fresh, false otherwise
+ *
+ * @throws \Twig\Error\LoaderError When $name is not found
+ */
+ public function isFresh($name, $time);
+
+ /**
+ * Check if we have the source code of a template, given its name.
+ *
+ * @param string $name The name of the template to check if we can load
+ *
+ * @return bool If the template source code is handled by this loader or not
+ */
+ public function exists($name);
+ }
+
+The ``isFresh()`` method must return ``true`` if the current cached template
+is still fresh, given the last modification time, or ``false`` otherwise.
+
+The ``getSourceContext()`` method must return an instance of ``\Twig\Source``.
+
+Using Extensions
+----------------
+
+Twig extensions are packages that add new features to Twig. Register an
+extension via the ``addExtension()`` method::
+
+ $twig->addExtension(new \Twig\Extension\SandboxExtension());
+
+Twig comes bundled with the following extensions:
+
+* *Twig\Extension\CoreExtension*: Defines all the core features of Twig.
+
+* *Twig\Extension\DebugExtension*: Defines the ``dump`` function to help debug
+ template variables.
+
+* *Twig\Extension\EscaperExtension*: Adds automatic output-escaping and the
+ possibility to escape/unescape blocks of code.
+
+* *Twig\Extension\SandboxExtension*: Adds a sandbox mode to the default Twig
+ environment, making it safe to evaluate untrusted code.
+
+* *Twig\Extension\ProfilerExtension*: Enables the built-in Twig profiler.
+
+* *Twig\Extension\OptimizerExtension*: Optimizes the node tree before
+ compilation.
+
+* *Twig\Extension\StringLoaderExtension*: Defines the ``template_from_string``
+ function to allow loading templates from string in a template.
+
+The Core, Escaper, and Optimizer extensions are registered by default.
+
+Built-in Extensions
+-------------------
+
+This section describes the features added by the built-in extensions.
+
+.. tip::
+
+ Read the chapter about :doc:`extending Twig ` to learn how to
+ create your own extensions.
+
+Core Extension
+~~~~~~~~~~~~~~
+
+The ``core`` extension defines all the core features of Twig:
+
+* :doc:`Tags `;
+* :doc:`Filters `;
+* :doc:`Functions `;
+* :doc:`Tests `.
+
+Escaper Extension
+~~~~~~~~~~~~~~~~~
+
+The ``escaper`` extension adds automatic output escaping to Twig. It defines a
+tag, ``autoescape``, and a filter, ``raw``.
+
+When creating the escaper extension, you can switch on or off the global
+output escaping strategy::
+
+ $escaper = new \Twig\Extension\EscaperExtension('html');
+ $twig->addExtension($escaper);
+
+If set to ``html``, all variables in templates are escaped (using the ``html``
+escaping strategy), except those using the ``raw`` filter:
+
+.. code-block:: twig
+
+ {{ article.to_html|raw }}
+
+You can also change the escaping mode locally by using the ``autoescape`` tag:
+
+.. code-block:: twig
+
+ {% autoescape 'html' %}
+ {{ var }}
+ {{ var|raw }} {# var won't be escaped #}
+ {{ var|escape }} {# var won't be double-escaped #}
+ {% endautoescape %}
+
+.. warning::
+
+ The ``autoescape`` tag has no effect on included files.
+
+The escaping rules are implemented as follows:
+
+* Literals (integers, booleans, arrays, ...) used in the template directly as
+ variables or filter arguments are never automatically escaped:
+
+ .. code-block:: html+twig
+
+ {{ "Twig " }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ text }} {# will be escaped #}
+
+* Expressions which the result is a literal or a variable marked safe
+ are never automatically escaped:
+
+ .. code-block:: html+twig
+
+ {{ foo ? "Twig " : " Twig" }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ true ? text : " Twig" }} {# will be escaped #}
+ {{ false ? text : " Twig" }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ foo ? text|raw : " Twig" }} {# won't be escaped #}
+
+* Objects with a ``__toString`` method are converted to strings and
+ escaped. You can mark some classes and/or interfaces as being safe for some
+ strategies via ``EscaperExtension::addSafeClass()``:
+
+ .. code-block:: twig
+
+ // mark object of class Foo as safe for the HTML strategy
+ $escaper->addSafeClass('Foo', ['html']);
+
+ // mark object of interface Foo as safe for the HTML strategy
+ $escaper->addSafeClass('FooInterface', ['html']);
+
+ // mark object of class Foo as safe for the HTML and JS strategies
+ $escaper->addSafeClass('Foo', ['html', 'js']);
+
+ // mark object of class Foo as safe for all strategies
+ $escaper->addSafeClass('Foo', ['all']);
+
+* Escaping is applied before printing, after any other filter is applied:
+
+ .. code-block:: twig
+
+ {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #}
+
+* The ``raw`` filter should only be used at the end of the filter chain:
+
+ .. code-block:: twig
+
+ {{ var|raw|upper }} {# will be escaped #}
+
+ {{ var|upper|raw }} {# won't be escaped #}
+
+* Automatic escaping is not applied if the last filter in the chain is marked
+ safe for the current context (e.g. ``html`` or ``js``). ``escape`` and
+ ``escape('html')`` are marked safe for HTML, ``escape('js')`` is marked
+ safe for JavaScript, ``raw`` is marked safe for everything.
+
+ .. code-block:: twig
+
+ {% autoescape 'js' %}
+ {{ var|escape('html') }} {# will be escaped for HTML and JavaScript #}
+ {{ var }} {# will be escaped for JavaScript #}
+ {{ var|escape('js') }} {# won't be double-escaped #}
+ {% endautoescape %}
+
+.. note::
+
+ Note that autoescaping has some limitations as escaping is applied on
+ expressions after evaluation. For instance, when working with
+ concatenation, ``{{ foo|raw ~ bar }}`` won't give the expected result as
+ escaping is applied on the result of the concatenation, not on the
+ individual variables (so, the ``raw`` filter won't have any effect here).
+
+Sandbox Extension
+~~~~~~~~~~~~~~~~~
+
+The ``sandbox`` extension can be used to evaluate untrusted code. Access to
+unsafe attributes and methods is prohibited. The sandbox security is managed
+by a policy instance. By default, Twig comes with one policy class:
+``\Twig\Sandbox\SecurityPolicy``. This class allows you to white-list some
+tags, filters, functions, properties, and methods::
+
+ $tags = ['if'];
+ $filters = ['upper'];
+ $methods = [
+ 'Article' => ['getTitle', 'getBody'],
+ ];
+ $properties = [
+ 'Article' => ['title', 'body'],
+ ];
+ $functions = ['range'];
+ $policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions);
+
+With the previous configuration, the security policy will only allow usage of
+the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be
+able to call the ``getTitle()`` and ``getBody()`` methods on ``Article``
+objects, and the ``title`` and ``body`` public properties. Everything else
+won't be allowed and will generate a ``\Twig\Sandbox\SecurityError`` exception.
+
+.. caution::
+
+ The ``extends`` and ``use`` tags are always allowed in a sandboxed
+ template. That behavior will change in 4.0 where these tags will need to be
+ explicitly allowed like any other tag.
+
+The policy object is the first argument of the sandbox constructor::
+
+ $sandbox = new \Twig\Extension\SandboxExtension($policy);
+ $twig->addExtension($sandbox);
+
+By default, the sandbox mode is disabled and should be enabled when including
+untrusted template code by using the ``sandbox`` tag:
+
+.. code-block:: twig
+
+ {% sandbox %}
+ {% include 'user.html' %}
+ {% endsandbox %}
+
+You can sandbox all templates by passing ``true`` as the second argument of
+the extension constructor::
+
+ $sandbox = new \Twig\Extension\SandboxExtension($policy, true);
+
+Profiler Extension
+~~~~~~~~~~~~~~~~~~
+
+The ``profiler`` extension enables a profiler for Twig templates; it should
+only be used on your development machines as it adds some overhead::
+
+ $profile = new \Twig\Profiler\Profile();
+ $twig->addExtension(new \Twig\Extension\ProfilerExtension($profile));
+
+ $dumper = new \Twig\Profiler\Dumper\TextDumper();
+ echo $dumper->dump($profile);
+
+A profile contains information about time and memory consumption for template,
+block, and macro executions.
+
+You can also dump the data in a `Blackfire.io `_
+compatible format::
+
+ $dumper = new \Twig\Profiler\Dumper\BlackfireDumper();
+ file_put_contents('/path/to/profile.prof', $dumper->dump($profile));
+
+Upload the profile to visualize it (create a `free account
+`_
+first):
+
+.. code-block:: sh
+
+ blackfire --slot=7 upload /path/to/profile.prof
+
+Optimizer Extension
+~~~~~~~~~~~~~~~~~~~
+
+The ``optimizer`` extension optimizes the node tree before compilation::
+
+ $twig->addExtension(new \Twig\Extension\OptimizerExtension());
+
+By default, all optimizations are turned on. You can select the ones you want
+to enable by passing them to the constructor::
+
+ $optimizer = new \Twig\Extension\OptimizerExtension(\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR);
+
+ $twig->addExtension($optimizer);
+
+Twig supports the following optimizations:
+
+* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_ALL``, enables all optimizations
+ (this is the default value).
+
+* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_NONE``, disables all optimizations.
+ This reduces the compilation time, but it can increase the execution time
+ and the consumed memory.
+
+* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR``, optimizes the ``for`` tag by
+ removing the ``loop`` variable creation whenever possible.
+
+Exceptions
+----------
+
+Twig can throw exceptions:
+
+* ``\Twig\Error\Error``: The base exception for all errors.
+
+* ``\Twig\Error\SyntaxError``: Thrown to tell the user that there is a problem with
+ the template syntax.
+
+* ``\Twig\Error\RuntimeError``: Thrown when an error occurs at runtime (when a filter
+ does not exist for instance).
+
+* ``\Twig\Error\LoaderError``: Thrown when an error occurs during template loading.
+
+* ``\Twig\Sandbox\SecurityError``: Thrown when an unallowed tag, filter, or
+ method is called in a sandboxed template.
diff --git a/upload/system/storage/vendor/twig/twig/doc/coding_standards.rst b/upload/system/storage/vendor/twig/twig/doc/coding_standards.rst
new file mode 100644
index 000000000..46be8eca6
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/coding_standards.rst
@@ -0,0 +1,113 @@
+Coding Standards
+================
+
+.. note::
+
+ The `Twig CS fixer tool `_
+ uses the coding standards described in this document to automatically fix
+ your templates.
+
+When writing Twig templates, we recommend you to follow these official coding
+standards:
+
+* Put exactly one space after the start of a delimiter (``{{``, ``{%``,
+ and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``):
+
+ .. code-block:: twig
+
+ {{ foo }}
+ {# comment #}
+ {% if foo %}{% endif %}
+
+ When using the whitespace control character, do not put any spaces between
+ it and the delimiter:
+
+ .. code-block:: twig
+
+ {{- foo -}}
+ {#- comment -#}
+ {%- if foo -%}{%- endif -%}
+
+* Put exactly one space before and after the following operators:
+ comparison operators (``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``), math
+ operators (``+``, ``-``, ``/``, ``*``, ``%``, ``//``, ``**``), logic
+ operators (``not``, ``and``, ``or``), ``~``, ``is``, ``in``, and the ternary
+ operator (``?:``):
+
+ .. code-block:: twig
+
+ {{ 1 + 2 }}
+ {{ foo ~ bar }}
+ {{ true ? true : false }}
+
+* Put exactly one space after the ``:`` sign in mappings and ``,`` in sequences
+ and mappings:
+
+ .. code-block:: twig
+
+ {{ [1, 2, 3] }}
+ {{ {'foo': 'bar'} }}
+
+* Do not put any spaces after an opening parenthesis and before a closing
+ parenthesis in expressions:
+
+ .. code-block:: twig
+
+ {{ 1 + (2 * 3) }}
+
+* Do not put any spaces before and after string delimiters:
+
+ .. code-block:: twig
+
+ {{ 'foo' }}
+ {{ "foo" }}
+
+* Do not put any spaces before and after the following operators: ``|``,
+ ``.``, ``..``, ``[]``:
+
+ .. code-block:: twig
+
+ {{ foo|upper|lower }}
+ {{ user.name }}
+ {{ user[name] }}
+ {% for i in 1..12 %}{% endfor %}
+
+* Do not put any spaces before and after the parenthesis used for filter and
+ function calls:
+
+ .. code-block:: twig
+
+ {{ foo|default('foo') }}
+ {{ range(1..10) }}
+
+* Do not put any spaces before and after the opening and the closing of
+ sequences and mappings:
+
+ .. code-block:: twig
+
+ {{ [1, 2, 3] }}
+ {{ {'foo': 'bar'} }}
+
+* Use lower cased and underscored variable names:
+
+ .. code-block:: twig
+
+ {% set foo = 'foo' %}
+ {% set foo_bar = 'foo' %}
+
+* Indent your code inside tags (use the same indentation as the one used for
+ the target language of the rendered template):
+
+ .. code-block:: twig
+
+ {% block foo %}
+ {% if true %}
+ true
+ {% endif %}
+ {% endblock %}
+
+* Use ``:`` instead of ``=`` to separate argument names and values:
+
+ .. code-block:: twig
+
+ {{ data|convert_encoding(from: 'iso-2022-jp', to: 'UTF-8') }}
diff --git a/upload/system/storage/vendor/twig/twig/doc/deprecated.rst b/upload/system/storage/vendor/twig/twig/doc/deprecated.rst
new file mode 100644
index 000000000..affdd2ba9
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/deprecated.rst
@@ -0,0 +1,202 @@
+Deprecated Features
+===================
+
+This document lists deprecated features in Twig 3.x. Deprecated features are
+kept for backward compatibility and removed in the next major release (a
+feature that was deprecated in Twig 3.x is removed in Twig 4.0).
+
+Functions
+---------
+
+ * The ``twig_test_iterable`` function is deprecated; use the native PHP
+ ``is_iterable`` function instead.
+
+Extensions
+----------
+
+* All functions defined in Twig extensions are marked as internal as of Twig
+ 3.9.0, and will be removed in Twig 4.0. They have been replaced by internal
+ methods on their respective extension classes.
+
+ If you were using the ``twig_escape_filter()`` function in your code, use
+ ``$env->getRuntime(EscaperRuntime::class)->escape()`` instead.
+
+* The following methods from ``Twig\Extension\EscaperExtension`` are
+ deprecated: ``setEscaper()``, ``getEscapers()``, ``setSafeClasses``,
+ ``addSafeClasses()``. Use the same methods on the
+ ``Twig\Runtime\EscaperRuntime`` class instead:
+
+ Before:
+ ``$twig->getExtension(EscaperExtension::class)->METHOD();``
+
+ After:
+ ``$twig->getRuntime(EscaperRuntime::class)->METHOD();``
+
+Nodes
+-----
+
+* The "tag" constructor parameter of the ``Twig\Node\Node`` class is deprecated
+ as of Twig 3.12 as the tag is now automatically set by the Parser when
+ needed.
+
+* Passing a second argument to "ExpressionParser::parseFilterExpressionRaw()"
+ is deprecated as of Twig 3.12.
+
+* The following ``Twig\Node\Node`` methods will take a string or an integer
+ (instead of just a string) in Twig 4.0 for their "name" argument:
+ ``getNode()``, ``hasNode()``, ``setNode()``, ``removeNode()``, and
+ ``deprecateNode()``.
+
+* Not passing a ``BodyNode`` instance as the body of a ``ModuleNode`` or
+ ``MacroNode`` constructor is deprecated as of Twig 3.12.
+
+* Returning ``null`` from ``TokenParserInterface::parse()`` is deprecated as of
+ Twig 3.12 (as forbidden by the interface).
+
+* The second argument of the
+ ``Twig\Node\Expression\CallExpression::compileArguments()`` method is
+ deprecated.
+
+* The ``Twig\Node\Expression\NameExpression::isSimple()`` and
+ ``Twig\Node\Expression\NameExpression::isSpecial()`` methods are deprecated as
+ of Twig 3.11 and will be removed in Twig 4.0.
+
+* The ``filter`` node of ``Twig\Node\Expression\FilterExpression`` is
+ deprecated as of Twig 3.12 and will be removed in 4.0. Use the ``filter``
+ attribute instead to get the filter:
+
+ Before:
+ ``$node->getNode('filter')->getAttribute('value')``
+
+ After:
+ ``$node->getAttribute('twig_callable')->getName()``
+
+* Passing a name to ``Twig\Node\Expression\FunctionExpression``,
+ ``Twig\Node\Expression\FilterExpression``, and
+ ``Twig\Node\Expression\TestExpression`` is deprecated as of Twig 3.12.
+ As of Twig 4.0, you need to pass a ``TwigFunction``, ``TwigFilter``, or
+ ``TestFilter`` instead.
+
+ Let's take a ``FunctionExpression`` as an example.
+
+ If you have a node that extends ``FunctionExpression`` and if you don't
+ override the constructor, you don't need to do anything. But if you override
+ the constructor, then you need to change the type hint of the name and mark
+ the constructor with the ``Twig\Attribute\FirstClassTwigCallableReady`` attribute.
+
+ Before::
+
+ class NotReadyFunctionExpression extends FunctionExpression
+ {
+ public function __construct(string $function, Node $arguments, int $lineno)
+ {
+ parent::__construct($function, $arguments, $lineno);
+ }
+ }
+
+ class NotReadyFilterExpression extends FilterExpression
+ {
+ public function __construct(Node $node, ConstantExpression $filter, Node $arguments, int $lineno)
+ {
+ parent::__construct($node, $filter, $arguments, $lineno);
+ }
+ }
+
+ class NotReadyTestExpression extends TestExpression
+ {
+ public function __construct(Node $node, string $test, ?Node $arguments, int $lineno)
+ {
+ parent::__construct($node, $test, $arguments, $lineno);
+ }
+ }
+
+ After::
+
+ class ReadyFunctionExpression extends FunctionExpression
+ {
+ #[FirstClassTwigCallableReady]
+ public function __construct(TwigFunction|string $function, Node $arguments, int $lineno)
+ {
+ parent::__construct($function, $arguments, $lineno);
+ }
+ }
+
+ class ReadyFilterExpression extends FilterExpression
+ {
+ #[FirstClassTwigCallableReady]
+ public function __construct(Node $node, TwigFilter|ConstantExpression $filter, Node $arguments, int $lineno)
+ {
+ parent::__construct($node, $filter, $arguments, $lineno);
+ }
+ }
+
+ class ReadyTestExpression extends TestExpression
+ {
+ #[FirstClassTwigCallableReady]
+ public function __construct(Node $node, TwigTest|string $test, ?Node $arguments, int $lineno)
+ {
+ parent::__construct($node, $test, $arguments, $lineno);
+ }
+ }
+
+* The following ``Twig\Node\Expression\FunctionExpression`` attributes are
+ deprecated as of Twig 3.12: ``needs_charset``, ``needs_environment``,
+ ``needs_context``, ``arguments``, ``callable``, ``is_variadic``,
+ and ``dynamic_name``.
+
+* The following ``Twig\Node\Expression\FilterExpression`` attributes are
+ deprecated as of Twig 3.12: ``needs_charset``, ``needs_environment``,
+ ``needs_context``, ``arguments``, ``callable``, ``is_variadic``,
+ and ``dynamic_name``.
+
+* The following ``Twig\Node\Expression\TestExpression`` attributes are
+ deprecated as of Twig 3.12: ``arguments``, ``callable``, ``is_variadic``,
+ and ``dynamic_name``.
+
+Node Visitors
+-------------
+
+* The ``Twig\NodeVisitor\AbstractNodeVisitor`` class is deprecated, implement the
+ ``Twig\NodeVisitor\NodeVisitorInterface`` interface instead.
+
+* The ``Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER`` and the
+ ``Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_TEXT_NODES`` options are
+ deprecated as of Twig 3.12 and will be removed in Twig 4.0; they don't do
+ anything anymore.
+
+Parser
+------
+
+* The following methods from ``Twig\Parser`` are deprecated as of Twig 3.12:
+ ``getBlockStack()``, ``hasBlock()``, ``getBlock()``, ``hasMacro()``,
+ ``hasTraits()``, ``getParent()``.
+
+* The ``Twig\ExpressionParser::parseHashExpression()`` method is deprecated, use
+ ``Twig\ExpressionParser::parseMappingExpression()`` instead.
+
+* The ``Twig\ExpressionParser::parseArrayExpression()`` method is deprecated, use
+ ``Twig\ExpressionParser::parseSequenceExpression()`` instead.
+
+* Passing ``null`` to ``Twig\Parser::setParent()`` is deprecated as of Twig
+ 3.12.
+
+Templates
+---------
+
+* Passing ``Twig\Template`` instances to Twig public API is deprecated (like
+ in ``Environment::resolveTemplate()``, ``Environment::load()``, and
+ ``Template::loadTemplate()``); pass instances of ``Twig\TemplateWrapper``
+ instead.
+
+Filters
+-------
+
+* The ``spaceless`` filter is deprecated as of Twig 3.12 and will be removed in
+ Twig 4.0.
+
+Sandbox
+-------
+
+* Having the ``extends`` and ``use`` tags allowed by default in a sandbox is
+ deprecated as of Twig 3.12. You will need to explicitly allow them if needed
+ in 4.0.
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/abs.rst b/upload/system/storage/vendor/twig/twig/doc/filters/abs.rst
new file mode 100644
index 000000000..fea117536
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/abs.rst
@@ -0,0 +1,18 @@
+``abs``
+=======
+
+The ``abs`` filter returns the absolute value.
+
+.. code-block:: twig
+
+ {# number = -5 #}
+
+ {{ number|abs }}
+
+ {# outputs 5 #}
+
+.. note::
+
+ Internally, Twig uses the PHP `abs`_ function.
+
+.. _`abs`: https://www.php.net/abs
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/batch.rst b/upload/system/storage/vendor/twig/twig/doc/filters/batch.rst
new file mode 100644
index 000000000..adb2948c6
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/batch.rst
@@ -0,0 +1,77 @@
+``batch``
+=========
+
+The ``batch`` filter "batches" items by returning a list of lists with the
+given number of items. A second parameter can be provided and used to fill in
+missing items:
+
+.. code-block:: html+twig
+
+ {% set items = ['a', 'b', 'c', 'd'] %}
+
+
+ {% for row in items|batch(3, 'No item') %}
+
+ {% for index, column in row %}
+
{{ index }} - {{ column }}
+ {% endfor %}
+
+ {% endfor %}
+
+
+The above example will be rendered as:
+
+.. code-block:: html+twig
+
+
+
+
0 - a
+
1 - b
+
2 - c
+
+
+
3 - d
+
4 - No item
+
5 - No item
+
+
+
+If you choose to set the third parameter ``preserve_keys`` to ``false``, the keys will be reset in each loop.
+
+.. code-block:: html+twig
+
+ {% set items = ['a', 'b', 'c', 'd'] %}
+
+
+ {% for row in items|batch(3, 'No item', false) %}
+
+ {% for index, column in row %}
+
{{ index }} - {{ column }}
+ {% endfor %}
+
+ {% endfor %}
+
+
+The above example will be rendered as:
+
+.. code-block:: html+twig
+
+
+
+
0 - a
+
1 - b
+
2 - c
+
+
+
0 - d
+
1 - No item
+
2 - No item
+
+
+
+Arguments
+---------
+
+* ``size``: The size of the batch; fractional numbers will be rounded up
+* ``fill``: Used to fill in missing items
+* ``preserve_keys``: Whether to preserve keys or not (defaults to ``true``)
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/capitalize.rst b/upload/system/storage/vendor/twig/twig/doc/filters/capitalize.rst
new file mode 100644
index 000000000..2353658bf
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/capitalize.rst
@@ -0,0 +1,11 @@
+``capitalize``
+==============
+
+The ``capitalize`` filter capitalizes a value. The first character will be
+uppercase, all others lowercase:
+
+.. code-block:: twig
+
+ {{ 'my first car'|capitalize }}
+
+ {# outputs 'My first car' #}
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/column.rst b/upload/system/storage/vendor/twig/twig/doc/filters/column.rst
new file mode 100644
index 000000000..981b8608a
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/column.rst
@@ -0,0 +1,24 @@
+``column``
+==========
+
+The ``column`` filter returns the values from a single column in the input
+array.
+
+.. code-block:: twig
+
+ {% set items = [{ 'fruit' : 'apple'}, {'fruit' : 'orange' }] %}
+
+ {% set fruits = items|column('fruit') %}
+
+ {# fruits now contains ['apple', 'orange'] #}
+
+.. note::
+
+ Internally, Twig uses the PHP `array_column`_ function.
+
+Arguments
+---------
+
+* ``name``: The column name to extract
+
+.. _`array_column`: https://www.php.net/array_column
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/convert_encoding.rst b/upload/system/storage/vendor/twig/twig/doc/filters/convert_encoding.rst
new file mode 100644
index 000000000..98645494e
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/convert_encoding.rst
@@ -0,0 +1,22 @@
+``convert_encoding``
+====================
+
+The ``convert_encoding`` filter converts a string from one encoding to
+another. The first argument is the expected output charset and the second one
+is the input charset:
+
+.. code-block:: twig
+
+ {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
+
+.. note::
+
+ This filter relies on the `iconv`_ extension.
+
+Arguments
+---------
+
+* ``to``: The output charset
+* ``from``: The input charset
+
+.. _`iconv`: https://www.php.net/iconv
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/country_name.rst b/upload/system/storage/vendor/twig/twig/doc/filters/country_name.rst
new file mode 100644
index 000000000..434b0bda7
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/country_name.rst
@@ -0,0 +1,44 @@
+``country_name``
+================
+
+The ``country_name`` filter returns the country name given its ISO-3166
+two-letter code:
+
+.. code-block:: twig
+
+ {# France #}
+ {{ 'FR'|country_name }}
+
+By default, the filter uses the current locale. You can pass it explicitly:
+
+.. code-block:: twig
+
+ {# États-Unis #}
+ {{ 'US'|country_name('fr') }}
+
+.. note::
+
+ The ``country_name`` filter is part of the ``IntlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/intl-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Intl\IntlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new IntlExtension());
+
+Arguments
+---------
+
+* ``locale``: The locale
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/currency_name.rst b/upload/system/storage/vendor/twig/twig/doc/filters/currency_name.rst
new file mode 100644
index 000000000..a35c49998
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/currency_name.rst
@@ -0,0 +1,47 @@
+``currency_name``
+=================
+
+The ``currency_name`` filter returns the currency name given its three-letter
+code:
+
+.. code-block:: twig
+
+ {# Euro #}
+ {{ 'EUR'|currency_name }}
+
+ {# Japanese Yen #}
+ {{ 'JPY'|currency_name }}
+
+By default, the filter uses the current locale. You can pass it explicitly:
+
+.. code-block:: twig
+
+ {# yen japonais #}
+ {{ 'JPY'|currency_name('fr_FR') }}
+
+.. note::
+
+ The ``currency_name`` filter is part of the ``IntlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/intl-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Intl\IntlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new IntlExtension());
+
+Arguments
+---------
+
+* ``locale``: The locale
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/currency_symbol.rst b/upload/system/storage/vendor/twig/twig/doc/filters/currency_symbol.rst
new file mode 100644
index 000000000..84a048ed5
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/currency_symbol.rst
@@ -0,0 +1,47 @@
+``currency_symbol``
+===================
+
+The ``currency_symbol`` filter returns the currency symbol given its three-letter
+code:
+
+.. code-block:: twig
+
+ {# € #}
+ {{ 'EUR'|currency_symbol }}
+
+ {# ¥ #}
+ {{ 'JPY'|currency_symbol }}
+
+By default, the filter uses the current locale. You can pass it explicitly:
+
+.. code-block:: twig
+
+ {# ¥ #}
+ {{ 'JPY'|currency_symbol('fr') }}
+
+.. note::
+
+ The ``currency_symbol`` filter is part of the ``IntlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/intl-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Intl\IntlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new IntlExtension());
+
+Arguments
+---------
+
+* ``locale``: The locale
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/data_uri.rst b/upload/system/storage/vendor/twig/twig/doc/filters/data_uri.rst
new file mode 100644
index 000000000..a68deb0f2
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/data_uri.rst
@@ -0,0 +1,55 @@
+``data_uri``
+============
+
+The ``data_uri`` filter generates a URL using the data scheme as defined in
+`RFC 2397`_:
+
+.. code-block:: html+twig
+
+ {{ image_data|data_uri }}
+
+ {{ source('path_to_image')|data_uri }}
+
+ {# force the mime type, disable the guessing of the mime type #}
+ {{ image_data|data_uri(mime: "image/svg") }}
+
+ {# also works with plain text #}
+ {{ 'foobar'|data_uri(mime: "text/html") }}
+
+ {# add some extra parameters #}
+ {{ 'foobar'|data_uri(mime: "text/html", parameters: {charset: "ascii"}) }}
+
+.. note::
+
+ The ``data_uri`` filter is part of the ``HtmlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/html-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Html\HtmlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new HtmlExtension());
+
+.. note::
+
+ The filter does not perform any length validation on purpose (limit depends
+ on the usage context), validation should be done before calling this filter.
+
+Arguments
+---------
+
+* ``mime``: The mime type
+* ``parameters``: A mapping of parameters
+
+.. _RFC 2397: https://tools.ietf.org/html/rfc2397
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/date.rst b/upload/system/storage/vendor/twig/twig/doc/filters/date.rst
new file mode 100644
index 000000000..7ac9b8750
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/date.rst
@@ -0,0 +1,79 @@
+``date``
+========
+
+The ``date`` filter formats a date to a given format:
+
+.. code-block:: twig
+
+ {{ post.published_at|date("m/d/Y") }}
+
+The format specifier is the same as supported by `date`_,
+except when the filtered data is of type `DateInterval`_, when the format must conform to
+`DateInterval::format`_ instead.
+
+The ``date`` filter accepts strings (it must be in a format supported by the
+`strtotime`_ function), `DateTime`_ instances, or `DateInterval`_ instances. For
+instance, to display the current date, filter the word "now":
+
+.. code-block:: twig
+
+ {{ "now"|date("m/d/Y") }}
+
+To escape words and characters in the date format use ``\\`` in front of each
+character:
+
+.. code-block:: twig
+
+ {{ post.published_at|date("F jS \\a\\t g:ia") }}
+
+If the value passed to the ``date`` filter is ``null``, it will return the
+current date by default. If an empty string is desired instead of the current
+date, use a ternary operator:
+
+.. code-block:: twig
+
+ {{ post.published_at is empty ? "" : post.published_at|date("m/d/Y") }}
+
+If no format is provided, Twig will use the default one: ``F j, Y H:i``. This
+default can be changed by calling the ``setDateFormat()`` method on the
+``core`` extension instance. The first argument is the default format for
+dates and the second one is the default format for date intervals::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension(\Twig\Extension\CoreExtension::class)->setDateFormat('d/m/Y', '%d days');
+
+Timezone
+--------
+
+By default, the date is displayed by applying the default timezone (the one
+specified in php.ini or declared in Twig -- see below), but you can override
+it by explicitly specifying a supported `timezone`_:
+
+.. code-block:: twig
+
+ {{ post.published_at|date("m/d/Y", "Europe/Paris") }}
+
+If the date is already a DateTime object, and if you want to keep its current
+timezone, pass ``false`` as the timezone value:
+
+.. code-block:: twig
+
+ {{ post.published_at|date("m/d/Y", false) }}
+
+The default timezone can also be set globally by calling ``setTimezone()``::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone('Europe/Paris');
+
+Arguments
+---------
+
+* ``format``: The date format (default format is ``F j, Y H:i``, which will render as ``January 11, 2024 15:17``)
+* ``timezone``: The date timezone
+
+.. _`strtotime`: https://www.php.net/strtotime
+.. _`DateTime`: https://www.php.net/DateTime
+.. _`DateInterval`: https://www.php.net/DateInterval
+.. _`date`: https://www.php.net/date
+.. _`DateInterval::format`: https://www.php.net/DateInterval.format
+.. _`timezone`: https://www.php.net/manual/en/timezones.php
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/date_modify.rst b/upload/system/storage/vendor/twig/twig/doc/filters/date_modify.rst
new file mode 100644
index 000000000..e091391d1
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/date_modify.rst
@@ -0,0 +1,20 @@
+``date_modify``
+===============
+
+The ``date_modify`` filter modifies a date with a given modifier string:
+
+.. code-block:: twig
+
+ {{ post.published_at|date_modify("+1 day")|date("m/d/Y") }}
+
+The ``date_modify`` filter accepts strings (it must be in a format supported
+by the `strtotime`_ function) or `DateTime`_ instances. You can combine
+it with the :doc:`date` filter for formatting.
+
+Arguments
+---------
+
+* ``modifier``: The modifier
+
+.. _`strtotime`: https://www.php.net/strtotime
+.. _`DateTime`: https://www.php.net/DateTime
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/default.rst b/upload/system/storage/vendor/twig/twig/doc/filters/default.rst
new file mode 100644
index 000000000..2376fe7a6
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/default.rst
@@ -0,0 +1,42 @@
+``default``
+===========
+
+The ``default`` filter returns the passed default value if the value is
+undefined or empty, otherwise the value of the variable:
+
+.. code-block:: twig
+
+ {{ var|default('var is not defined') }}
+
+ {{ var.foo|default('foo item on var is not defined') }}
+
+ {{ var['foo']|default('foo item on var is not defined') }}
+
+ {{ ''|default('passed var is empty') }}
+
+When using the ``default`` filter on an expression that uses variables in some
+method calls, be sure to use the ``default`` filter whenever a variable can be
+undefined:
+
+.. code-block:: twig
+
+ {{ var.method(foo|default('foo'))|default('foo') }}
+
+Using the ``default`` filter on a boolean variable might trigger unexpected behavior, as
+``false`` is treated as an empty value. Consider using ``??`` instead:
+
+.. code-block:: twig
+
+ {% set foo = false %}
+ {{ foo|default(true) }} {# true #}
+ {{ foo ?? true }} {# false #}
+
+.. note::
+
+ Read the documentation for the :doc:`defined<../tests/defined>` and
+ :doc:`empty<../tests/empty>` tests to learn more about their semantics.
+
+Arguments
+---------
+
+* ``default``: The default value
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/escape.rst b/upload/system/storage/vendor/twig/twig/doc/filters/escape.rst
new file mode 100644
index 000000000..70d18eb57
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/escape.rst
@@ -0,0 +1,136 @@
+``escape``
+==========
+
+The ``escape`` filter escapes a string using strategies that depend on the
+context.
+
+By default, it uses the HTML escaping strategy:
+
+.. code-block:: html+twig
+
+
+ {{ user.username|escape }}
+
+
+For convenience, the ``e`` filter is defined as an alias:
+
+.. code-block:: html+twig
+
+
+ {{ user.username|e }}
+
+
+The ``escape`` filter can also be used in other contexts than HTML thanks to
+an optional argument which defines the escaping strategy to use:
+
+.. code-block:: twig
+
+ {{ user.username|e }}
+ {# is equivalent to #}
+ {{ user.username|e('html') }}
+
+And here is how to escape variables included in JavaScript code:
+
+.. code-block:: twig
+
+ {{ user.username|escape('js') }}
+ {{ user.username|e('js') }}
+
+The ``escape`` filter supports the following escaping strategies for HTML
+documents:
+
+* ``html``: escapes a string for the **HTML body** context.
+
+* ``js``: escapes a string for the **JavaScript** context.
+
+* ``css``: escapes a string for the **CSS** context. CSS escaping can be
+ applied to any string being inserted into CSS and escapes everything except
+ alphanumerics.
+
+* ``url``: escapes a string for the **URI or parameter** contexts. This should
+ not be used to escape an entire URI; only a subcomponent being inserted.
+
+* ``html_attr``: escapes a string for the **HTML attribute** context.
+
+Note that doing contextual escaping in HTML documents is hard and choosing the
+right escaping strategy depends on a lot of factors. Please, read related
+documentation like `the OWASP prevention cheat sheet
+`_
+to learn more about this topic.
+
+.. note::
+
+ Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function
+ for the HTML escaping strategy.
+
+.. caution::
+
+ When using automatic escaping, Twig tries to not double-escape a variable
+ when the automatic escaping strategy is the same as the one applied by the
+ escape filter; but that does not work when using a variable as the
+ escaping strategy:
+
+ .. code-block:: twig
+
+ {% set strategy = 'html' %}
+
+ {% autoescape 'html' %}
+ {{ var|escape('html') }} {# won't be double-escaped #}
+ {{ var|escape(strategy) }} {# will be double-escaped #}
+ {% endautoescape %}
+
+ When using a variable as the escaping strategy, you should disable
+ automatic escaping:
+
+ .. code-block:: twig
+
+ {% set strategy = 'html' %}
+
+ {% autoescape 'html' %}
+ {{ var|escape(strategy)|raw }} {# won't be double-escaped #}
+ {% endautoescape %}
+
+Custom Escapers
+---------------
+
+.. versionadded:: 3.10
+
+ The ``EscaperRuntime`` class has been added in 3.10. On previous versions,
+ you can define custom escapers by calling the ``setEscaper()`` method on
+ the escaper extension instance. The first argument is the escaper strategy
+ (to be used in the ``escape`` call) and the second one must be a valid PHP
+ callable::
+
+ use Twig\Extension\EscaperExtension;
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension(EscaperExtension::class)->setEscaper('csv', 'csv_escaper');
+
+ When called by Twig, the callable receives the Twig environment instance,
+ the string to escape, and the charset.
+
+You can define custom escapers by calling the ``setEscaper()`` method on the
+escaper runtime instance. It accepts two arguments: the strategy name and a PHP
+callable that accepts a string to escape and the charset::
+
+ use Twig\Runtime\EscaperRuntime;
+
+ $twig = new \Twig\Environment($loader);
+ $escaper = fn ($string, $charset) => $string;
+ $twig->getRuntime(EscaperRuntime::class)->setEscaper('identity', $escaper);
+
+ # Usage in a template:
+ # {{ 'foo'|escape('identity') }}
+
+.. note::
+
+ Built-in escapers cannot be overridden mainly because they should be
+ considered as the final implementation and also for better performance.
+
+Arguments
+---------
+
+* ``strategy``: The escaping strategy
+* ``charset``: The string charset
+
+.. _`htmlspecialchars`: https://www.php.net/htmlspecialchars
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/filter.rst b/upload/system/storage/vendor/twig/twig/doc/filters/filter.rst
new file mode 100644
index 000000000..257421f66
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/filter.rst
@@ -0,0 +1,55 @@
+``filter``
+==========
+
+The ``filter`` filter filters elements of a sequence or a mapping using an arrow
+function. The arrow function receives the value of the sequence or mapping:
+
+.. code-block:: twig
+
+ {% set sizes = [34, 36, 38, 40, 42] %}
+
+ {{ sizes|filter(v => v > 38)|join(', ') }}
+ {# output 40, 42 #}
+
+Combined with the ``for`` tag, it allows to filter the items to iterate over:
+
+.. code-block:: twig
+
+ {% for v in sizes|filter(v => v > 38) -%}
+ {{ v }}
+ {% endfor %}
+ {# output 40 42 #}
+
+It also works with mappings:
+
+.. code-block:: twig
+
+ {% set sizes = {
+ xs: 34,
+ s: 36,
+ m: 38,
+ l: 40,
+ xl: 42,
+ } %}
+
+ {% for k, v in sizes|filter(v => v > 38) -%}
+ {{ k }} = {{ v }}
+ {% endfor %}
+ {# output l = 40 xl = 42 #}
+
+The arrow function also receives the key as a second argument:
+
+.. code-block:: twig
+
+ {% for k, v in sizes|filter((v, k) => v > 38 and k != "xl") -%}
+ {{ k }} = {{ v }}
+ {% endfor %}
+ {# output l = 40 #}
+
+Note that the arrow function has access to the current context.
+
+Arguments
+---------
+
+* ``array``: The sequence or mapping
+* ``arrow``: The arrow function
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/find.rst b/upload/system/storage/vendor/twig/twig/doc/filters/find.rst
new file mode 100644
index 000000000..f11b68e36
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/find.rst
@@ -0,0 +1,57 @@
+``find``
+========
+
+.. versionadded:: 3.11
+
+ The ``find`` filter was added in Twig 3.11.
+
+The ``find`` filter returns the first element of a sequence matching an arrow
+function. The arrow function receives the value of the sequence:
+
+.. code-block:: twig
+
+ {% set sizes = [34, 36, 38, 40, 42] %}
+
+ {{ sizes|find(v => v > 38) }}
+ {# output 40 #}
+
+It also works with mappings:
+
+.. code-block:: twig
+
+ {% set sizes = {
+ xxs: 32,
+ xs: 34,
+ s: 36,
+ m: 38,
+ l: 40,
+ xl: 42,
+ } %}
+
+ {{ sizes|find(v => v > 38) }}
+
+ {# output 40 #}
+
+The arrow function also receives the key as a second argument:
+
+.. code-block:: twig
+
+ {{ sizes|find((v, k) => 's' not in k) }}
+
+ {# output 38 #}
+
+Note that the arrow function has access to the current context:
+
+.. code-block:: twig
+
+ {% set my_size = 39 %}
+
+ {{ sizes|find(v => v >= my_size) }}
+
+ {# output 40 #}
+
+Arguments
+---------
+
+* ``array``: The sequence or mapping
+* ``arrow``: The arrow function
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/first.rst b/upload/system/storage/vendor/twig/twig/doc/filters/first.rst
new file mode 100644
index 000000000..0d9ba9c49
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/first.rst
@@ -0,0 +1,22 @@
+``first``
+=========
+
+The ``first`` filter returns the first "element" of a sequence, a mapping, or
+a string:
+
+.. code-block:: twig
+
+ {{ [1, 2, 3, 4]|first }}
+ {# outputs 1 #}
+
+ {{ {a: 1, b: 2, c: 3, d: 4}|first }}
+ {# outputs 1 #}
+
+ {{ '1234'|first }}
+ {# outputs 1 #}
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+.. _`Traversable`: https://www.php.net/manual/en/class.traversable.php
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/format.rst b/upload/system/storage/vendor/twig/twig/doc/filters/format.rst
new file mode 100644
index 000000000..68551a3dd
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/format.rst
@@ -0,0 +1,18 @@
+``format``
+==========
+
+The ``format`` filter formats a given string by replacing the placeholders
+(placeholders follows the `sprintf`_ notation):
+
+.. code-block:: twig
+
+ {{ "I like %s and %s."|format(foo, "bar") }}
+
+ {# outputs I like foo and bar
+ if the foo parameter equals to the foo string. #}
+
+.. seealso::
+
+ :doc:`replace`
+
+.. _`sprintf`: https://www.php.net/sprintf
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/format_currency.rst b/upload/system/storage/vendor/twig/twig/doc/filters/format_currency.rst
new file mode 100644
index 000000000..c4c364a00
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/format_currency.rst
@@ -0,0 +1,77 @@
+``format_currency``
+===================
+
+The ``format_currency`` filter formats a number as a currency:
+
+.. code-block:: twig
+
+ {# €1,000,000.00 #}
+ {{ '1000000'|format_currency('EUR') }}
+
+You can pass attributes to tweak the output:
+
+.. code-block:: twig
+
+ {# €12.34 #}
+ {{ '12.345'|format_currency('EUR', {rounding_mode: 'floor'}) }}
+
+ {# €1,000,000.0000 #}
+ {{ '1000000'|format_currency('EUR', {fraction_digit: 4}) }}
+
+The list of supported options:
+
+* ``grouping_used``;
+* ``decimal_always_shown``;
+* ``max_integer_digit``;
+* ``min_integer_digit``;
+* ``integer_digit``;
+* ``max_fraction_digit``;
+* ``min_fraction_digit``;
+* ``fraction_digit``;
+* ``multiplier``;
+* ``grouping_size``;
+* ``rounding_mode``;
+* ``rounding_increment``;
+* ``format_width``;
+* ``padding_position``;
+* ``secondary_grouping_size``;
+* ``significant_digits_used``;
+* ``min_significant_digits_used``;
+* ``max_significant_digits_used``;
+* ``lenient_parse``.
+
+By default, the filter uses the current locale. You can pass it explicitly:
+
+.. code-block:: twig
+
+ {# 1.000.000,00 € #}
+ {{ '1000000'|format_currency('EUR', locale: 'de') }}
+
+.. note::
+
+ The ``format_currency`` filter is part of the ``IntlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/intl-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Intl\IntlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new IntlExtension());
+
+Arguments
+---------
+
+* ``currency``: The currency
+* ``attrs``: A map of attributes
+* ``locale``: The locale
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/format_date.rst b/upload/system/storage/vendor/twig/twig/doc/filters/format_date.rst
new file mode 100644
index 000000000..cd6beba9f
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/format_date.rst
@@ -0,0 +1,36 @@
+``format_date``
+===============
+
+The ``format_date`` filter formats a date. It behaves in the exact same way as
+the :doc:`format_datetime` filter, but without the time.
+
+.. note::
+
+ The ``format_date`` filter is part of the ``IntlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/intl-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Intl\IntlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new IntlExtension());
+
+Arguments
+---------
+
+* ``locale``: The locale
+* ``dateFormat``: The date format
+* ``pattern``: A date time pattern
+* ``timezone``: The date timezone
+* ``calendar``: The calendar ("gregorian" by default)
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/format_datetime.rst b/upload/system/storage/vendor/twig/twig/doc/filters/format_datetime.rst
new file mode 100644
index 000000000..a47d49731
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/format_datetime.rst
@@ -0,0 +1,108 @@
+``format_datetime``
+===================
+
+The ``format_datetime`` filter formats a date time:
+
+.. code-block:: twig
+
+ {# Aug 7, 2019, 11:39:12 PM #}
+ {{ '2019-08-07 23:39:12'|format_datetime() }}
+
+Format
+------
+
+You can tweak the output for the date part and the time part:
+
+.. code-block:: twig
+
+ {# 23:39 #}
+ {{ '2019-08-07 23:39:12'|format_datetime('none', 'short', locale: 'fr') }}
+
+ {# 07/08/2019 #}
+ {{ '2019-08-07 23:39:12'|format_datetime('short', 'none', locale: 'fr') }}
+
+ {# mercredi 7 août 2019 23:39:12 UTC #}
+ {{ '2019-08-07 23:39:12'|format_datetime('full', 'full', locale: 'fr') }}
+
+Supported values are: ``none``, ``short``, ``medium``, ``long``, and ``full``.
+
+.. versionadded:: 3.6
+
+ ``relative_short``, ``relative_medium``, ``relative_long``, and ``relative_full`` are also supported when running on
+ PHP 8.0 and superior or when using a polyfill that define the ``IntlDateFormatter::RELATIVE_*`` constants and
+ associated behavior.
+
+For greater flexibility, you can even define your own pattern
+(see the `ICU user guide`_ for supported patterns).
+
+.. code-block:: twig
+
+ {# 11 oclock PM, GMT #}
+ {{ '2019-08-07 23:39:12'|format_datetime(pattern: "hh 'oclock' a, zzzz") }}
+
+Locale
+------
+
+By default, the filter uses the current locale. You can pass it explicitly:
+
+.. code-block:: twig
+
+ {# 7 août 2019 23:39:12 #}
+ {{ '2019-08-07 23:39:12'|format_datetime(locale: 'fr') }}
+
+Timezone
+--------
+
+By default, the date is displayed by applying the default timezone (the one
+specified in php.ini or declared in Twig -- see below), but you can override
+it by explicitly specifying a timezone:
+
+.. code-block:: twig
+
+ {{ datetime|format_datetime(locale: 'en', timezone: 'Pacific/Midway') }}
+
+If the date is already a DateTime object, and if you want to keep its current
+timezone, pass ``false`` as the timezone value:
+
+.. code-block:: twig
+
+ {{ datetime|format_datetime(locale: 'en', timezone: false) }}
+
+The default timezone can also be set globally by calling ``setTimezone()``::
+
+ $twig = new \Twig\Environment($loader);
+ $twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone('Europe/Paris');
+
+.. note::
+
+ The ``format_datetime`` filter is part of the ``IntlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/intl-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Intl\IntlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new IntlExtension());
+
+Arguments
+---------
+
+* ``locale``: The locale
+* ``dateFormat``: The date format
+* ``timeFormat``: The time format
+* ``pattern``: A date time pattern
+* ``timezone``: The date timezone name
+* ``calendar``: The calendar ("gregorian" by default)
+
+.. _ICU user guide: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/format_number.rst b/upload/system/storage/vendor/twig/twig/doc/filters/format_number.rst
new file mode 100644
index 000000000..900fa5ea9
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/format_number.rst
@@ -0,0 +1,117 @@
+``format_number``
+=================
+
+The ``format_number`` filter formats a number:
+
+.. code-block:: twig
+
+ {{ '12.345'|format_number }}
+
+You can pass attributes to tweak the output:
+
+.. code-block:: twig
+
+ {# 12.34 #}
+ {{ '12.345'|format_number({rounding_mode: 'floor'}) }}
+
+ {# 1000000.0000 #}
+ {{ '1000000'|format_number({fraction_digit: 4}) }}
+
+The list of supported options:
+
+* ``grouping_used``;
+* ``decimal_always_shown``;
+* ``max_integer_digit``;
+* ``min_integer_digit``;
+* ``integer_digit``;
+* ``max_fraction_digit``;
+* ``min_fraction_digit``;
+* ``fraction_digit``;
+* ``multiplier``;
+* ``grouping_size``;
+* ``rounding_mode``;
+* ``rounding_increment``;
+* ``format_width``;
+* ``padding_position``;
+* ``secondary_grouping_size``;
+* ``significant_digits_used``;
+* ``min_significant_digits_used``;
+* ``max_significant_digits_used``;
+* ``lenient_parse``.
+
+Besides plain numbers, the filter can also format numbers in various styles:
+
+.. code-block:: twig
+
+ {# 1,234% #}
+ {{ '12.345'|format_number(style: 'percent') }}
+
+ {# twelve point three four five #}
+ {{ '12.345'|format_number(style: 'spellout') }}
+
+ {# 12 sec. #}
+ {{ '12'|format_duration_number }}
+
+The list of supported styles:
+
+* ``decimal``;
+* ``currency``;
+* ``percent``;
+* ``scientific``;
+* ``spellout``;
+* ``ordinal``;
+* ``duration``.
+
+As a shortcut, you can use the ``format_*_number`` filters by replacing ``*``
+with a style:
+
+.. code-block:: twig
+
+ {# 1,234% #}
+ {{ '12.345'|format_percent_number }}
+
+ {# twelve point three four five #}
+ {{ '12.345'|format_spellout_number }}
+
+You can pass attributes to tweak the output:
+
+.. code-block:: twig
+
+ {# 12.3% #}
+ {{ '0.12345'|format_percent_number({rounding_mode: 'floor', fraction_digit: 1}) }}
+
+By default, the filter uses the current locale. You can pass it explicitly:
+
+.. code-block:: twig
+
+ {# 12,345 #}
+ {{ '12.345'|format_number(locale: 'fr') }}
+
+.. note::
+
+ The ``format_number`` filter is part of the ``IntlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/intl-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Intl\IntlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new IntlExtension());
+
+Arguments
+---------
+
+* ``locale``: The locale
+* ``attrs``: A map of attributes
+* ``style``: The style of the number output
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/format_time.rst b/upload/system/storage/vendor/twig/twig/doc/filters/format_time.rst
new file mode 100644
index 000000000..1e213e616
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/format_time.rst
@@ -0,0 +1,36 @@
+``format_time``
+===============
+
+The ``format_time`` filter formats a time. It behaves in the exact same way as
+the :doc:`format_datetime` filter, but without the date.
+
+.. note::
+
+ The ``format_time`` filter is part of the ``IntlExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/intl-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Intl\IntlExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new IntlExtension());
+
+Arguments
+---------
+
+* ``locale``: The locale
+* ``timeFormat``: The time format
+* ``pattern``: A date time pattern
+* ``timezone``: The date timezone
+* ``calendar``: The calendar ("gregorian" by default)
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/html_to_markdown.rst b/upload/system/storage/vendor/twig/twig/doc/filters/html_to_markdown.rst
new file mode 100644
index 000000000..58568a445
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/html_to_markdown.rst
@@ -0,0 +1,77 @@
+``html_to_markdown``
+====================
+
+The ``html_to_markdown`` filter converts a block of HTML to Markdown:
+
+.. code-block:: html+twig
+
+ {% apply html_to_markdown %}
+
+
Hello!
+
+ {% endapply %}
+
+You can also use the filter on an entire template which you ``include``:
+
+.. code-block:: twig
+
+ {{ include('some_template.html.twig')|html_to_markdown }}
+
+.. note::
+
+ The ``html_to_markdown`` filter is part of the ``MarkdownExtension`` which
+ is not installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/markdown-extra
+
+ On Symfony projects, you can automatically enable it by installing the
+ ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Or add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Markdown\MarkdownExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new MarkdownExtension());
+
+ If you are not using Symfony, you must also register the extension runtime::
+
+ use Twig\Extra\Markdown\DefaultMarkdown;
+ use Twig\Extra\Markdown\MarkdownRuntime;
+ use Twig\RuntimeLoader\RuntimeLoaderInterface;
+
+ $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
+ public function load($class) {
+ if (MarkdownRuntime::class === $class) {
+ return new MarkdownRuntime(new DefaultMarkdown());
+ }
+ }
+ });
+
+``html_to_markdown`` is just a frontend; the actual conversion is done by one of
+the following compatible libraries, from which you can choose:
+
+* `league/html-to-markdown`_
+* `michelf/php-markdown`_
+* `erusev/parsedown`_
+
+Depending on the library, you can also add some options by passing them as an argument
+to the filter. Example for ``league/html-to-markdown``:
+
+.. code-block:: html+twig
+
+ {% apply html_to_markdown({hard_break: false}) %}
+
+
Hello!
+
+ {% endapply %}
+
+.. _league/html-to-markdown: https://github.com/thephpleague/html-to-markdown
+.. _michelf/php-markdown: https://github.com/michelf/php-markdown
+.. _erusev/parsedown: https://github.com/erusev/parsedown
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/index.rst b/upload/system/storage/vendor/twig/twig/doc/filters/index.rst
new file mode 100644
index 000000000..7d2bde1b1
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/index.rst
@@ -0,0 +1,63 @@
+Filters
+=======
+
+.. toctree::
+ :maxdepth: 1
+
+ abs
+ batch
+ capitalize
+ column
+ convert_encoding
+ country_name
+ currency_name
+ currency_symbol
+ data_uri
+ date
+ date_modify
+ default
+ escape
+ filter
+ first
+ format
+ format_currency
+ format_date
+ format_datetime
+ format_number
+ format_time
+ html_to_markdown
+ inline_css
+ inky_to_html
+ join
+ json_encode
+ keys
+ language_name
+ last
+ length
+ locale_name
+ lower
+ map
+ markdown_to_html
+ merge
+ nl2br
+ number_format
+ plural
+ raw
+ reduce
+ replace
+ reverse
+ round
+ shuffle
+ singular
+ slice
+ slug
+ sort
+ spaceless
+ split
+ striptags
+ timezone_name
+ title
+ trim
+ u
+ upper
+ url_encode
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/inky_to_html.rst b/upload/system/storage/vendor/twig/twig/doc/filters/inky_to_html.rst
new file mode 100644
index 000000000..563baba36
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/inky_to_html.rst
@@ -0,0 +1,42 @@
+``inky_to_html``
+================
+
+The ``inky_to_html`` filter processes an `inky email template
+`_:
+
+.. code-block:: html+twig
+
+ {% apply inky_to_html %}
+
+
+
+
+ {% endapply %}
+
+You can also use the filter on an included file:
+
+.. code-block:: twig
+
+ {{ include('some_template.inky.twig')|inky_to_html }}
+
+.. note::
+
+ The ``inky_to_html`` filter is part of the ``InkyExtension`` which is not
+ installed by default. Install it first:
+
+ .. code-block:: bash
+
+ $ composer require twig/inky-extra
+
+ Then, on Symfony projects, install the ``twig/extra-bundle``:
+
+ .. code-block:: bash
+
+ $ composer require twig/extra-bundle
+
+ Otherwise, add the extension explicitly on the Twig environment::
+
+ use Twig\Extra\Inky\InkyExtension;
+
+ $twig = new \Twig\Environment(...);
+ $twig->addExtension(new InkyExtension());
diff --git a/upload/system/storage/vendor/twig/twig/doc/filters/inline_css.rst b/upload/system/storage/vendor/twig/twig/doc/filters/inline_css.rst
new file mode 100644
index 000000000..44b142626
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/filters/inline_css.rst
@@ -0,0 +1,66 @@
+``inline_css``
+==============
+
+The ``inline_css`` filter inline CSS styles in HTML documents:
+
+.. code-block:: html+twig
+
+ {% apply inline_css %}
+
+
+
+
+
+
Hello CSS!
+
+
+ {% endapply %}
+
+You can also add some stylesheets by passing them as arguments to the filter:
+
+.. code-block:: html+twig
+
+ {% apply inline_css(source("some_styles.css"), source("another.css")) %}
+
+
+
Hello CSS!
+
+
+ {% endapply %}
+
+Styles loaded via the filter override the styles defined in the ``
+ {% endblock %}
+ {% block content %}
+
Index
+
+ Welcome on my awesome homepage.
+
+ {% endblock %}
+
+The ``extends`` tag is the key here. It tells the template engine that this
+template "extends" another template. When the template system evaluates this
+template, first it locates the parent. The extends tag should be the first tag
+in the template.
+
+Note that since the child template doesn't define the ``footer`` block, the
+value from the parent template is used instead.
+
+You can't define multiple ``block`` tags with the same name in the same
+template. This limitation exists because a block tag works in "both"
+directions. That is, a block tag doesn't just provide a hole to fill - it also
+defines the content that fills the hole in the *parent*. If there were two
+similarly-named ``block`` tags in a template, that template's parent wouldn't
+know which one of the blocks' content to use.
+
+If you want to print a block multiple times you can however use the
+``block`` function:
+
+.. code-block:: html+twig
+
+ {% block title %}{% endblock %}
+
{{ block('title') }}
+ {% block body %}{% endblock %}
+
+Parent Blocks
+-------------
+
+It's possible to render the contents of the parent block by using the
+:doc:`parent<../functions/parent>` function. This gives back the results of
+the parent block:
+
+.. code-block:: html+twig
+
+ {% block sidebar %}
+
Table Of Contents
+ ...
+ {{ parent() }}
+ {% endblock %}
+
+Named Block End-Tags
+--------------------
+
+Twig allows you to put the name of the block after the end tag for better
+readability (the name after the ``endblock`` word must match the block name):
+
+.. code-block:: twig
+
+ {% block sidebar %}
+ {% block inner_sidebar %}
+ ...
+ {% endblock inner_sidebar %}
+ {% endblock sidebar %}
+
+Block Nesting and Scope
+-----------------------
+
+Blocks can be nested for more complex layouts. Per default, blocks have access
+to variables from outer scopes:
+
+.. code-block:: html+twig
+
+ {% for item in seq %}
+
{% block loop_item %}{{ item }}{% endblock %}
+ {% endfor %}
+
+Block Shortcuts
+---------------
+
+For blocks with little content, it's possible to use a shortcut syntax. The
+following constructs do the same thing:
+
+.. code-block:: twig
+
+ {% block title %}
+ {{ page_title|title }}
+ {% endblock %}
+
+.. code-block:: twig
+
+ {% block title page_title|title %}
+
+Dynamic Inheritance
+-------------------
+
+Twig supports dynamic inheritance by using a variable as the base template:
+
+.. code-block:: twig
+
+ {% extends some_var %}
+
+If the variable evaluates to a ``\Twig\Template`` or a ``\Twig\TemplateWrapper``
+instance, Twig will use it as the parent template::
+
+ // {% extends layout %}
+
+ $layout = $twig->load('some_layout_template.twig');
+
+ $twig->display('template.twig', ['layout' => $layout]);
+
+You can also provide a list of templates that are checked for existence. The
+first template that exists will be used as a parent:
+
+.. code-block:: twig
+
+ {% extends ['layout.html', 'base_layout.html'] %}
+
+Conditional Inheritance
+-----------------------
+
+As the template name for the parent can be any valid Twig expression, it's
+possible to make the inheritance mechanism conditional:
+
+.. code-block:: twig
+
+ {% extends standalone ? "minimum.html" : "base.html" %}
+
+In this example, the template will extend the "minimum.html" layout template
+if the ``standalone`` variable evaluates to ``true``, and "base.html"
+otherwise.
+
+How do blocks work?
+-------------------
+
+A block provides a way to change how a certain part of a template is rendered
+but it does not interfere in any way with the logic around it.
+
+Let's take the following example to illustrate how a block works and more
+importantly, how it does not work:
+
+.. code-block:: html+twig
+
+ {# base.twig #}
+ {% for post in posts %}
+ {% block post %}
+
{{ post.title }}
+
{{ post.body }}
+ {% endblock %}
+ {% endfor %}
+
+If you render this template, the result would be exactly the same with or
+without the ``block`` tag. The ``block`` inside the ``for`` loop is just a way
+to make it overridable by a child template:
+
+.. code-block:: html+twig
+
+ {# child.twig #}
+ {% extends "base.twig" %}
+
+ {% block post %}
+
+ {{ post.title }}
+ {{ post.text }}
+
+ {% endblock %}
+
+Now, when rendering the child template, the loop is going to use the block
+defined in the child template instead of the one defined in the base one; the
+executed template is then equivalent to the following one:
+
+.. code-block:: html+twig
+
+ {% for post in posts %}
+
+ {{ post.title }}
+ {{ post.text }}
+
+ {% endfor %}
+
+Let's take another example: a block included within an ``if`` statement:
+
+.. code-block:: html+twig
+
+ {% if posts is empty %}
+ {% block head %}
+ {{ parent() }}
+
+
+ {% endblock head %}
+ {% endif %}
+
+Contrary to what you might think, this template does not define a block
+conditionally; it just makes overridable by a child template the output of
+what will be rendered when the condition is ``true``.
+
+If you want the output to be displayed conditionally, use the following
+instead:
+
+.. code-block:: html+twig
+
+ {% block head %}
+ {{ parent() }}
+
+ {% if posts is empty %}
+
+ {% endif %}
+ {% endblock head %}
+
+.. seealso::
+
+ :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/flush.rst b/upload/system/storage/vendor/twig/twig/doc/tags/flush.rst
new file mode 100644
index 000000000..03d2a3677
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/flush.rst
@@ -0,0 +1,14 @@
+``flush``
+=========
+
+The ``flush`` tag tells Twig to flush the output buffer:
+
+.. code-block:: twig
+
+ {% flush %}
+
+.. note::
+
+ Internally, Twig uses the PHP `flush`_ function.
+
+.. _`flush`: https://www.php.net/flush
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/for.rst b/upload/system/storage/vendor/twig/twig/doc/tags/for.rst
new file mode 100644
index 000000000..656d9c07b
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/for.rst
@@ -0,0 +1,141 @@
+``for``
+=======
+
+Loop over each item in a sequence or a mapping. For example, to display a list
+of users provided in a variable called ``users``:
+
+.. code-block:: html+twig
+
+
Members
+
+ {% for user in users %}
+
{{ user.username|e }}
+ {% endfor %}
+
+
+.. note::
+
+ A sequence or a mapping can be either an array or an object implementing
+ the ``Traversable`` interface.
+
+If you do need to iterate over a sequence of numbers, you can use the ``..``
+operator:
+
+.. code-block:: twig
+
+ {% for i in 0..10 %}
+ * {{ i }}
+ {% endfor %}
+
+The above snippet of code would print all numbers from 0 to 10.
+
+It can be also useful with letters:
+
+.. code-block:: twig
+
+ {% for letter in 'a'..'z' %}
+ * {{ letter }}
+ {% endfor %}
+
+The ``..`` operator can take any expression at both sides:
+
+.. code-block:: twig
+
+ {% for letter in 'a'|upper..'z'|upper %}
+ * {{ letter }}
+ {% endfor %}
+
+.. tip:
+
+ If you need a step different from 1, you can use the ``range`` function
+ instead.
+
+The ``loop`` variable
+---------------------
+
+Inside of a ``for`` loop block you can access some special variables:
+
+===================== =============================================================
+Variable Description
+===================== =============================================================
+``loop.index`` The current iteration of the loop. (1 indexed)
+``loop.index0`` The current iteration of the loop. (0 indexed)
+``loop.revindex`` The number of iterations from the end of the loop (1 indexed)
+``loop.revindex0`` The number of iterations from the end of the loop (0 indexed)
+``loop.first`` True if first iteration
+``loop.last`` True if last iteration
+``loop.length`` The number of items in the sequence
+``loop.parent`` The parent context
+===================== =============================================================
+
+.. code-block:: twig
+
+ {% for user in users %}
+ {{ loop.index }} - {{ user.username }}
+ {% endfor %}
+
+.. note::
+
+ The ``loop.length``, ``loop.revindex``, ``loop.revindex0``, and
+ ``loop.last`` variables are only available for PHP arrays, or objects that
+ implement the ``Countable`` interface.
+
+The ``else`` Clause
+-------------------
+
+If no iteration took place because the sequence was empty, you can render a
+replacement block by using ``else``:
+
+.. code-block:: html+twig
+
+
+ {% for user in users %}
+
{{ user.username|e }}
+ {% else %}
+
no user found
+ {% endfor %}
+
+
+Iterating over Keys
+-------------------
+
+By default, a loop iterates over the values of the sequence. You can iterate
+on keys by using the ``keys`` filter:
+
+.. code-block:: html+twig
+
+
Members
+
+ {% for key in users|keys %}
+
{{ key }}
+ {% endfor %}
+
+
+Iterating over Keys and Values
+------------------------------
+
+You can also access both keys and values:
+
+.. code-block:: html+twig
+
+
Members
+
+ {% for key, user in users %}
+
{{ key }}: {{ user.username|e }}
+ {% endfor %}
+
+
+Iterating over a Subset
+-----------------------
+
+You might want to iterate over a subset of values. This can be achieved using
+the :doc:`slice <../filters/slice>` filter:
+
+.. code-block:: html+twig
+
+
Top Ten Members
+
+ {% for user in users|slice(0, 10) %}
+
{{ user.username|e }}
+ {% endfor %}
+
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/from.rst b/upload/system/storage/vendor/twig/twig/doc/tags/from.rst
new file mode 100644
index 000000000..96c439aa7
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/from.rst
@@ -0,0 +1,6 @@
+``from``
+========
+
+The ``from`` tag imports :doc:`macro<../tags/macro>` names into the current
+namespace. The tag is documented in detail in the documentation for the
+:doc:`macro<../tags/macro>` tag.
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/if.rst b/upload/system/storage/vendor/twig/twig/doc/tags/if.rst
new file mode 100644
index 000000000..8a29af5da
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/if.rst
@@ -0,0 +1,80 @@
+``if``
+======
+
+The ``if`` statement in Twig is comparable with the if statements of PHP.
+
+In the simplest form you can use it to test if an expression evaluates to
+``true``:
+
+.. code-block:: html+twig
+
+ {% if online == false %}
+
Our website is in maintenance mode. Please, come back later.
+ {% endif %}
+
+You can also test if a sequence or a mapping is not empty:
+
+.. code-block:: html+twig
+
+ {% if users %}
+
+ {% for user in users %}
+
{{ user.username|e }}
+ {% endfor %}
+
+ {% endif %}
+
+.. note::
+
+ If you want to test if the variable is defined, use ``if users is defined`` instead.
+
+You can also use ``not`` to check for values that evaluate to ``false``:
+
+.. code-block:: html+twig
+
+ {% if not user.subscribed %}
+
You are not subscribed to our mailing list.
+ {% endif %}
+
+For multiple conditions, ``and`` and ``or`` can be used:
+
+.. code-block:: html+twig
+
+ {% if temperature > 18 and temperature < 27 %}
+
It's a nice day for a walk in the park.
+ {% endif %}
+
+For multiple branches ``elseif`` and ``else`` can be used like in PHP. You can
+use more complex ``expressions`` there too:
+
+.. code-block:: twig
+
+ {% if product.stock > 10 %}
+ Available
+ {% elseif product.stock > 0 %}
+ Only {{ product.stock }} left!
+ {% else %}
+ Sold-out!
+ {% endif %}
+
+.. note::
+
+ The rules to determine if an expression is ``true`` or ``false`` are the
+ same as in PHP; here are the edge cases rules:
+
+ ====================== ====================
+ Value Boolean evaluation
+ ====================== ====================
+ empty string false
+ numeric zero false
+ NAN (Not A Number) true
+ INF (Infinity) true
+ whitespace-only string true
+ string "0" or '0' false
+ empty sequence false
+ empty mapping false
+ null false
+ non-empty sequence true
+ non-empty mapping true
+ object true
+ ====================== ====================
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/import.rst b/upload/system/storage/vendor/twig/twig/doc/tags/import.rst
new file mode 100644
index 000000000..f217479fb
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/import.rst
@@ -0,0 +1,6 @@
+``import``
+==========
+
+The ``import`` tag imports :doc:`macro<../tags/macro>` names in a local
+variable. The tag is documented in detail in the documentation for the
+:doc:`macro<../tags/macro>` tag.
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/include.rst b/upload/system/storage/vendor/twig/twig/doc/tags/include.rst
new file mode 100644
index 000000000..93fb0371b
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/include.rst
@@ -0,0 +1,110 @@
+``include``
+===========
+
+The ``include`` statement includes a template and outputs the rendered content
+of that file:
+
+.. code-block:: twig
+
+ {% include 'header.html' %}
+ Body
+ {% include 'footer.html' %}
+
+.. note::
+
+ It is recommended to use the :doc:`include<../functions/include>` function
+ instead as it provides the same features with a bit more flexibility:
+
+ * The ``include`` function is semantically more "correct" (including a
+ template outputs its rendered contents in the current scope; a tag should
+ not display anything);
+
+ * The ``include`` function is more "composable":
+
+ .. code-block:: twig
+
+ {# Store a rendered template in a variable #}
+ {% set content %}
+ {% include 'template.html' %}
+ {% endset %}
+ {# vs #}
+ {% set content = include('template.html') %}
+
+ {# Apply filter on a rendered template #}
+ {% apply upper %}
+ {% include 'template.html' %}
+ {% endapply %}
+ {# vs #}
+ {{ include('template.html')|upper }}
+
+ * The ``include`` function does not impose any specific order for
+ arguments thanks to :ref:`named arguments `.
+
+Included templates have access to the variables of the active context.
+
+If you are using the filesystem loader, the templates are looked for in the
+paths defined by it.
+
+You can add additional variables by passing them after the ``with`` keyword:
+
+.. code-block:: twig
+
+ {# template.html will have access to the variables from the current context and the additional ones provided #}
+ {% include 'template.html' with {'foo': 'bar'} %}
+
+ {% set vars = {'foo': 'bar'} %}
+ {% include 'template.html' with vars %}
+
+You can disable access to the context by appending the ``only`` keyword:
+
+.. code-block:: twig
+
+ {# only the foo variable will be accessible #}
+ {% include 'template.html' with {'foo': 'bar'} only %}
+
+.. code-block:: twig
+
+ {# no variables will be accessible #}
+ {% include 'template.html' only %}
+
+.. tip::
+
+ When including a template created by an end user, you should consider
+ sandboxing it. More information in the :doc:`Twig for Developers<../api>`
+ chapter and in the :doc:`sandbox<../tags/sandbox>` tag documentation.
+
+The template name can be any valid Twig expression:
+
+.. code-block:: twig
+
+ {% include some_var %}
+ {% include ajax ? 'ajax.html' : 'not_ajax.html' %}
+
+And if the expression evaluates to a ``\Twig\Template`` or a
+``\Twig\TemplateWrapper`` instance, Twig will use it directly::
+
+ // {% include template %}
+
+ $template = $twig->load('some_template.twig');
+
+ $twig->display('template.twig', ['template' => $template]);
+
+You can mark an include with ``ignore missing`` in which case Twig will ignore
+the statement if the template to be included does not exist. It has to be
+placed just after the template name. Here some valid examples:
+
+.. code-block:: twig
+
+ {% include 'sidebar.html' ignore missing %}
+ {% include 'sidebar.html' ignore missing with {'foo': 'bar'} %}
+ {% include 'sidebar.html' ignore missing only %}
+
+You can also provide a list of templates that are checked for existence before
+inclusion. The first template that exists will be included:
+
+.. code-block:: twig
+
+ {% include ['page_detailed.html', 'page.html'] %}
+
+If ``ignore missing`` is given, it will fall back to rendering nothing if none
+of the templates exist, otherwise it will throw an exception.
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/index.rst b/upload/system/storage/vendor/twig/twig/doc/tags/index.rst
new file mode 100644
index 000000000..b3c104080
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/index.rst
@@ -0,0 +1,26 @@
+Tags
+====
+
+.. toctree::
+ :maxdepth: 1
+
+ apply
+ autoescape
+ block
+ cache
+ deprecated
+ do
+ embed
+ extends
+ flush
+ for
+ from
+ if
+ import
+ include
+ macro
+ sandbox
+ set
+ use
+ verbatim
+ with
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/macro.rst b/upload/system/storage/vendor/twig/twig/doc/tags/macro.rst
new file mode 100644
index 000000000..d1d0641c0
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/macro.rst
@@ -0,0 +1,148 @@
+``macro``
+=========
+
+Macros are comparable with functions in regular programming languages. They
+are useful to reuse template fragments to not repeat yourself.
+
+Macros are defined in regular templates.
+
+Imagine having a generic helper template that define how to render HTML forms
+via macros (called ``forms.twig``):
+
+.. code-block:: html+twig
+
+ {% macro input(name, value, type = "text", size = 20) %}
+
+ {% endmacro %}
+
+ {% macro textarea(name, value, rows = 10, cols = 40) %}
+
+ {% endmacro %}
+
+Each macro argument can have a default value (here ``text`` is the default value
+for ``type`` if not provided in the call).
+
+Macros differ from native PHP functions in a few ways:
+
+* Arguments of a macro are always optional.
+
+* If extra positional arguments are passed to a macro, they end up in the
+ special ``varargs`` variable as a list of values.
+
+But as with PHP functions, macros don't have access to the current template
+variables.
+
+.. tip::
+
+ You can pass the whole context as an argument by using the special
+ ``_context`` variable.
+
+Importing Macros
+----------------
+
+There are two ways to import macros. You can import the complete template
+containing the macros into a local variable (via the ``import`` tag) or only
+import specific macros from the template (via the ``from`` tag).
+
+To import all macros from a template into a local variable, use the ``import``
+tag:
+
+.. code-block:: twig
+
+ {% import "forms.twig" as forms %}
+
+The above ``import`` call imports the ``forms.twig`` file (which can contain
+only macros, or a template and some macros), and import the macros as items of
+the ``forms`` local variable.
+
+The macros can then be called at will in the *current* template:
+
+.. code-block:: html+twig
+
+
{{ forms.input('username') }}
+
{{ forms.input('password', null, 'password') }}
+
+Alternatively you can import names from the template into the current namespace
+via the ``from`` tag:
+
+.. code-block:: html+twig
+
+ {% from 'forms.twig' import input as input_field, textarea %}
+
+
{{ input_field('password', '', 'password') }}
+
{{ textarea('comment') }}
+
+.. caution::
+
+ As macros imported via ``from`` are called like functions, be careful that
+ they shadow existing functions:
+
+ .. code-block:: twig
+
+ {% from 'forms.twig' import input as include %}
+
+ {# include refers to the macro and not to the built-in "include" function #}
+ {{ include() }}
+
+.. tip::
+
+ When macro usages and definitions are in the same template, you don't need to
+ import the macros as they are automatically available under the special
+ ``_self`` variable:
+
+ .. code-block:: html+twig
+
+
{{ _self.input('password', '', 'password') }}
+
+ {% macro input(name, value, type = "text", size = 20) %}
+
+ {% endmacro %}
+
+Macros Scoping
+--------------
+
+The scoping rules are the same whether you imported macros via ``import`` or
+``from``.
+
+Imported macros are always **local** to the current template. It means that
+macros are available in all blocks and other macros defined in the current
+template, but they are not available in included templates or child templates;
+you need to explicitly re-import macros in each template.
+
+Imported macros are not available in the body of ``embed`` tags, you need
+to explicitly re-import macros inside the tag.
+
+When calling ``import`` or ``from`` from a ``block`` tag, the imported macros
+are only defined in the current block and they shadow macros defined at the
+template level with the same names.
+
+Checking if a Macro is defined
+------------------------------
+
+You can check if a macro is defined via the ``defined`` test:
+
+.. code-block:: twig
+
+ {% import "macros.twig" as macros %}
+
+ {% from "macros.twig" import hello %}
+
+ {% if macros.hello is defined -%}
+ OK
+ {% endif %}
+
+ {% if hello is defined -%}
+ OK
+ {% endif %}
+
+Named Macro End-Tags
+--------------------
+
+Twig allows you to put the name of the macro after the end tag for better
+readability (the name after the ``endmacro`` word must match the macro name):
+
+.. code-block:: twig
+
+ {% macro input() %}
+ ...
+ {% endmacro input %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/sandbox.rst b/upload/system/storage/vendor/twig/twig/doc/tags/sandbox.rst
new file mode 100644
index 000000000..b331fdb8e
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/sandbox.rst
@@ -0,0 +1,30 @@
+``sandbox``
+===========
+
+The ``sandbox`` tag can be used to enable the sandboxing mode for an included
+template, when sandboxing is not enabled globally for the Twig environment:
+
+.. code-block:: twig
+
+ {% sandbox %}
+ {% include 'user.html' %}
+ {% endsandbox %}
+
+.. warning::
+
+ The ``sandbox`` tag is only available when the sandbox extension is
+ enabled (see the :doc:`Twig for Developers<../api>` chapter).
+
+.. note::
+
+ The ``sandbox`` tag can only be used to sandbox an include tag and it
+ cannot be used to sandbox a section of a template. The following example
+ won't work:
+
+ .. code-block:: twig
+
+ {% sandbox %}
+ {% for i in 1..2 %}
+ {{ i }}
+ {% endfor %}
+ {% endsandbox %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/set.rst b/upload/system/storage/vendor/twig/twig/doc/tags/set.rst
new file mode 100644
index 000000000..7a3a784f5
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/set.rst
@@ -0,0 +1,78 @@
+``set``
+=======
+
+Inside code blocks you can also assign values to variables. Assignments use
+the ``set`` tag and can have multiple targets.
+
+Here is how you can assign the ``bar`` value to the ``foo`` variable:
+
+.. code-block:: twig
+
+ {% set foo = 'bar' %}
+
+After the ``set`` call, the ``foo`` variable is available in the template like
+any other ones:
+
+.. code-block:: twig
+
+ {# displays bar #}
+ {{ foo }}
+
+The assigned value can be any valid :ref:`Twig expression
+`:
+
+.. code-block:: twig
+
+ {% set foo = [1, 2] %}
+ {% set foo = {'foo': 'bar'} %}
+ {% set foo = 'foo' ~ 'bar' %}
+
+Several variables can be assigned in one block:
+
+.. code-block:: twig
+
+ {% set foo, bar = 'foo', 'bar' %}
+
+ {# is equivalent to #}
+
+ {% set foo = 'foo' %}
+ {% set bar = 'bar' %}
+
+The ``set`` tag can also be used to 'capture' chunks of text:
+
+.. code-block:: html+twig
+
+ {% set foo %}
+
+ ...
+
+ {% endset %}
+
+.. caution::
+
+ If you enable automatic output escaping, Twig will only consider the
+ content to be safe when capturing chunks of text.
+
+.. note::
+
+ Note that loops are scoped in Twig; therefore a variable declared inside a
+ ``for`` loop is not accessible outside the loop itself:
+
+ .. code-block:: twig
+
+ {% for item in list %}
+ {% set foo = item %}
+ {% endfor %}
+
+ {# foo is NOT available #}
+
+ If you want to access the variable, just declare it before the loop:
+
+ .. code-block:: twig
+
+ {% set foo = "" %}
+ {% for item in list %}
+ {% set foo = item %}
+ {% endfor %}
+
+ {# foo is available #}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/use.rst b/upload/system/storage/vendor/twig/twig/doc/tags/use.rst
new file mode 100644
index 000000000..2aca6a01f
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/use.rst
@@ -0,0 +1,117 @@
+``use``
+=======
+
+.. note::
+
+ Horizontal reuse is an advanced Twig feature that is hardly ever needed in
+ regular templates. It is mainly used by projects that need to make
+ template blocks reusable without using inheritance.
+
+Template inheritance is one of the most powerful features of Twig but it is
+limited to single inheritance; a template can only extend one other template.
+This limitation makes template inheritance simple to understand and easy to
+debug:
+
+.. code-block:: twig
+
+ {% extends "base.html" %}
+
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+Horizontal reuse is a way to achieve the same goal as multiple inheritance,
+but without the associated complexity:
+
+.. code-block:: twig
+
+ {% extends "base.html" %}
+
+ {% use "blocks.html" %}
+
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+The ``use`` statement tells Twig to import the blocks defined in
+``blocks.html`` into the current template (it's like macros, but for blocks):
+
+.. code-block:: twig
+
+ {# blocks.html #}
+
+ {% block sidebar %}{% endblock %}
+
+In this example, the ``use`` statement imports the ``sidebar`` block into the
+main template. The code is mostly equivalent to the following one (the
+imported blocks are not outputted automatically):
+
+.. code-block:: twig
+
+ {% extends "base.html" %}
+
+ {% block sidebar %}{% endblock %}
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+.. note::
+
+ The ``use`` tag only imports a template if it does not extend another
+ template, if it does not define macros, and if the body is empty. But it
+ can *use* other templates.
+
+.. note::
+
+ Because ``use`` statements are resolved independently of the context
+ passed to the template, the template reference cannot be an expression.
+
+The main template can also override any imported block. If the template
+already defines the ``sidebar`` block, then the one defined in ``blocks.html``
+is ignored. To avoid name conflicts, you can rename imported blocks:
+
+.. code-block:: twig
+
+ {% extends "base.html" %}
+
+ {% use "blocks.html" with sidebar as base_sidebar, title as base_title %}
+
+ {% block sidebar %}{% endblock %}
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+The ``parent()`` function automatically determines the correct inheritance
+tree, so it can be used when overriding a block defined in an imported
+template:
+
+.. code-block:: twig
+
+ {% extends "base.html" %}
+
+ {% use "blocks.html" %}
+
+ {% block sidebar %}
+ {{ parent() }}
+ {% endblock %}
+
+ {% block title %}{% endblock %}
+ {% block content %}{% endblock %}
+
+In this example, ``parent()`` will correctly call the ``sidebar`` block from
+the ``blocks.html`` template.
+
+.. tip::
+
+ Renaming allows you to simulate inheritance by calling the "parent" block:
+
+ .. code-block:: twig
+
+ {% extends "base.html" %}
+
+ {% use "blocks.html" with sidebar as parent_sidebar %}
+
+ {% block sidebar %}
+ {{ block('parent_sidebar') }}
+ {% endblock %}
+
+.. note::
+
+ You can use as many ``use`` statements as you want in any given template.
+ If two imported templates define the same block, the latest one wins.
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/verbatim.rst b/upload/system/storage/vendor/twig/twig/doc/tags/verbatim.rst
new file mode 100644
index 000000000..3d7115a68
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/verbatim.rst
@@ -0,0 +1,16 @@
+``verbatim``
+============
+
+The ``verbatim`` tag marks sections as being raw text that should not be
+parsed. For example to put Twig syntax as example into a template you can use
+this snippet:
+
+.. code-block:: html+twig
+
+ {% verbatim %}
+
+ {% for item in seq %}
+
{{ item }}
+ {% endfor %}
+
+ {% endverbatim %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tags/with.rst b/upload/system/storage/vendor/twig/twig/doc/tags/with.rst
new file mode 100644
index 000000000..268bb373d
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tags/with.rst
@@ -0,0 +1,41 @@
+``with``
+========
+
+Use the ``with`` tag to create a new inner scope. Variables set within this
+scope are not visible outside of the scope:
+
+.. code-block:: twig
+
+ {% with %}
+ {% set foo = 42 %}
+ {{ foo }} {# foo is 42 here #}
+ {% endwith %}
+ foo is not visible here any longer
+
+Instead of defining variables at the beginning of the scope, you can pass a
+mapping of variables you want to define in the ``with`` tag; the previous
+example is equivalent to the following one:
+
+.. code-block:: twig
+
+ {% with {foo: 42} %}
+ {{ foo }} {# foo is 42 here #}
+ {% endwith %}
+ foo is not visible here any longer
+
+ {# it works with any expression that resolves to a mapping #}
+ {% set vars = {foo: 42} %}
+ {% with vars %}
+ ...
+ {% endwith %}
+
+By default, the inner scope has access to the outer scope context; you can
+disable this behavior by appending the ``only`` keyword:
+
+.. code-block:: twig
+
+ {% set bar = 'bar' %}
+ {% with {foo: 42} only %}
+ {# only foo is defined #}
+ {# bar is not defined #}
+ {% endwith %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/templates.rst b/upload/system/storage/vendor/twig/twig/doc/templates.rst
new file mode 100644
index 000000000..3cd8f9b90
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/templates.rst
@@ -0,0 +1,965 @@
+Twig for Template Designers
+===========================
+
+This document describes the syntax and semantics of the template engine and
+will be most useful as reference to those creating Twig templates.
+
+Synopsis
+--------
+
+A template is a regular text file. It can generate any text-based format (HTML,
+XML, CSV, LaTeX, etc.). It doesn't have a specific extension, ``.html`` or
+``.xml`` are just fine.
+
+A template contains **variables** or **expressions**, which get replaced with
+values when the template is evaluated, and **tags**, which control the
+template's logic.
+
+Below is a minimal template that illustrates a few basics. We will cover further
+details later on:
+
+.. code-block:: html+twig
+
+
+
+
+ My Webpage
+
+
+
+ {{ a_variable }}
+
+
+
+There are two kinds of delimiters: ``{% ... %}`` and ``{{ ... }}``. The first
+one is used to execute statements such as for-loops, the latter outputs the
+result of an expression.
+
+IDEs Integration
+----------------
+
+Many IDEs support syntax highlighting and auto-completion for Twig:
+
+* *Textmate* via the `Twig bundle`_
+* *Vim* via the `vim-twig plugin`_
+* *Netbeans* (native as of 7.2)
+* *PhpStorm* (native as of 2.1)
+* *Eclipse* via the `Twig plugin`_
+* *Sublime Text* via the `Twig bundle`_
+* *GtkSourceView* via the `Twig language definition`_ (used by gedit and other projects)
+* *Coda* and *SubEthaEdit* via the `Twig syntax mode`_
+* *Coda 2* via the `other Twig syntax mode`_
+* *Komodo* and *Komodo Edit* via the Twig highlight/syntax check mode
+* *Notepad++* via the `Notepad++ Twig Highlighter`_
+* *Emacs* via `web-mode.el`_
+* *Atom* via the `PHP-twig for atom`_
+* *Visual Studio Code* via the `Twig pack`_, `Modern Twig`_ or `Twiggy`_
+
+You might also be interested in:
+
+* `TwigFiddle`_: an online service that allows you to execute Twig templates
+ from a browser; it supports all versions of Twig
+
+* `Twig Language Server`_: provides some language features like syntax
+ highlighting, diagnostics, auto complete, ...
+
+Variables
+---------
+
+The application passes variables to the templates for manipulation in the
+template. Variables may have attributes or elements you can access, too. The
+visual representation of a variable depends heavily on the application providing
+it.
+
+Use a dot (``.``) to access attributes of a variable (methods or properties of a
+PHP object, or items of a PHP array):
+
+.. code-block:: twig
+
+ {{ foo.bar }}
+
+.. note::
+
+ It's important to know that the curly braces are *not* part of the
+ variable but the print statement. When accessing variables inside tags,
+ don't put the braces around them.
+
+If a variable or attribute does not exist, the behavior depends on the
+``strict_variables`` option value (see :ref:`environment options
+`):
+
+* When ``false``, it returns ``null``;
+* When ``true``, it throws an exception.
+
+.. sidebar:: Implementation
+
+ For convenience's sake ``foo.bar`` does the following things on the PHP
+ layer:
+
+ * check if ``foo`` is a sequence or a mapping and ``bar`` a valid element;
+ * if not, and if ``foo`` is an object, check that ``bar`` is a valid property;
+ * if not, and if ``foo`` is an object, check that ``bar`` is a valid method
+ (even if ``bar`` is the constructor - use ``__construct()`` instead);
+ * if not, and if ``foo`` is an object, check that ``getBar`` is a valid method;
+ * if not, and if ``foo`` is an object, check that ``isBar`` is a valid method;
+ * if not, and if ``foo`` is an object, check that ``hasBar`` is a valid method;
+ * if not, and if ``strict_variables`` is ``false``, return ``null``;
+ * if not, throw an exception.
+
+ Twig also supports a specific syntax for accessing items on PHP arrays,
+ ``foo['bar']``:
+
+ * check if ``foo`` is a sequence or a mapping and ``bar`` a valid element;
+ * if not, and if ``strict_variables`` is ``false``, return ``null``;
+ * if not, throw an exception.
+
+.. note::
+
+ If you want to access a dynamic attribute of a variable, use the
+ :doc:`attribute` function instead.
+
+ The ``attribute`` function is also useful when the attribute contains
+ special characters (like ``-`` that would be interpreted as the minus
+ operator):
+
+ .. code-block:: twig
+
+ {# equivalent to the non-working foo.data-foo #}
+ {{ attribute(foo, 'data-foo') }}
+
+Global Variables
+~~~~~~~~~~~~~~~~
+
+The following variables are always available in templates:
+
+* ``_self``: references the current template name;
+* ``_context``: references the current context;
+* ``_charset``: references the current charset.
+
+Setting Variables
+~~~~~~~~~~~~~~~~~
+
+You can assign values to variables inside code blocks. Assignments use the
+:doc:`set` tag:
+
+.. code-block:: twig
+
+ {% set foo = 'foo' %}
+ {% set foo = [1, 2] %}
+ {% set foo = {'foo': 'bar'} %}
+
+Filters
+-------
+
+Variables can be modified by **filters**. Filters are separated from the
+variable by a pipe symbol (``|``). Multiple filters can be chained. The output
+of one filter is applied to the next.
+
+The following example removes all HTML tags from the ``name`` and title-cases
+it:
+
+.. code-block:: twig
+
+ {{ name|striptags|title }}
+
+Filters that accept arguments have parentheses around the arguments. This
+example joins the elements of a list by commas:
+
+.. code-block:: twig
+
+ {{ list|join(', ') }}
+
+To apply a filter on a section of code, wrap it with the
+:doc:`apply` tag:
+
+.. code-block:: twig
+
+ {% apply upper %}
+ This text becomes uppercase
+ {% endapply %}
+
+Go to the :doc:`filters` page to learn more about built-in
+filters.
+
+Functions
+---------
+
+Functions can be called to generate content. Functions are called by their
+name followed by parentheses (``()``) and may have arguments.
+
+For instance, the ``range`` function returns a list containing an arithmetic
+progression of integers:
+
+.. code-block:: twig
+
+ {% for i in range(0, 3) %}
+ {{ i }},
+ {% endfor %}
+
+Go to the :doc:`functions` page to learn more about the
+built-in functions.
+
+.. _named-arguments:
+
+Named Arguments
+---------------
+
+Named arguments are supported in functions, filters, and tests.
+
+.. versionadded:: 3.12
+
+ Twig supports both ``=`` and ``:`` as separators between argument names and
+ values, but support for ``:`` was introduced in Twig 3.12.
+
+.. code-block:: twig
+
+ {% for i in range(low: 1, high: 10, step: 2) %}
+ {{ i }},
+ {% endfor %}
+
+Using named arguments makes your templates more explicit about the meaning of
+the values you pass as arguments:
+
+.. code-block:: twig
+
+ {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
+
+ {# versus #}
+
+ {{ data|convert_encoding(from: 'iso-2022-jp', to: 'UTF-8') }}
+
+Named arguments also allow you to skip some arguments for which you don't want
+to change the default value:
+
+.. code-block:: twig
+
+ {# the first argument is the date format, which defaults to the global date format if null is passed #}
+ {{ "now"|date(null, "Europe/Paris") }}
+
+ {# or skip the format value by using a named argument for the time zone #}
+ {{ "now"|date(timezone: "Europe/Paris") }}
+
+You can also use both positional and named arguments in one call, in which
+case positional arguments must always come before named arguments:
+
+.. code-block:: twig
+
+ {{ "now"|date('d/m/Y H:i', timezone: "Europe/Paris") }}
+
+.. tip::
+
+ Each function, filter, and test documentation page has a section where the
+ names of all supported arguments are listed.
+
+Control Structure
+-----------------
+
+A control structure refers to all those things that control the flow of a
+program - conditionals (i.e. ``if``/``elseif``/``else``), ``for``-loops, as
+well as things like blocks. Control structures appear inside ``{% ... %}``
+blocks.
+
+For example, to display a list of users provided in a variable called
+``users``, use the :doc:`for` tag:
+
+.. code-block:: html+twig
+
+
Members
+
+ {% for user in users %}
+
{{ user.username|e }}
+ {% endfor %}
+
+
+The :doc:`if` tag can be used to test an expression:
+
+.. code-block:: html+twig
+
+ {% if users|length > 0 %}
+
+ {% for user in users %}
+
{{ user.username|e }}
+ {% endfor %}
+
+ {% endif %}
+
+Go to the :doc:`tags` page to learn more about the built-in tags.
+
+Comments
+--------
+
+To comment-out part of a line in a template, use the comment syntax ``{# ...
+#}``. This is useful for debugging or to add information for other template
+designers or yourself:
+
+.. code-block:: twig
+
+ {# note: disabled template because we no longer use this
+ {% for user in users %}
+ ...
+ {% endfor %}
+ #}
+
+Including other Templates
+-------------------------
+
+The :doc:`include` function is useful to include a template
+and return the rendered content of that template into the current one:
+
+.. code-block:: twig
+
+ {{ include('sidebar.html') }}
+
+By default, included templates have access to the same context as the template
+which includes them. This means that any variable defined in the main template
+will be available in the included template too:
+
+.. code-block:: twig
+
+ {% for box in boxes %}
+ {{ include('render_box.html') }}
+ {% endfor %}
+
+The included template ``render_box.html`` is able to access the ``box`` variable.
+
+The name of the template depends on the template loader. For instance, the
+``\Twig\Loader\FilesystemLoader`` allows you to access other templates by giving the
+filename. You can access templates in subdirectories with a slash:
+
+.. code-block:: twig
+
+ {{ include('sections/articles/sidebar.html') }}
+
+This behavior depends on the application embedding Twig.
+
+Template Inheritance
+--------------------
+
+The most powerful part of Twig is template inheritance. Template inheritance
+allows you to build a base "skeleton" template that contains all the common
+elements of your site and defines **blocks** that child templates can
+override.
+
+It's easier to understand the concept by starting with an example.
+
+Let's define a base template, ``base.html``, which defines an HTML skeleton
+document that might be used for a two-column page:
+
+.. code-block:: html+twig
+
+
+
+
+ {% block head %}
+
+ {% block title %}{% endblock %} - My Webpage
+ {% endblock %}
+
+
+
{% block content %}{% endblock %}
+
+
+
+
+In this example, the :doc:`block` tags define four blocks that
+child templates can fill in. All the ``block`` tag does is to tell the
+template engine that a child template may override those portions of the
+template.
+
+A child template might look like this:
+
+.. code-block:: html+twig
+
+ {% extends "base.html" %}
+
+ {% block title %}Index{% endblock %}
+ {% block head %}
+ {{ parent() }}
+
+ {% endblock %}
+ {% block content %}
+
Index
+
+ Welcome to my awesome homepage.
+
+ {% endblock %}
+
+The :doc:`extends` tag is the key here. It tells the template
+engine that this template "extends" another template. When the template system
+evaluates this template, first it locates the parent. The extends tag should
+be the first tag in the template.
+
+Note that since the child template doesn't define the ``footer`` block, the
+value from the parent template is used instead.
+
+It's possible to render the contents of the parent block by using the
+:doc:`parent` function. This gives back the results of the
+parent block:
+
+.. code-block:: html+twig
+
+ {% block sidebar %}
+
Table Of Contents
+ ...
+ {{ parent() }}
+ {% endblock %}
+
+.. tip::
+
+ The documentation page for the :doc:`extends` tag describes
+ more advanced features like block nesting, scope, dynamic inheritance, and
+ conditional inheritance.
+
+.. note::
+
+ Twig also supports multiple inheritance via "horizontal reuse" with the help
+ of the :doc:`use` tag.
+
+HTML Escaping
+-------------
+
+When generating HTML from templates, there's always a risk that a variable
+will include characters that affect the resulting HTML. There are two
+approaches: manually escaping each variable or automatically escaping
+everything by default.
+
+Twig supports both, automatic escaping is enabled by default.
+
+The automatic escaping strategy can be configured via the
+:ref:`autoescape` option and defaults to ``html``.
+
+Working with Manual Escaping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If manual escaping is enabled, it is **your** responsibility to escape variables
+if needed. What to escape? Any variable that comes from an untrusted source.
+
+Escaping works by using the :doc:`escape` or ``e`` filter:
+
+.. code-block:: twig
+
+ {{ user.username|e }}
+
+By default, the ``escape`` filter uses the ``html`` strategy, but depending on
+the escaping context, you might want to explicitly use another strategy:
+
+.. code-block:: twig
+
+ {{ user.username|e('js') }}
+ {{ user.username|e('css') }}
+ {{ user.username|e('url') }}
+ {{ user.username|e('html_attr') }}
+
+Working with Automatic Escaping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Whether automatic escaping is enabled or not, you can mark a section of a
+template to be escaped or not by using the :doc:`autoescape`
+tag:
+
+.. code-block:: twig
+
+ {% autoescape %}
+ Everything will be automatically escaped in this block (using the HTML strategy)
+ {% endautoescape %}
+
+By default, auto-escaping uses the ``html`` escaping strategy. If you output
+variables in other contexts, you need to explicitly escape them with the
+appropriate escaping strategy:
+
+.. code-block:: twig
+
+ {% autoescape 'js' %}
+ Everything will be automatically escaped in this block (using the JS strategy)
+ {% endautoescape %}
+
+Escaping
+--------
+
+It is sometimes desirable or even necessary to have Twig ignore parts it would
+otherwise handle as variables or blocks. For example if the default syntax is
+used and you want to use ``{{`` as raw string in the template and not start a
+variable you have to use a trick.
+
+The easiest way is to output the variable delimiter (``{{``) by using a variable
+expression:
+
+.. code-block:: twig
+
+ {{ '{{' }}
+
+For bigger sections it makes sense to mark a block
+:doc:`verbatim`.
+
+Macros
+------
+
+Macros are comparable with functions in regular programming languages. They are
+useful to reuse HTML fragments to not repeat yourself. They are described in the
+:doc:`macro` tag documentation.
+
+.. _twig-expressions:
+
+Expressions
+-----------
+
+Twig allows expressions everywhere.
+
+Literals
+~~~~~~~~
+
+The simplest form of expressions are literals. Literals are representations
+for PHP types such as strings, numbers, and arrays. The following literals
+exist:
+
+* ``"Hello World"``: Everything between two double or single quotes is a
+ string. They are useful whenever you need a string in the template (for
+ example as arguments to function calls, filters or just to extend or include
+ a template).
+
+ Note that certain characters require escaping:
+ * ``\f``: Form feed
+ * ``\n``: New line
+ * ``\r``: Carriage return
+ * ``\t``: Horizontal tab
+ * ``\v``: Vertical tab
+ * ``\x``: Hexadecimal escape sequence
+ * ``\0`` to ``\377``: Octal escape sequences representing characters
+ * ``\``: Backslash
+
+ When using single-quoted strings, the single quote character (``'``) needs to be escaped with a backslash (``\'``).
+ When using double-quoted strings, the double quote character (``"``) needs to be escaped with a backslash (``\"``).
+
+ For example, a single quoted string can contain a delimiter if it is preceded by a
+ backslash (``\``) -- like in ``'It\'s good'``. If the string contains a
+ backslash (e.g. ``'c:\Program Files'``) escape it by doubling it
+ (e.g. ``'c:\\Program Files'``).
+
+* ``42`` / ``42.23``: Integers and floating point numbers are created by
+ writing the number down. If a dot is present the number is a float,
+ otherwise an integer.
+
+* ``["foo", "bar"]``: Sequences are defined by a sequence of expressions
+ separated by a comma (``,``) and wrapped with squared brackets (``[]``).
+
+* ``{"foo": "bar"}``: Mappings are defined by a list of keys and values
+ separated by a comma (``,``) and wrapped with curly braces (``{}``):
+
+ .. code-block:: twig
+
+ {# keys as string #}
+ {'foo': 'foo', 'bar': 'bar'}
+
+ {# keys as names (equivalent to the previous mapping) #}
+ {foo: 'foo', bar: 'bar'}
+
+ {# keys as integer #}
+ {2: 'foo', 4: 'bar'}
+
+ {# keys can be omitted if it is the same as the variable name #}
+ {foo}
+ {# is equivalent to the following #}
+ {'foo': foo}
+
+ {# keys as expressions (the expression must be enclosed into parentheses) #}
+ {% set foo = 'foo' %}
+ {(foo): 'foo', (1 + 1): 'bar', (foo ~ 'b'): 'baz'}
+
+* ``true`` / ``false``: ``true`` represents the true value, ``false``
+ represents the false value.
+
+* ``null``: ``null`` represents no specific value. This is the value returned
+ when a variable does not exist. ``none`` is an alias for ``null``.
+
+Sequences and mappings can be nested:
+
+.. code-block:: twig
+
+ {% set foo = [1, {"foo": "bar"}] %}
+
+.. tip::
+
+ Using double-quoted or single-quoted strings has no impact on performance
+ but :ref:`string interpolation ` is only
+ supported in double-quoted strings.
+
+.. _templates-string-interpolation:
+
+String Interpolation
+~~~~~~~~~~~~~~~~~~~~
+
+String interpolation (``#{expression}``) allows any valid expression to appear
+within a *double-quoted string*. The result of evaluating that expression is
+inserted into the string:
+
+.. code-block:: twig
+
+ {{ "foo #{bar} baz" }}
+ {{ "foo #{1 + 2} baz" }}
+
+.. tip::
+
+ String interpolations can be ignored by escaping them with a backslash
+ (``\``):
+
+ .. code-block:: twig
+
+ {# outputs foo #{1 + 2} baz #}
+ {{ "foo \#{1 + 2} baz" }}
+
+Math
+~~~~
+
+Twig allows you to do math in templates; the following operators are supported:
+
+* ``+``: Adds two numbers together (the operands are casted to numbers). ``{{
+ 1 + 1 }}`` is ``2``.
+
+* ``-``: Subtracts the second number from the first one. ``{{ 3 - 2 }}`` is
+ ``1``.
+
+* ``/``: Divides two numbers. The returned value will be a floating point
+ number. ``{{ 1 / 2 }}`` is ``{{ 0.5 }}``.
+
+* ``%``: Calculates the remainder of an integer division. ``{{ 11 % 7 }}`` is
+ ``4``.
+
+* ``//``: Divides two numbers and returns the floored integer result. ``{{ 20
+ // 7 }}`` is ``2``, ``{{ -20 // 7 }}`` is ``-3`` (this is just syntactic
+ sugar for the :doc:`round` filter).
+
+* ``*``: Multiplies the left operand with the right one. ``{{ 2 * 2 }}`` would
+ return ``4``.
+
+* ``**``: Raises the left operand to the power of the right operand. ``{{ 2 **
+ 3 }}`` would return ``8``.
+
+.. _template_logic:
+
+Logic
+~~~~~
+
+You can combine multiple expressions with the following operators:
+
+* ``and``: Returns true if the left and the right operands are both true.
+
+* ``or``: Returns true if the left or the right operand is true.
+
+* ``not``: Negates a statement.
+
+* ``(expr)``: Groups an expression.
+
+.. note::
+
+ Twig also supports bitwise operators (``b-and``, ``b-xor``, and ``b-or``).
+
+.. note::
+
+ Operators are case sensitive.
+
+Comparisons
+~~~~~~~~~~~
+
+The following comparison operators are supported in any expression: ``==``,
+``!=``, ``<``, ``>``, ``>=``, and ``<=``.
+
+Check if a string ``starts with`` or ``ends with`` another string:
+
+.. code-block:: twig
+
+ {% if 'Fabien' starts with 'F' %}
+ {% endif %}
+
+ {% if 'Fabien' ends with 'n' %}
+ {% endif %}
+
+Check that a string contains another string via the containment operator (see
+next section).
+
+.. note::
+
+ For complex string comparisons, the ``matches`` operator allows you to use
+ `regular expressions`_:
+
+ .. code-block:: twig
+
+ {% if phone matches '/^[\\d\\.]+$/' %}
+ {% endif %}
+
+Check that a sequence or a mapping ``has every`` or ``has some`` of its
+elements return ``true`` using an arrow function. The arrow function receives
+the value of the sequence or mapping:
+
+.. code-block:: twig
+
+ {% set sizes = [34, 36, 38, 40, 42] %}
+
+ {% set hasOnlyOver38 = sizes has every v => v > 38 %}
+ {# hasOnlyOver38 is false #}
+
+ {% set hasOver38 = sizes has some v => v > 38 %}
+ {# hasOver38 is true #}
+
+Containment Operator
+~~~~~~~~~~~~~~~~~~~~
+
+The ``in`` operator performs containment test. It returns ``true`` if the left
+operand is contained in the right:
+
+.. code-block:: twig
+
+ {# returns true #}
+
+ {{ 1 in [1, 2, 3] }}
+
+ {{ 'cd' in 'abcde' }}
+
+.. tip::
+
+ You can use this filter to perform a containment test on strings,
+ sequences, mappings, or objects implementing the ``Traversable`` interface.
+
+To perform a negative test, use the ``not in`` operator:
+
+.. code-block:: twig
+
+ {% if 1 not in [1, 2, 3] %}
+
+ {# is equivalent to #}
+ {% if not (1 in [1, 2, 3]) %}
+
+Test Operator
+~~~~~~~~~~~~~
+
+The ``is`` operator performs tests. Tests can be used to test a variable against
+a common expression. The right operand is name of the test:
+
+.. code-block:: twig
+
+ {# find out if a variable is odd #}
+
+ {{ name is odd }}
+
+Tests can accept arguments too:
+
+.. code-block:: twig
+
+ {% if post.status is constant('Post::PUBLISHED') %}
+
+Tests can be negated by using the ``is not`` operator:
+
+.. code-block:: twig
+
+ {% if post.status is not constant('Post::PUBLISHED') %}
+
+ {# is equivalent to #}
+ {% if not (post.status is constant('Post::PUBLISHED')) %}
+
+Go to the :doc:`tests` page to learn more about the built-in
+tests.
+
+Other Operators
+~~~~~~~~~~~~~~~
+
+The following operators don't fit into any of the other categories:
+
+* ``|``: Applies a filter.
+
+* ``..``: Creates a sequence based on the operand before and after the operator
+ (this is syntactic sugar for the :doc:`range` function):
+
+ .. code-block:: twig
+
+ {% for i in 1..5 %}{{ i }}{% endfor %}
+
+ {# is equivalent to #}
+ {% for i in range(1, 5) %}{{ i }}{% endfor %}
+
+ Note that you must use parentheses when combining it with the filter operator
+ due to the :ref:`operator precedence rules `:
+
+ .. code-block:: twig
+
+ (1..5)|join(', ')
+
+* ``~``: Converts all operands into strings and concatenates them. ``{{ "Hello
+ " ~ name ~ "!" }}`` would return (assuming ``name`` is ``'John'``) ``Hello
+ John!``.
+
+* ``.``, ``[]``: Gets an attribute of a variable.
+
+* ``?:``: The ternary operator:
+
+ .. code-block:: twig
+
+ {{ foo ? 'yes' : 'no' }}
+ {{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
+ {{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
+
+* ``??``: The null-coalescing operator:
+
+ .. code-block:: twig
+
+ {# returns the value of foo if it is defined and not null, 'no' otherwise #}
+ {{ foo ?? 'no' }}
+
+* ``...``: The spread operator can be used to expand sequences or mappings (it
+ cannot be used to expand the arguments of a function call):
+
+ .. code-block:: twig
+
+ {% set numbers = [1, 2, ...moreNumbers] %}
+ {% set ratings = {'foo': 10, 'bar': 5, ...moreRatings} %}
+
+Operators
+~~~~~~~~~
+
+Twig uses operators to perform various operations within templates.
+Understanding the precedence of these operators is crucial for writing correct
+and efficient Twig templates.
+
+The operator precedence rules are as follows, with the lowest-precedence
+operators listed first:
+
+============================= =================================== =====================================================
+Operator Score of precedence Description
+============================= =================================== =====================================================
+``?:`` 0 Ternary operator, conditional statement
+``or`` 10 Logical OR operation between two boolean expressions
+``and`` 15 Logical AND operation between two boolean expressions
+``b-or`` 16 Bitwise OR operation on integers
+``b-xor`` 17 Bitwise XOR operation on integers
+``b-and`` 18 Bitwise AND operation on integers
+``==``, ``!=``, ``<=>``, 20 Comparison operators
+``<``, ``>``, ``>=``,
+``<=``, ``not in``, ``in``,
+``matches``, ``starts with``,
+``ends with``, ``has some``,
+``has every``
+``..`` 25 Range of values
+``+``, ``-`` 30 Addition and subtraction on numbers
+``~`` 40 String concatenation
+``not`` 50 Negates a statement
+``*``, ``/``, ``//``, ``%`` 60 Arithmetic operations on numbers
+``is``, ``is not`` 100 Tests
+``**`` 200 Raises a number to the power of another
+``??`` 300 Default value when a variable is null
+``+``, ``-`` 500 Unary operations on numbers
+``|``,``[]``,``.`` - Filters, sequence, mapping, and attribute access
+============================= =================================== =====================================================
+
+Without using any parentheses, the operator precedence rules are used to
+determine how to convert the code to PHP:
+
+.. code-block:: twig
+
+ {{ 6 b-and 2 or 6 b-and 16 }}
+
+ {# it is converted to the following PHP code: (6 & 2) || (6 & 16) #}
+
+Change the default precedence by explicitly grouping expressions with parentheses:
+
+.. code-block:: twig
+
+ {% set greeting = 'Hello ' %}
+ {% set name = 'Fabien' %}
+
+ {{ greeting ~ name|lower }} {# Hello fabien #}
+
+ {# use parenthesis to change precedence #}
+ {{ (greeting ~ name)|lower }} {# hello fabien #}
+
+.. _templates-whitespace-control:
+
+Whitespace Control
+------------------
+
+The first newline after a template tag is removed automatically (like in PHP).
+Whitespace is not further modified by the template engine, so each whitespace
+(spaces, tabs, newlines etc.) is returned unchanged.
+
+You can also control whitespace on a per tag level. By using the whitespace
+control modifiers on your tags, you can trim leading and or trailing whitespace.
+
+Twig supports two modifiers:
+
+* *Whitespace trimming* via the ``-`` modifier: Removes all whitespace
+ (including newlines);
+
+* *Line whitespace trimming* via the ``~`` modifier: Removes all whitespace
+ (excluding newlines). Using this modifier on the right disables the default
+ removal of the first newline inherited from PHP.
+
+The modifiers can be used on either side of the tags like in ``{%-`` or ``-%}``
+and they consume all whitespace for that side of the tag. It is possible to use
+the modifiers on one side of a tag or on both sides:
+
+.. code-block:: html+twig
+
+ {% set value = 'no spaces' %}
+ {#- No leading/trailing whitespace -#}
+ {%- if true -%}
+ {{- value -}}
+ {%- endif -%}
+ {# output 'no spaces' #}
+
+
+ {{ value }}
+ {# outputs '
\n no spaces
' #}
+
+
+ {{- value }}
+ {# outputs '
no spaces
' #}
+
+
+ {{~ value }}
+ {# outputs '
\nno spaces
' #}
+
+.. tip::
+
+ In addition to the whitespace modifiers, Twig also has a ``spaceless`` filter
+ that removes whitespace **between HTML tags**:
+
+ .. code-block:: html+twig
+
+ {% apply spaceless %}
+
+ foo bar
+
+ {% endapply %}
+
+ {# output will be
foo bar
#}
+
+Extensions
+----------
+
+Twig can be extended. If you want to create your own extensions, read the
+:ref:`Creating an Extension ` chapter.
+
+.. _`Twig bundle`: https://github.com/uhnomoli/PHP-Twig.tmbundle
+.. _`vim-twig plugin`: https://github.com/lumiliet/vim-twig
+.. _`Twig plugin`: https://github.com/pulse00/Twig-Eclipse-Plugin
+.. _`Twig language definition`: https://github.com/gabrielcorpse/gedit-twig-template-language
+.. _`Twig syntax mode`: https://github.com/bobthecow/Twig-HTML.mode
+.. _`other Twig syntax mode`: https://github.com/muxx/Twig-HTML.mode
+.. _`Notepad++ Twig Highlighter`: https://github.com/Banane9/notepadplusplus-twig
+.. _`web-mode.el`: https://web-mode.org/
+.. _`regular expressions`: https://www.php.net/manual/en/pcre.pattern.php
+.. _`PHP-twig for atom`: https://github.com/reesef/php-twig
+.. _`TwigFiddle`: https://twigfiddle.com/
+.. _`Twig pack`: https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-twig-pack
+.. _`Modern Twig`: https://marketplace.visualstudio.com/items?itemName=Stanislav.vscode-twig
+.. _`Twig Language Server`: https://github.com/kaermorchen/twig-language-server/tree/master/packages/language-server
+.. _`Twiggy`: https://marketplace.visualstudio.com/items?itemName=moetelo.twiggy
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/constant.rst b/upload/system/storage/vendor/twig/twig/doc/tests/constant.rst
new file mode 100644
index 000000000..448c238bc
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/constant.rst
@@ -0,0 +1,19 @@
+``constant``
+============
+
+``constant`` checks if a variable has the exact same value as a constant. You
+can use either global constants or class constants:
+
+.. code-block:: twig
+
+ {% if post.status is constant('Post::PUBLISHED') %}
+ the status attribute is exactly the same as Post::PUBLISHED
+ {% endif %}
+
+You can test constants from object instances as well:
+
+.. code-block:: twig
+
+ {% if post.status is constant('PUBLISHED', post) %}
+ the status attribute is exactly the same as Post::PUBLISHED
+ {% endif %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/defined.rst b/upload/system/storage/vendor/twig/twig/doc/tests/defined.rst
new file mode 100644
index 000000000..234a28988
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/defined.rst
@@ -0,0 +1,30 @@
+``defined``
+===========
+
+``defined`` checks if a variable is defined in the current context. This is very
+useful if you use the ``strict_variables`` option:
+
+.. code-block:: twig
+
+ {# defined works with variable names #}
+ {% if foo is defined %}
+ ...
+ {% endif %}
+
+ {# and attributes on variables names #}
+ {% if foo.bar is defined %}
+ ...
+ {% endif %}
+
+ {% if foo['bar'] is defined %}
+ ...
+ {% endif %}
+
+When using the ``defined`` test on an expression that uses variables in some
+method calls, be sure that they are all defined first:
+
+.. code-block:: twig
+
+ {% if var is defined and foo.method(var) is defined %}
+ ...
+ {% endif %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/divisibleby.rst b/upload/system/storage/vendor/twig/twig/doc/tests/divisibleby.rst
new file mode 100644
index 000000000..8032d349a
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/divisibleby.rst
@@ -0,0 +1,10 @@
+``divisible by``
+================
+
+``divisible by`` checks if a variable is divisible by a number:
+
+.. code-block:: twig
+
+ {% if loop.index is divisible by(3) %}
+ ...
+ {% endif %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/empty.rst b/upload/system/storage/vendor/twig/twig/doc/tests/empty.rst
new file mode 100644
index 000000000..3abdb8bbd
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/empty.rst
@@ -0,0 +1,18 @@
+``empty``
+=========
+
+``empty`` checks if a variable is an empty string, an empty sequence, an empty
+mapping, exactly ``false``, or exactly ``null``.
+
+For objects that implement the ``Countable`` interface, ``empty`` will check the
+return value of the ``count()`` method.
+
+For objects that implement the ``__toString()`` magic method (and not ``Countable``),
+it will check if an empty string is returned.
+
+.. code-block:: twig
+
+ {% if foo is empty %}
+ ...
+ {% endif %}
+
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/even.rst b/upload/system/storage/vendor/twig/twig/doc/tests/even.rst
new file mode 100644
index 000000000..2de0de2f3
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/even.rst
@@ -0,0 +1,12 @@
+``even``
+========
+
+``even`` returns ``true`` if the given number is even:
+
+.. code-block:: twig
+
+ {{ var is even }}
+
+.. seealso::
+
+ :doc:`odd<../tests/odd>`
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/index.rst b/upload/system/storage/vendor/twig/twig/doc/tests/index.rst
new file mode 100644
index 000000000..c63208ee7
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/index.rst
@@ -0,0 +1,15 @@
+Tests
+=====
+
+.. toctree::
+ :maxdepth: 1
+
+ constant
+ defined
+ divisibleby
+ empty
+ even
+ iterable
+ null
+ odd
+ sameas
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/iterable.rst b/upload/system/storage/vendor/twig/twig/doc/tests/iterable.rst
new file mode 100644
index 000000000..8c83efcd8
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/iterable.rst
@@ -0,0 +1,16 @@
+``iterable``
+============
+
+``iterable`` checks if a variable is an array or a traversable object:
+
+.. code-block:: twig
+
+ {# evaluates to true if the users variable is iterable #}
+ {% if users is iterable %}
+ {% for user in users %}
+ Hello {{ user }}!
+ {% endfor %}
+ {% else %}
+ {# users is probably a string #}
+ Hello {{ users }}!
+ {% endif %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/mapping.rst b/upload/system/storage/vendor/twig/twig/doc/tests/mapping.rst
new file mode 100644
index 000000000..ab90cd6c1
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/mapping.rst
@@ -0,0 +1,14 @@
+``mapping``
+===========
+
+``mapping`` checks if a variable is a mapping:
+
+.. code-block:: twig
+
+ {% set users = {alice: "Alice Dupond", bob: "Bob Smith"} %}
+ {# evaluates to true if the users variable is a mapping #}
+ {% if users is mapping %}
+ {% for key, user in users %}
+ {{ key }}: {{ user }};
+ {% endfor %}
+ {% endif %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/null.rst b/upload/system/storage/vendor/twig/twig/doc/tests/null.rst
new file mode 100644
index 000000000..9ed93f6bb
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/null.rst
@@ -0,0 +1,12 @@
+``null``
+========
+
+``null`` returns ``true`` if the variable is ``null``:
+
+.. code-block:: twig
+
+ {{ var is null }}
+
+.. note::
+
+ ``none`` is an alias for ``null``.
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/odd.rst b/upload/system/storage/vendor/twig/twig/doc/tests/odd.rst
new file mode 100644
index 000000000..27fe7e4dc
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/odd.rst
@@ -0,0 +1,12 @@
+``odd``
+=======
+
+``odd`` returns ``true`` if the given number is odd:
+
+.. code-block:: twig
+
+ {{ var is odd }}
+
+.. seealso::
+
+ :doc:`even<../tests/even>`
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/sameas.rst b/upload/system/storage/vendor/twig/twig/doc/tests/sameas.rst
new file mode 100644
index 000000000..c09297114
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/sameas.rst
@@ -0,0 +1,11 @@
+``same as``
+===========
+
+``same as`` checks if a variable is the same as another variable.
+This is equivalent to ``===`` in PHP:
+
+.. code-block:: twig
+
+ {% if foo.attribute is same as(false) %}
+ the foo attribute really is the 'false' PHP value
+ {% endif %}
diff --git a/upload/system/storage/vendor/twig/twig/doc/tests/sequence.rst b/upload/system/storage/vendor/twig/twig/doc/tests/sequence.rst
new file mode 100644
index 000000000..0ae47a387
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/doc/tests/sequence.rst
@@ -0,0 +1,14 @@
+``sequence``
+============
+
+``sequence`` checks if a variable is a sequence:
+
+.. code-block:: twig
+
+ {% set users = ["Alice", "Bob"] %}
+ {# evaluates to true if the users variable is a sequence #}
+ {% if users is sequence %}
+ {% for user in users %}
+ Hello {{ user }}!
+ {% endfor %}
+ {% endif %}
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/.gitattributes b/upload/system/storage/vendor/twig/twig/extra/cache-extra/.gitattributes
new file mode 100644
index 000000000..aa02dc651
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/.gitattributes
@@ -0,0 +1,2 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/.gitignore b/upload/system/storage/vendor/twig/twig/extra/cache-extra/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/CacheExtension.php b/upload/system/storage/vendor/twig/twig/extra/cache-extra/CacheExtension.php
new file mode 100644
index 000000000..5cf849dc6
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/CacheExtension.php
@@ -0,0 +1,25 @@
+cache = $cache;
+ }
+
+ public function getCache(): CacheInterface
+ {
+ return $this->cache;
+ }
+}
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/LICENSE b/upload/system/storage/vendor/twig/twig/extra/cache-extra/LICENSE
new file mode 100644
index 000000000..99c6bdf35
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2021-present Fabien Potencier
+
+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/upload/system/storage/vendor/twig/twig/extra/cache-extra/Node/CacheNode.php b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Node/CacheNode.php
new file mode 100644
index 000000000..7308b6bc9
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Node/CacheNode.php
@@ -0,0 +1,71 @@
+setAttribute('raw', true);
+
+ $nodes = ['key' => $key, 'body' => $body];
+ if (null !== $ttl) {
+ $nodes['ttl'] = $ttl;
+ }
+ if (null !== $tags) {
+ $nodes['tags'] = $tags;
+ }
+
+ parent::__construct($nodes, [], $lineno);
+ }
+
+ public function compile(Compiler $compiler): void
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->raw('$this->env->getRuntime(\'Twig\Extra\Cache\CacheRuntime\')->getCache()->get(')
+ ->subcompile($this->getNode('key'))
+ ->raw(", function (\Symfony\Contracts\Cache\ItemInterface \$item) use (\$context, \$macros, \$blocks) {\n")
+ ->indent()
+ ;
+
+ if ($this->hasNode('tags')) {
+ $compiler
+ ->write('$item->tag(')
+ ->subcompile($this->getNode('tags'))
+ ->raw(");\n")
+ ;
+ }
+
+ if ($this->hasNode('ttl')) {
+ $compiler
+ ->write('$item->expiresAfter(')
+ ->subcompile($this->getNode('ttl'))
+ ->raw(");\n")
+ ;
+ }
+
+ $compiler
+ ->write('return ')
+ ->subcompile($this->getNode('body'))
+ ->raw(";\n")
+ ->outdent()
+ ->write("})\n")
+ ;
+ }
+}
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/README.md b/upload/system/storage/vendor/twig/twig/extra/cache-extra/README.md
new file mode 100644
index 000000000..9db5195cc
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/README.md
@@ -0,0 +1,9 @@
+Cache Extension
+===============
+
+This package is a Twig extension that provides integration with the Symfony
+Cache component.
+
+It provides a single [`cache`][1] tag that allows to cache template fragments.
+
+[1]: https://twig.symfony.com/cache
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache.test b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache.test
new file mode 100644
index 000000000..734f106cb
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache.test
@@ -0,0 +1,22 @@
+--TEST--
+"cache" tag
+--TEMPLATE--
+{% set foo = "bar" %}
+{% set value1 %}
+ {% cache "test;v1" ttl(3) %}
+ {% set foo = "bar1" %}
+ {{ random(1, 1000000) }}
+ {% endcache %}
+{% endset %}
+{% set value2 %}
+ {% cache "test;v1" ttl(3) %}
+ {{ random(1, 1000000) }}
+ {% endcache %}
+{% endset %}
+{{ value1 == value2 ? 'OK' : 'KO' }}
+{{ foo == "bar" ? 'OK' : 'KO' }}
+--DATA--
+return []
+--EXPECT--
+OK
+OK
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache_complex.test b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache_complex.test
new file mode 100644
index 000000000..206865088
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache_complex.test
@@ -0,0 +1,15 @@
+--TEST--
+"cache" tag
+--TEMPLATE--
+{% cache 'test_%s_%s'|format(10, 10000) ttl(36000) %}
+ {% set content %}
+ ok
+ {% endset %}
+ {% apply upper %}
+ {{ content }}
+ {% endapply %}
+{% endcache %}
+--DATA--
+return []
+--EXPECT--
+OK
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache_with_blocks.test b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache_with_blocks.test
new file mode 100644
index 000000000..79721d7fc
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/cache_with_blocks.test
@@ -0,0 +1,15 @@
+--TEST--
+"cache" tag
+--TEMPLATE--
+{% extends "layout.twig" %}
+{% block bar %}
+ {% cache "foo" %}
+ {%- block content %}FOO{% endblock %}
+ {% endcache %}
+{% endblock %}
+--TEMPLATE(layout.twig)--
+{% block content %}{% endblock %}
+--DATA--
+return []
+--EXPECT--
+FOO
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/macro.test b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/macro.test
new file mode 100644
index 000000000..4a8afb5cc
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/Fixtures/macro.test
@@ -0,0 +1,22 @@
+--TEST--
+macro call inside "cache" tag
+--TEMPLATE--
+{% macro macro_out(bar) %}{{ bar }}{% endmacro %}
+1
+{% cache "testmacro1" ttl(3) %}
+ {%~ macro macro_in(bar) %}{{ bar }}{% endmacro %}
+ 2
+ {{ _self.macro_out(3) }}
+ {{ _self.macro_in(4) }}
+{% endcache %}
+5
+{{ _self.macro_in(6) }}
+--DATA--
+return []
+--EXPECT--
+1
+ 2
+ 3
+ 4
+5
+6
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/FunctionalTest.php b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/FunctionalTest.php
new file mode 100644
index 000000000..0ae24436e
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/FunctionalTest.php
@@ -0,0 +1,91 @@
+createEnvironment(['index' => '{% cache "city;v1" %}{{- city -}}{% endcache %}'], $cache);
+
+ $this->assertSame('Paris', $twig->render('index', ['city' => 'Paris']));
+ $value = $cache->get('city;v1', function () { throw new \RuntimeException('Key should be in the cache'); });
+ $this->assertSame('Paris', $value);
+ }
+
+ public function testTtlNoArgs()
+ {
+ $twig = $this->createEnvironment(['index' => '{% cache "ttl_no_args" ttl() %}{% endcache %}']);
+ $this->expectException(SyntaxError::class);
+ $this->expectExceptionMessage('The "ttl" modifier takes exactly one argument (0 given) in "index" at line 1.');
+ $twig->render('index');
+ }
+
+ public function testTtlTooManyArgs()
+ {
+ $twig = $this->createEnvironment(['index' => '{% cache "ttl_too_many_args" ttl(0, 1) %}{% endcache %}']);
+ $this->expectException(SyntaxError::class);
+ $this->expectExceptionMessage('The "ttl" modifier takes exactly one argument (2 given) in "index" at line 1.');
+ $twig->render('index');
+ }
+
+ public function testTagsNoArgs()
+ {
+ $twig = $this->createEnvironment(['index' => '{% cache "tags_no_args" tags() %}{% endcache %}']);
+ $this->expectException(SyntaxError::class);
+ $this->expectExceptionMessage('The "tags" modifier takes exactly one argument (0 given) in "index" at line 1.');
+ $twig->render('index');
+ }
+
+ public function testTagsTooManyArgs()
+ {
+ $twig = $this->createEnvironment(['index' => '{% cache "tags_too_many_args" tags(["foo"], 1) %}{% endcache %}']);
+ $this->expectException(SyntaxError::class);
+ $this->expectExceptionMessage('The "tags" modifier takes exactly one argument (2 given) in "index" at line 1.');
+ $twig->render('index');
+ }
+
+ private function createEnvironment(array $templates, ?ArrayAdapter $cache = null): Environment
+ {
+ $twig = new Environment(new ArrayLoader($templates));
+ $cache = $cache ?? new ArrayAdapter();
+ $twig->addExtension(new CacheExtension());
+ $twig->addRuntimeLoader(new class($cache) implements RuntimeLoaderInterface {
+ private $cache;
+
+ public function __construct(CacheInterface $cache)
+ {
+ $this->cache = $cache;
+ }
+
+ public function load($class)
+ {
+ if (CacheRuntime::class === $class) {
+ return new CacheRuntime($this->cache);
+ }
+ }
+ });
+
+ return $twig;
+ }
+}
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/IntegrationTest.php b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/IntegrationTest.php
new file mode 100644
index 000000000..8e216aaa5
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/Tests/IntegrationTest.php
@@ -0,0 +1,47 @@
+parser->getStream();
+ $expressionParser = $this->parser->getExpressionParser();
+ $key = $expressionParser->parseExpression();
+
+ $ttl = null;
+ $tags = null;
+ while ($stream->test(Token::NAME_TYPE)) {
+ $k = $stream->getCurrent()->getValue();
+ $stream->next();
+ $args = $expressionParser->parseArguments();
+
+ switch ($k) {
+ case 'ttl':
+ if (1 !== \count($args)) {
+ throw new SyntaxError(\sprintf('The "ttl" modifier takes exactly one argument (%d given).', \count($args)), $stream->getCurrent()->getLine(), $stream->getSourceContext());
+ }
+ $ttl = $args->getNode('0');
+ break;
+ case 'tags':
+ if (1 !== \count($args)) {
+ throw new SyntaxError(\sprintf('The "tags" modifier takes exactly one argument (%d given).', \count($args)), $stream->getCurrent()->getLine(), $stream->getSourceContext());
+ }
+ $tags = $args->getNode('0');
+ break;
+ default:
+ throw new SyntaxError(\sprintf('Unknown "%s" configuration.', $k), $stream->getCurrent()->getLine(), $stream->getSourceContext());
+ }
+ }
+
+ $stream->expect(Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse([$this, 'decideCacheEnd'], true);
+ $stream->expect(Token::BLOCK_END_TYPE);
+
+ $body = new CacheNode($key, $ttl, $tags, $body, $token->getLine());
+
+ return new PrintNode(new RawFilter($body), $token->getLine());
+ }
+
+ public function decideCacheEnd(Token $token): bool
+ {
+ return $token->test('endcache');
+ }
+
+ public function getTag(): string
+ {
+ return 'cache';
+ }
+}
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/composer.json b/upload/system/storage/vendor/twig/twig/extra/cache-extra/composer.json
new file mode 100644
index 000000000..74e377e95
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/composer.json
@@ -0,0 +1,31 @@
+{
+ "name": "twig/cache-extra",
+ "type": "library",
+ "description": "A Twig extension for Symfony Cache",
+ "keywords": ["twig", "html", "cache"],
+ "homepage": "https://twig.symfony.com",
+ "license": "MIT",
+ "minimum-stability": "dev",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ }
+ ],
+ "require": {
+ "php": ">=8.0.2",
+ "symfony/cache": "^5.4|^6.4|^7.0",
+ "twig/twig": "^3.12"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^6.4|^7.0"
+ },
+ "autoload": {
+ "psr-4" : { "Twig\\Extra\\Cache\\" : "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ }
+}
diff --git a/upload/system/storage/vendor/twig/twig/extra/cache-extra/phpunit.xml.dist b/upload/system/storage/vendor/twig/twig/extra/cache-extra/phpunit.xml.dist
new file mode 100644
index 000000000..0cfdd7296
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cache-extra/phpunit.xml.dist
@@ -0,0 +1,20 @@
+
+
+
+
+ ./
+
+
+ ./Tests
+ ./vendor
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
diff --git a/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/.gitattributes b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/.gitattributes
new file mode 100644
index 000000000..aa02dc651
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/.gitattributes
@@ -0,0 +1,2 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
diff --git a/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/.gitignore b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/CssInlinerExtension.php b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/CssInlinerExtension.php
new file mode 100644
index 000000000..2ceb2e085
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/CssInlinerExtension.php
@@ -0,0 +1,39 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Twig\Extra\CssInliner;
+
+use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;
+use Twig\Extension\AbstractExtension;
+use Twig\TwigFilter;
+
+class CssInlinerExtension extends AbstractExtension
+{
+ public function getFilters()
+ {
+ return [
+ new TwigFilter('inline_css', [self::class, 'inlineCss'], ['is_safe' => ['all']]),
+ ];
+ }
+
+ /**
+ * @internal
+ */
+ public static function inlineCss(string $body, string ...$css): string
+ {
+ static $inliner;
+ if (null === $inliner) {
+ $inliner = new CssToInlineStyles();
+ }
+
+ return $inliner->convert($body, implode("\n", $css));
+ }
+}
diff --git a/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/LICENSE b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/LICENSE
new file mode 100644
index 000000000..f37c76b59
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2019-present Fabien Potencier
+
+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/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/README.md b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/README.md
new file mode 100644
index 000000000..089a189a0
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/README.md
@@ -0,0 +1,8 @@
+Twig CssInliner Extension
+=========================
+
+This package is a Twig extension that provides the following:
+
+ * [`inline_css`][1] filter: inlines CSS styles in HTML documents.
+
+[1]: https://twig.symfony.com/inline_css
diff --git a/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/Resources/functions.php b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/Resources/functions.php
new file mode 100644
index 000000000..60305e231
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/Resources/functions.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Twig\Extra\CssInliner;
+
+/**
+ * @internal
+ *
+ * @deprecated since Twig 3.9.0
+ */
+function twig_inline_css(string $body, string ...$css): string
+{
+ trigger_deprecation('twig/cssinliner-extra', '3.9.0', 'Using the internal "%s" function is deprecated.', __FUNCTION__);
+
+ return CssInlinerExtension::inlineCss($body, ...$css);
+}
diff --git a/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/Tests/Fixtures/inline_css.test b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/Tests/Fixtures/inline_css.test
new file mode 100644
index 000000000..7142b9e71
--- /dev/null
+++ b/upload/system/storage/vendor/twig/twig/extra/cssinliner-extra/Tests/Fixtures/inline_css.test
@@ -0,0 +1,50 @@
+--TEST--
+"inline_css" filter
+--TEMPLATE--
+{% apply inline_css %}
+